cleanup of skia serve url handling
authorjoshualitt <joshualitt@chromium.org>
Tue, 2 Feb 2016 15:16:24 +0000 (07:16 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 2 Feb 2016 15:16:24 +0000 (07:16 -0800)
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1653203002

Review URL: https://codereview.chromium.org/1653203002

tools/skiaserve/skiaserve.cpp

index d37dcaf..6b93429 100644 (file)
@@ -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() {