| Index: tools/skiaserve/skiaserve.cpp
|
| diff --git a/tools/skiaserve/skiaserve.cpp b/tools/skiaserve/skiaserve.cpp
|
| index 9252da85dcba497504ca8c52b43abf760a32cba9..aa6d803264c2e06ce26a31fa121d88f4036e1923 100644
|
| --- a/tools/skiaserve/skiaserve.cpp
|
| +++ b/tools/skiaserve/skiaserve.cpp
|
| @@ -129,93 +129,129 @@ static int process_upload_data(void* cls, enum MHD_ValueKind kind,
|
| return MHD_YES;
|
| }
|
|
|
| -int answer_to_connection(void* cls, struct MHD_Connection* connection,
|
| - const char* url, const char* method, const char* version,
|
| - const char* upload_data, size_t* upload_data_size,
|
| - void** con_cls) {
|
| - SkDebugf("New %s request for %s using version %s\n", method, url, version);
|
| +static int SendImage(MHD_Connection* connection, const SkData* data) {
|
| + MHD_Response* response = MHD_create_response_from_buffer(data->size(),
|
| + const_cast<void*>(data->data()),
|
| + MHD_RESPMEM_MUST_COPY);
|
| + MHD_add_response_header(response, "Content-Type", "image/png");
|
| +
|
| + int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
| + MHD_destroy_response(response);
|
| + return ret;
|
| +}
|
|
|
| - Request* request = reinterpret_cast<Request*>(cls);
|
| +static int SendTemplate(MHD_Connection* connection) {
|
| + SkString debuggerTemplate = generateTemplate(SkString("http://debugger.skia.org"));
|
|
|
| - MHD_Response* response;
|
| - int ret = MHD_NO;
|
| -
|
| - // TODO url handlers
|
| - // handle uploads
|
| - if (0 == strcmp(method, MHD_HTTP_METHOD_POST) &&
|
| - 0 == strcmp(url, "/new")) {
|
| - UploadContext* uc = request->fUploadContext;
|
| -
|
| - // New connection
|
| - if (!uc) {
|
| - // TODO make this a method on request
|
| - uc = new UploadContext;
|
| - uc->connection = connection;
|
| - uc->pp = MHD_create_post_processor(connection, kBufferSize, &process_upload_data, uc);
|
| - SkASSERT(uc->pp);
|
| -
|
| - request->fUploadContext = uc;
|
| - return MHD_YES;
|
| - }
|
| + MHD_Response* response = MHD_create_response_from_buffer(
|
| + debuggerTemplate.size(),
|
| + (void*) const_cast<char*>(debuggerTemplate.c_str()),
|
| + MHD_RESPMEM_MUST_COPY);
|
|
|
| - // in process upload
|
| - if (0 != *upload_data_size) {
|
| - SkASSERT(uc->pp);
|
| - MHD_post_process(uc->pp, upload_data, *upload_data_size);
|
| - *upload_data_size = 0;
|
| - return MHD_YES;
|
| - }
|
| + int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
| + MHD_destroy_response(response);
|
| + return ret;
|
| +}
|
|
|
| - // end of upload
|
| - MHD_destroy_post_processor(uc->pp);
|
| - uc->pp = nullptr;
|
| +typedef int (*UrlHandler)(Request* request, MHD_Connection* connection,
|
| + const char* upload_data, size_t* upload_data_size);
|
|
|
| - // TODO response
|
| - SkString error;
|
| - SkData* data = setupAndDrawToCanvas(uc->stream.detachAsStream(), &error);
|
| - if (!data) {
|
| - // TODO send error
|
| - return MHD_YES;
|
| - }
|
| +int rootHandler(Request* request, MHD_Connection* connection,
|
| + const char* upload_data, size_t* upload_data_size) {
|
| + return SendTemplate(connection);
|
| +}
|
| +
|
| +int postHandler(Request* request, MHD_Connection* connection,
|
| + const char* upload_data, size_t* upload_data_size) {
|
| + UploadContext* uc = request->fUploadContext;
|
| +
|
| + // New connection
|
| + if (!uc) {
|
| + // TODO make this a method on request
|
| + uc = new UploadContext;
|
| + uc->connection = connection;
|
| + uc->pp = MHD_create_post_processor(connection, kBufferSize, &process_upload_data, uc);
|
| + SkASSERT(uc->pp);
|
| +
|
| + request->fUploadContext = uc;
|
| + return MHD_YES;
|
| + }
|
| +
|
| + // in process upload
|
| + if (0 != *upload_data_size) {
|
| + SkASSERT(uc->pp);
|
| + MHD_post_process(uc->pp, upload_data, *upload_data_size);
|
| + *upload_data_size = 0;
|
| + return MHD_YES;
|
| + }
|
| +
|
| + // end of upload
|
| + MHD_destroy_post_processor(uc->pp);
|
| + uc->pp = nullptr;
|
|
|
| - request->fPNG.reset(data);
|
| - // TODO Hack
|
| - SkString debuggerTemplate = generateTemplate(SkString("http://debugger.skia.org"));
|
| -
|
| - response = MHD_create_response_from_buffer(debuggerTemplate.size(),
|
| - (void*) const_cast<char*>(debuggerTemplate.c_str()),
|
| - MHD_RESPMEM_MUST_COPY);
|
| -
|
| - ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
| - MHD_destroy_response(response);
|
| - } else if (0 == strcmp(method, MHD_HTTP_METHOD_GET)) {
|
| - if (0 == strcmp(url, "/")) {
|
| - SkString debuggerTemplate = generateTemplate(SkString("http://debugger.skia.org"));
|
| -
|
| - response = MHD_create_response_from_buffer(debuggerTemplate.size(),
|
| - (void*) const_cast<char*>(debuggerTemplate.c_str()),
|
| - MHD_RESPMEM_MUST_COPY);
|
| -
|
| - ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
| - MHD_destroy_response(response);
|
| - } else if (0 == strcmp(url, "/img")) {
|
| - if (request->fPNG.get()) {
|
| - SkData* data = request->fPNG.get();
|
| - response = MHD_create_response_from_buffer(data->size(),
|
| - const_cast<void*>(data->data()),
|
| - MHD_RESPMEM_MUST_COPY);
|
| - MHD_add_response_header(response, "Content-Type", "image/png");
|
| -
|
| - ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
| - MHD_destroy_response(response);
|
| + // TODO response
|
| + SkString error;
|
| + SkData* data = setupAndDrawToCanvas(uc->stream.detachAsStream(), &error);
|
| + if (!data) {
|
| + // TODO send error
|
| + return MHD_YES;
|
| + }
|
| +
|
| + request->fPNG.reset(data);
|
| + return SendTemplate(connection);
|
| +}
|
| +
|
| +int imgHandler(Request* request, MHD_Connection* connection,
|
| + const char* upload_data, size_t* upload_data_size) {
|
| + if (request->fPNG.get()) {
|
| + SkData* data = request->fPNG.get();
|
| + return SendImage(connection, data);
|
| + }
|
| + return MHD_NO;
|
| +}
|
| +
|
| +class UrlManager {
|
| +public:
|
| + UrlManager() {
|
| + // Register handlers
|
| + fHandlers.push_back({MHD_HTTP_METHOD_GET, "/", rootHandler});
|
| + fHandlers.push_back({MHD_HTTP_METHOD_POST, "/new", postHandler});
|
| + fHandlers.push_back({MHD_HTTP_METHOD_GET, "/img", imgHandler});
|
| + }
|
| +
|
| + // This is clearly not efficient for a large number of urls and handlers
|
| + int invoke(Request* request, MHD_Connection* connection, const char* url, const char* method,
|
| + const char* upload_data, size_t* upload_data_size) const {
|
| + for (int i = 0; i < fHandlers.count(); i++) {
|
| + const Url& urlHandler = fHandlers[i];
|
| + if (0 == strcmp(method, urlHandler.fMethod) &&
|
| + 0 == strcmp(url, urlHandler.fPath)) {
|
| + return (*urlHandler.fHandler)(request, connection, upload_data,
|
| + upload_data_size);
|
| }
|
| }
|
| - } else {
|
| - SkFAIL("whoops, need proper error handling");
|
| return MHD_NO;
|
| }
|
|
|
| - return ret;
|
| +private:
|
| + struct Url {
|
| + const char* fMethod;
|
| + const char* fPath;
|
| + UrlHandler fHandler;
|
| + };
|
| + SkTArray<Url> fHandlers;
|
| +};
|
| +
|
| +const UrlManager kUrlManager;
|
| +
|
| +int answer_to_connection(void* cls, struct MHD_Connection* connection,
|
| + const char* url, const char* method, const char* version,
|
| + const char* upload_data, size_t* upload_data_size,
|
| + void** con_cls) {
|
| + SkDebugf("New %s request for %s using version %s\n", method, url, version);
|
| +
|
| + Request* request = reinterpret_cast<Request*>(cls);
|
| + return kUrlManager.invoke(request, connection, url, method, upload_data, upload_data_size);
|
| }
|
|
|
| int skiaserve_main() {
|
|
|