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() { |