1
0
ithewei 4 жил өмнө
parent
commit
9a470feb6b

+ 31 - 30
http/server/HttpHandler.cpp

@@ -5,6 +5,31 @@
 #include "hlog.h"
 #include "http_page.h"
 
+int HttpHandler::customHttpHandler(const http_handler& handler) {
+    return invokeHttpHandler(&handler);
+}
+
+int HttpHandler::invokeHttpHandler(const http_handler* handler) {
+    int status_code = HTTP_STATUS_NOT_IMPLEMENTED;
+    if (handler->sync_handler) {
+        status_code = handler->sync_handler(req.get(), resp.get());
+    } else if (handler->async_handler) {
+        handler->async_handler(req, writer);
+        status_code = HTTP_STATUS_UNFINISHED;
+    } else if (handler->ctx_handler) {
+        HttpContextPtr ctx(new hv::HttpContext);
+        ctx->service = service;
+        ctx->request = req;
+        ctx->response = resp;
+        ctx->writer = writer;
+        status_code = handler->ctx_handler(ctx);
+        if (writer->state != hv::HttpResponseWriter::SEND_BEGIN) {
+            status_code = HTTP_STATUS_UNFINISHED;
+        }
+    }
+    return status_code;
+}
+
 int HttpHandler::HandleHttpRequest() {
     // preprocessor -> processor -> postprocessor
     int status_code = HTTP_STATUS_OK;
@@ -21,7 +46,7 @@ int HttpHandler::HandleHttpRequest() {
 preprocessor:
     state = HANDLE_BEGIN;
     if (service->preprocessor) {
-        status_code = service->preprocessor(pReq, pResp);
+        status_code = customHttpHandler(service->preprocessor);
         if (status_code != 0) {
             goto postprocessor;
         }
@@ -53,7 +78,7 @@ postprocessor:
         pResp->headers["Etag"] = fc->etag;
     }
     if (service->postprocessor) {
-        service->postprocessor(pReq, pResp);
+        customHttpHandler(service->postprocessor);
     }
 
     if (status_code == 0) {
@@ -65,40 +90,16 @@ postprocessor:
     return status_code;
 }
 
-int HttpHandler::customHttpHandler(http_handler& fn) {
-    HttpContextPtr ctx(new hv::HttpContext);
-    ctx->service = service;
-    ctx->request = req;
-    ctx->response = resp;
-    ctx->writer = writer;
-    return fn(ctx);
-}
-
 int HttpHandler::defaultRequestHandler() {
     int status_code = HTTP_STATUS_OK;
-    http_sync_handler sync_handler = NULL;
-    http_async_handler async_handler = NULL;
-    http_handler ctx_handler = NULL;
+    http_handler* handler = NULL;
 
     if (service->api_handlers.size() != 0) {
-        service->GetApi(req.get(), &sync_handler, &async_handler, &ctx_handler);
+        service->GetApi(req.get(), &handler);
     }
 
-    if (sync_handler) {
-        // sync api handler
-        status_code = sync_handler(req.get(), resp.get());
-    }
-    else if (async_handler) {
-        // async api handler
-        async_handler(req, writer);
-        status_code = 0;
-    }
-    else if (ctx_handler) {
-        // HttpContext handler
-        status_code = customHttpHandler(ctx_handler);
-        if (writer->state != hv::HttpResponseWriter::SEND_BEGIN) {
-            status_code = 0;
-        }
+    if (handler) {
+        status_code = invokeHttpHandler(handler);
     }
     else if (req->method == HTTP_GET || req->method == HTTP_HEAD) {
         // static handler

+ 2 - 1
http/server/HttpHandler.h

@@ -174,7 +174,8 @@ private:
     int defaultRequestHandler();
     int defaultStaticHandler();
     int defaultErrorHandler();
-    int customHttpHandler(http_handler& fn);
+    int customHttpHandler(const http_handler& handler);
+    int invokeHttpHandler(const http_handler* handler);
 };
 
 #endif // HV_HTTP_HANDLER_H_

+ 6 - 19
http/server/HttpService.cpp

@@ -4,7 +4,7 @@
 
 namespace hv {
 
-void HttpService::AddApi(const char* path, http_method method, http_sync_handler sync_handler, http_async_handler async_handler, http_handler handler) {
+void HttpService::AddApi(const char* path, http_method method, const http_handler& handler) {
     std::shared_ptr<http_method_handlers> method_handlers = NULL;
     auto iter = api_handlers.find(path);
     if (iter == api_handlers.end()) {
@@ -18,17 +18,15 @@ void HttpService::AddApi(const char* path, http_method method, http_sync_handler
     for (auto iter = method_handlers->begin(); iter != method_handlers->end(); ++iter) {
         if (iter->method == method) {
             // update
-            iter->sync_handler = sync_handler;
-            iter->async_handler = async_handler;
             iter->handler = handler;
             return;
         }
     }
     // add
-    method_handlers->push_back(http_method_handler(method, sync_handler, async_handler, handler));
+    method_handlers->push_back(http_method_handler(method, handler));
 }
 
-int HttpService::GetApi(const char* url, http_method method, http_sync_handler* sync_handler, http_async_handler* async_handler, http_handler* handler) {
+int HttpService::GetApi(const char* url, http_method method, http_handler** handler) {
     // {base_url}/path?query
     const char* s = url;
     const char* b = base_url.c_str();
@@ -42,26 +40,21 @@ int HttpService::GetApi(const char* url, http_method method, http_sync_handler*
     std::string path = std::string(s, e);
     auto iter = api_handlers.find(path);
     if (iter == api_handlers.end()) {
-        if (sync_handler) *sync_handler = NULL;
-        if (async_handler) *async_handler = NULL;
         if (handler) *handler = NULL;
         return HTTP_STATUS_NOT_FOUND;
     }
     auto method_handlers = iter->second;
     for (auto iter = method_handlers->begin(); iter != method_handlers->end(); ++iter) {
         if (iter->method == method) {
-            if (sync_handler) *sync_handler = iter->sync_handler;
-            if (async_handler) *async_handler = iter->async_handler;
-            if (handler) *handler = iter->handler;
+            if (handler) *handler = &iter->handler;
             return 0;
         }
     }
     if (handler) *handler = NULL;
-    if (async_handler) *async_handler = NULL;
     return HTTP_STATUS_METHOD_NOT_ALLOWED;
 }
 
-int HttpService::GetApi(HttpRequest* req, http_sync_handler* sync_handler, http_async_handler* async_handler, http_handler* handler) {
+int HttpService::GetApi(HttpRequest* req, http_handler** handler) {
     // {base_url}/path?query
     const char* s = req->path.c_str();
     const char* b = base_url.c_str();
@@ -120,23 +113,17 @@ int HttpService::GetApi(HttpRequest* req, http_sync_handler* sync_handler, http_
                         // RESTful /:field/ => req->query_params[field]
                         req->query_params[param.first] = param.second;
                     }
-                    if (sync_handler) *sync_handler = iter->sync_handler;
-                    if (async_handler) *async_handler = iter->async_handler;
-                    if (handler) *handler = iter->handler;
+                    if (handler) *handler = &iter->handler;
                     return 0;
                 }
             }
 
             if (params.size() == 0) {
-                if (sync_handler) *sync_handler = NULL;
-                if (async_handler) *async_handler = NULL;
                 if (handler) *handler = NULL;
                 return HTTP_STATUS_METHOD_NOT_ALLOWED;
             }
         }
     }
-    if (sync_handler) *sync_handler = NULL;
-    if (async_handler) *async_handler = NULL;
     if (handler) *handler = NULL;
     return HTTP_STATUS_NOT_FOUND;
 }

+ 60 - 47
http/server/HttpService.h

@@ -29,24 +29,55 @@
 #define HTTP_STATUS_UNFINISHED  0
 typedef std::function<int(HttpRequest* req, HttpResponse* resp)>                            http_sync_handler;
 typedef std::function<void(const HttpRequestPtr& req, const HttpResponseWriterPtr& writer)> http_async_handler;
-typedef std::function<int(const HttpContextPtr& ctx)>                                       http_handler;
+typedef std::function<int(const HttpContextPtr& ctx)>                                       http_ctx_handler;
 
-struct http_method_handler {
-    http_method         method;
+struct http_handler {
     http_sync_handler   sync_handler;
     http_async_handler  async_handler;
-    http_handler        handler;
-    http_method_handler(http_method m = HTTP_POST,
-                        http_sync_handler s = NULL,
-                        http_async_handler a = NULL,
-                        http_handler h = NULL)
-    {
-        method = m;
-        sync_handler = std::move(s);
-        async_handler = std::move(a);
-        handler = std::move(h);
+    http_ctx_handler    ctx_handler;
+
+    http_handler()  {}
+    http_handler(http_sync_handler fn)  : sync_handler(std::move(fn))   {}
+    http_handler(http_async_handler fn) : async_handler(std::move(fn))  {}
+    http_handler(http_ctx_handler fn)   : ctx_handler(std::move(fn))    {}
+    http_handler(const http_handler& rhs)
+        : sync_handler(std::move(rhs.sync_handler))
+        , async_handler(std::move(rhs.async_handler))
+        , ctx_handler(std::move(rhs.ctx_handler))
+    {}
+
+    const http_handler& operator=(http_sync_handler fn) {
+        sync_handler = std::move(fn);
+        return *this;
+    }
+    const http_handler& operator=(http_async_handler fn) {
+        async_handler = std::move(fn);
+        return *this;
+    }
+    const http_handler& operator=(http_ctx_handler fn) {
+        ctx_handler = std::move(fn);
+        return *this;
+    }
+
+    bool isNull() {
+        return  sync_handler == NULL &&
+                async_handler == NULL &&
+                ctx_handler == NULL;
+    }
+
+    operator bool() {
+        return !isNull();
     }
 };
+
+struct http_method_handler {
+    http_method         method;
+    http_handler        handler;
+
+    http_method_handler()   {}
+    http_method_handler(http_method m, const http_handler& h) : method(m), handler(h) {}
+};
+
 // method => http_method_handler
 typedef std::list<http_method_handler>                                          http_method_handlers;
 // path => http_method_handlers
@@ -56,10 +87,10 @@ namespace hv {
 
 struct HV_EXPORT HttpService {
     // preprocessor -> processor -> postprocessor
-    http_sync_handler   preprocessor;
+    http_handler        preprocessor;
     // processor: api_handlers -> staticHandler -> errorHandler
     http_handler        processor;
-    http_sync_handler   postprocessor;
+    http_handler        postprocessor;
 
     // api service (that is http.APIServer)
     std::string         base_url;
@@ -80,39 +111,21 @@ struct HV_EXPORT HttpService {
     int keepalive_timeout;
 
     HttpService() {
-        preprocessor = NULL;
-        processor = NULL;
-        postprocessor = NULL;
-
         // base_url = DEFAULT_BASE_URL;
 
-        staticHandler = NULL;
-        largeFileHandler = NULL;
-
         document_root = DEFAULT_DOCUMENT_ROOT;
         home_page = DEFAULT_HOME_PAGE;
         // error_page = DEFAULT_ERROR_PAGE;
         // index_of = DEFAULT_INDEXOF_DIR;
 
-        errorHandler = NULL;
-
         keepalive_timeout = DEFAULT_KEEPALIVE_TIMEOUT;
     }
 
-    void AddApi(const char* path, http_method method,
-            http_sync_handler sync_handler = NULL,
-            http_async_handler async_handler = NULL,
-            http_handler handler = NULL);
     // @retval 0 OK, else HTTP_STATUS_NOT_FOUND, HTTP_STATUS_METHOD_NOT_ALLOWED
-    int GetApi(const char* url, http_method method,
-            http_sync_handler* sync_handler = NULL,
-            http_async_handler* async_handler = NULL,
-            http_handler* handler = NULL);
+    void AddApi(const char* path, http_method method, const http_handler& handler);
+    int  GetApi(const char* url,  http_method method, http_handler** handler);
     // RESTful API /:field/ => req->query_params["field"]
-    int GetApi(HttpRequest* req,
-            http_sync_handler* sync_handler = NULL,
-            http_async_handler* async_handler = NULL,
-            http_handler* handler = NULL);
+    int  GetApi(HttpRequest* req, http_handler** handler);
 
     hv::StringList Paths() {
         hv::StringList paths;
@@ -124,13 +137,13 @@ struct HV_EXPORT HttpService {
 
     // github.com/gin-gonic/gin
     void Handle(const char* httpMethod, const char* relativePath, http_sync_handler handlerFunc) {
-        AddApi(relativePath, http_method_enum(httpMethod), handlerFunc, NULL, NULL);
+        AddApi(relativePath, http_method_enum(httpMethod), http_handler(handlerFunc));
     }
     void Handle(const char* httpMethod, const char* relativePath, http_async_handler handlerFunc) {
-        AddApi(relativePath, http_method_enum(httpMethod), NULL, handlerFunc, NULL);
+        AddApi(relativePath, http_method_enum(httpMethod), http_handler(handlerFunc));
     }
-    void Handle(const char* httpMethod, const char* relativePath, http_handler handlerFunc) {
-        AddApi(relativePath, http_method_enum(httpMethod), NULL, NULL, handlerFunc);
+    void Handle(const char* httpMethod, const char* relativePath, http_ctx_handler handlerFunc) {
+        AddApi(relativePath, http_method_enum(httpMethod), http_handler(handlerFunc));
     }
 
     // HEAD
@@ -140,7 +153,7 @@ struct HV_EXPORT HttpService {
     void HEAD(const char* relativePath, http_async_handler handlerFunc) {
         Handle("HEAD", relativePath, handlerFunc);
     }
-    void HEAD(const char* relativePath, http_handler handlerFunc) {
+    void HEAD(const char* relativePath, http_ctx_handler handlerFunc) {
         Handle("HEAD", relativePath, handlerFunc);
     }
 
@@ -151,7 +164,7 @@ struct HV_EXPORT HttpService {
     void GET(const char* relativePath, http_async_handler handlerFunc) {
         Handle("GET", relativePath, handlerFunc);
     }
-    void GET(const char* relativePath, http_handler handlerFunc) {
+    void GET(const char* relativePath, http_ctx_handler handlerFunc) {
         Handle("GET", relativePath, handlerFunc);
     }
 
@@ -162,7 +175,7 @@ struct HV_EXPORT HttpService {
     void POST(const char* relativePath, http_async_handler handlerFunc) {
         Handle("POST", relativePath, handlerFunc);
     }
-    void POST(const char* relativePath, http_handler handlerFunc) {
+    void POST(const char* relativePath, http_ctx_handler handlerFunc) {
         Handle("POST", relativePath, handlerFunc);
     }
 
@@ -173,7 +186,7 @@ struct HV_EXPORT HttpService {
     void PUT(const char* relativePath, http_async_handler handlerFunc) {
         Handle("PUT", relativePath, handlerFunc);
     }
-    void PUT(const char* relativePath, http_handler handlerFunc) {
+    void PUT(const char* relativePath, http_ctx_handler handlerFunc) {
         Handle("PUT", relativePath, handlerFunc);
     }
 
@@ -185,7 +198,7 @@ struct HV_EXPORT HttpService {
     void Delete(const char* relativePath, http_async_handler handlerFunc) {
         Handle("DELETE", relativePath, handlerFunc);
     }
-    void Delete(const char* relativePath, http_handler handlerFunc) {
+    void Delete(const char* relativePath, http_ctx_handler handlerFunc) {
         Handle("DELETE", relativePath, handlerFunc);
     }
 
@@ -196,7 +209,7 @@ struct HV_EXPORT HttpService {
     void PATCH(const char* relativePath, http_async_handler handlerFunc) {
         Handle("PATCH", relativePath, handlerFunc);
     }
-    void PATCH(const char* relativePath, http_handler handlerFunc) {
+    void PATCH(const char* relativePath, http_ctx_handler handlerFunc) {
         Handle("PATCH", relativePath, handlerFunc);
     }
 
@@ -217,7 +230,7 @@ struct HV_EXPORT HttpService {
         Handle("DELETE", relativePath, handlerFunc);
         Handle("PATCH", relativePath, handlerFunc);
     }
-    void Any(const char* relativePath, http_handler handlerFunc) {
+    void Any(const char* relativePath, http_ctx_handler handlerFunc) {
         Handle("HEAD", relativePath, handlerFunc);
         Handle("GET", relativePath, handlerFunc);
         Handle("POST", relativePath, handlerFunc);