aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2016-01-27 07:40:29 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-01-27 07:40:29 -0800
commitccfdaa5f2aee5da5cb49e0b5828bead73273a15e (patch)
tree4cb3b5b52caede393eb20eca9271a7c55c9c1cd2
parent8f5175842d26f5ef562b049f442b408fe59d9c9c (diff)
Add primitive url handling system to skiaserve
-rw-r--r--tools/skiaserve/skiaserve.cpp188
1 files changed, 112 insertions, 76 deletions
diff --git a/tools/skiaserve/skiaserve.cpp b/tools/skiaserve/skiaserve.cpp
index 9252da85dc..aa6d803264 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() {