1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "tools/skiaserve/urlhandlers/UrlHandler.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "microhttpd.h" 11cb93a386Sopenharmony_ci#include "tools/skiaserve/Request.h" 12cb93a386Sopenharmony_ci#include "tools/skiaserve/Response.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ciusing namespace Response; 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cistatic const size_t kBufferSize = 1024; 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_cistatic int process_upload_data(void* cls, enum MHD_ValueKind kind, 19cb93a386Sopenharmony_ci const char* key, const char* filename, 20cb93a386Sopenharmony_ci const char* content_type, const char* transfer_encoding, 21cb93a386Sopenharmony_ci const char* data, uint64_t off, size_t size) { 22cb93a386Sopenharmony_ci struct UploadContext* uc = reinterpret_cast<UploadContext*>(cls); 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci if (0 != size) { 25cb93a386Sopenharmony_ci uc->fStream.write(data, size); 26cb93a386Sopenharmony_ci } 27cb93a386Sopenharmony_ci return MHD_YES; 28cb93a386Sopenharmony_ci} 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_cibool PostHandler::canHandle(const char* method, const char* url) { 31cb93a386Sopenharmony_ci return 0 == strcmp(method, MHD_HTTP_METHOD_POST) && 32cb93a386Sopenharmony_ci 0 == strcmp(url, "/new"); 33cb93a386Sopenharmony_ci} 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ciint PostHandler::handle(Request* request, MHD_Connection* connection, 36cb93a386Sopenharmony_ci const char* url, const char* method, 37cb93a386Sopenharmony_ci const char* upload_data, size_t* upload_data_size) { 38cb93a386Sopenharmony_ci UploadContext* uc = request->fUploadContext; 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci // New connection 41cb93a386Sopenharmony_ci if (!uc) { 42cb93a386Sopenharmony_ci // TODO make this a method on request 43cb93a386Sopenharmony_ci uc = new UploadContext; 44cb93a386Sopenharmony_ci uc->connection = connection; 45cb93a386Sopenharmony_ci uc->fPostProcessor = MHD_create_post_processor(connection, kBufferSize, 46cb93a386Sopenharmony_ci &process_upload_data, uc); 47cb93a386Sopenharmony_ci SkASSERT(uc->fPostProcessor); 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci request->fUploadContext = uc; 50cb93a386Sopenharmony_ci return MHD_YES; 51cb93a386Sopenharmony_ci } 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci // in process upload 54cb93a386Sopenharmony_ci if (0 != *upload_data_size) { 55cb93a386Sopenharmony_ci SkASSERT(uc->fPostProcessor); 56cb93a386Sopenharmony_ci MHD_post_process(uc->fPostProcessor, upload_data, *upload_data_size); 57cb93a386Sopenharmony_ci *upload_data_size = 0; 58cb93a386Sopenharmony_ci return MHD_YES; 59cb93a386Sopenharmony_ci } 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci // end of upload 62cb93a386Sopenharmony_ci MHD_destroy_post_processor(uc->fPostProcessor); 63cb93a386Sopenharmony_ci uc->fPostProcessor = nullptr; 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci std::unique_ptr<SkStreamAsset> stream(request->fUploadContext->fStream.detachAsStream()); 66cb93a386Sopenharmony_ci if (!request->initPictureFromStream(stream.get())) { 67cb93a386Sopenharmony_ci fprintf(stderr, "Could not create picture from stream.\n"); 68cb93a386Sopenharmony_ci return MHD_NO; 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci // clear upload context 72cb93a386Sopenharmony_ci delete request->fUploadContext; 73cb93a386Sopenharmony_ci request->fUploadContext = nullptr; 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci return SendTemplate(connection, true, "/"); 76cb93a386Sopenharmony_ci} 77