From ccfdaa5f2aee5da5cb49e0b5828bead73273a15e Mon Sep 17 00:00:00 2001 From: joshualitt Date: Wed, 27 Jan 2016 07:40:29 -0800 Subject: [PATCH] Add primitive url handling system to skiaserve BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1644633002 Review URL: https://codereview.chromium.org/1644633002 --- tools/skiaserve/skiaserve.cpp | 188 +++++++++++++++++++++++++----------------- 1 file changed, 112 insertions(+), 76 deletions(-) diff --git a/tools/skiaserve/skiaserve.cpp b/tools/skiaserve/skiaserve.cpp index 9252da8..aa6d803 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(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(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(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(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(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(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 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(cls); + return kUrlManager.invoke(request, connection, url, method, upload_data, upload_data_size); } int skiaserve_main() { -- 2.7.4