Index: tools/skiaserve/skiaserve.cpp |
diff --git a/tools/skiaserve/skiaserve.cpp b/tools/skiaserve/skiaserve.cpp |
index d37dcafd23f2f82fae39a8fb9db8012e967180d3..6b93429764a56328873f6d8c0fb80776d918cf62 100644 |
--- a/tools/skiaserve/skiaserve.cpp |
+++ b/tools/skiaserve/skiaserve.cpp |
@@ -172,101 +172,135 @@ static int SendTemplate(MHD_Connection* connection, bool redirect = false, |
return ret; |
} |
-typedef int (*UrlHandler)(Request* request, MHD_Connection* connection, |
- const char* upload_data, size_t* upload_data_size); |
+class UrlHandler { |
+public: |
+ virtual ~UrlHandler() {} |
+ virtual bool canHandle(const char* method, const char* url) = 0; |
+ virtual int handle(Request* request, MHD_Connection* connection, |
+ const char* upload_data, size_t* upload_data_size) = 0; |
+}; |
-int rootHandler(Request* request, MHD_Connection* connection, |
- const char* upload_data, size_t* upload_data_size) { |
- return SendTemplate(connection); |
-} |
+class InfoHandler : public UrlHandler { |
+public: |
+ bool canHandle(const char* method, const char* url) override { |
+ return 0 == strcmp(method, MHD_HTTP_METHOD_GET) && |
+ 0 == strcmp(url, "/cmd"); |
+ } |
-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->fPostProcessor = MHD_create_post_processor(connection, kBufferSize, |
- &process_upload_data, uc); |
- SkASSERT(uc->fPostProcessor); |
- |
- request->fUploadContext = uc; |
- return MHD_YES; |
+ int handle(Request* request, MHD_Connection* connection, |
+ const char* upload_data, size_t* upload_data_size) override { |
+ if (request->fPicture.get()) { |
+ return SendJSON(connection, request->fPicture); |
+ } |
+ return MHD_NO; |
} |
+}; |
- // in process upload |
- if (0 != *upload_data_size) { |
- SkASSERT(uc->fPostProcessor); |
- MHD_post_process(uc->fPostProcessor, upload_data, *upload_data_size); |
- *upload_data_size = 0; |
- return MHD_YES; |
+class ImgHandler : public UrlHandler { |
+public: |
+ bool canHandle(const char* method, const char* url) override { |
+ static const char* kBasePath = "/img"; |
+ return 0 == strcmp(method, MHD_HTTP_METHOD_GET) && |
+ 0 == strncmp(url, kBasePath, strlen(kBasePath)); |
} |
- // end of upload |
- MHD_destroy_post_processor(uc->fPostProcessor); |
- uc->fPostProcessor = nullptr; |
+ int handle(Request* request, MHD_Connection* connection, |
+ const char* upload_data, size_t* upload_data_size) override { |
+ if (request->fPNG.get()) { |
+ SkData* data = request->fPNG.get(); |
+ return SendData(connection, data, "image/png"); |
+ } |
+ return MHD_NO; |
+ } |
+}; |
- // TODO response |
- SkString error; |
- if (!setupAndDrawToCanvas(request, &error)) { |
- // TODO send error |
- return MHD_YES; |
+class PostHandler : public UrlHandler { |
+public: |
+ bool canHandle(const char* method, const char* url) override { |
+ return 0 == strcmp(method, MHD_HTTP_METHOD_POST) && |
+ 0 == strcmp(url, "/new"); |
} |
- return SendTemplate(connection, true, "/"); |
-} |
+ int handle(Request* request, MHD_Connection* connection, |
+ const char* upload_data, size_t* upload_data_size) override { |
+ UploadContext* uc = request->fUploadContext; |
+ |
+ // New connection |
+ if (!uc) { |
+ // TODO make this a method on request |
+ uc = new UploadContext; |
+ uc->connection = connection; |
+ uc->fPostProcessor = MHD_create_post_processor(connection, kBufferSize, |
+ &process_upload_data, uc); |
+ SkASSERT(uc->fPostProcessor); |
+ |
+ request->fUploadContext = uc; |
+ return MHD_YES; |
+ } |
-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 SendData(connection, data, "image/png"); |
+ // in process upload |
+ if (0 != *upload_data_size) { |
+ SkASSERT(uc->fPostProcessor); |
+ MHD_post_process(uc->fPostProcessor, upload_data, *upload_data_size); |
+ *upload_data_size = 0; |
+ return MHD_YES; |
+ } |
+ |
+ // end of upload |
+ MHD_destroy_post_processor(uc->fPostProcessor); |
+ uc->fPostProcessor = nullptr; |
+ |
+ // TODO response |
+ SkString error; |
+ if (!setupAndDrawToCanvas(request, &error)) { |
+ // TODO send error |
+ return MHD_YES; |
+ } |
+ |
+ return SendTemplate(connection, true, "/"); |
} |
- return MHD_NO; |
-} |
+}; |
-int infoHandler(Request* request, MHD_Connection* connection, |
- const char* upload_data, size_t* upload_data_size) { |
- if (request->fPicture.get()) { |
- return SendJSON(connection, request->fPicture); |
+class RootHandler : public UrlHandler { |
+public: |
+ bool canHandle(const char* method, const char* url) override { |
+ return 0 == strcmp(method, MHD_HTTP_METHOD_GET) && |
+ 0 == strcmp(url, "/"); |
} |
- return MHD_NO; |
-} |
+ |
+ int handle(Request* request, MHD_Connection* connection, |
+ const char* upload_data, size_t* upload_data_size) override { |
+ return SendTemplate(connection); |
+ } |
+}; |
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}); |
- fHandlers.push_back({MHD_HTTP_METHOD_GET, "/cmd", infoHandler}); |
+ fHandlers.push_back(new RootHandler); |
+ fHandlers.push_back(new PostHandler); |
+ fHandlers.push_back(new ImgHandler); |
+ fHandlers.push_back(new InfoHandler); |
+ } |
+ |
+ ~UrlManager() { |
+ for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; } |
} |
// 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); |
+ if (fHandlers[i]->canHandle(method, url)) { |
+ return fHandlers[i]->handle(request, connection, upload_data, upload_data_size); |
} |
} |
return MHD_NO; |
} |
private: |
- struct Url { |
- const char* fMethod; |
- const char* fPath; |
- UrlHandler fHandler; |
- }; |
- SkTArray<Url> fHandlers; |
+ SkTArray<UrlHandler*> fHandlers; |
}; |
const UrlManager kUrlManager; |
@@ -278,7 +312,12 @@ int answer_to_connection(void* cls, struct MHD_Connection* connection, |
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 result = kUrlManager.invoke(request, connection, url, method, upload_data, |
+ upload_data_size); |
+ if (MHD_NO == result) { |
+ fprintf(stderr, "Invalid method and / or url: %s %s)\n", method, url); |
+ } |
+ return result; |
} |
int skiaserve_main() { |