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