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