Chromium Code Reviews| Index: tools/skiaserve/skiaserve.cpp |
| diff --git a/tools/skiaserve/skiaserve.cpp b/tools/skiaserve/skiaserve.cpp |
| index d37dcafd23f2f82fae39a8fb9db8012e967180d3..76d462742debc2c9ce35c50c170ee4c739c8074d 100644 |
| --- a/tools/skiaserve/skiaserve.cpp |
| +++ b/tools/skiaserve/skiaserve.cpp |
| @@ -172,101 +172,134 @@ 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 { |
| + return 0 == strcmp(method, MHD_HTTP_METHOD_GET) && |
| + 0 == strcmp(url, "/img"); |
|
jcgregorio
2016/02/02 12:35:31
0 == strncmp(url, "/img", 4);
So the cache-bustin
joshualitt
2016/02/02 14:02:34
Acknowledged.
|
| } |
| - // 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; |
| + } |
| + |
| + // 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; |
| -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"); |
| + // 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); |
|
jcgregorio
2016/02/02 12:35:31
Please log the method and the url to stderr.
joshualitt
2016/02/02 14:02:34
Acknowledged.
|
| } |
| } |
| return MHD_NO; |
| } |
| private: |
| - struct Url { |
| - const char* fMethod; |
| - const char* fPath; |
| - UrlHandler fHandler; |
| - }; |
| - SkTArray<Url> fHandlers; |
| + SkTArray<UrlHandler*> fHandlers; |
| }; |
| const UrlManager kUrlManager; |