diff --git a/lib/src/HttpAppFrameworkImpl.cc b/lib/src/HttpAppFrameworkImpl.cc index f850624a..5af9ed32 100755 --- a/lib/src/HttpAppFrameworkImpl.cc +++ b/lib/src/HttpAppFrameworkImpl.cc @@ -583,8 +583,7 @@ void HttpAppFrameworkImpl::onNewWebsockRequest(const HttpRequestImplPtr &req, std::function &&callback, const WebSocketConnectionPtr &wsConnPtr) { - auto callbackPtr = std::make_shared>(std::move(callback)); - _websockCtrlsRouter.route(req, callbackPtr, wsConnPtr); + _websockCtrlsRouter.route(req, std::move(callback), wsConnPtr); } void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::function &&callback) { @@ -780,13 +779,9 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu return; } } - auto sessionIdPtr = std::make_shared(std::move(session_id)); - auto callbackPtr = std::make_shared>(std::move(callback)); - //find simple controller - if (_httpSimpleCtrlsRouter.route(req, callbackPtr, needSetJsessionid, sessionIdPtr)) - return; - //Find http controller - _httpCtrlsRouter.route(req, callbackPtr, needSetJsessionid, sessionIdPtr); + + //Route to controller + _httpSimpleCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(session_id)); } void HttpAppFrameworkImpl::readSendFile(const std::string &filePath, const HttpRequestImplPtr &req, const HttpResponsePtr &resp) diff --git a/lib/src/HttpAppFrameworkImpl.h b/lib/src/HttpAppFrameworkImpl.h index f3c939d8..3d7ab7a1 100644 --- a/lib/src/HttpAppFrameworkImpl.h +++ b/lib/src/HttpAppFrameworkImpl.h @@ -39,8 +39,8 @@ class HttpAppFrameworkImpl : public HttpAppFramework { public: HttpAppFrameworkImpl() - : _httpSimpleCtrlsRouter(*this), - _httpCtrlsRouter(*this), + : _httpCtrlsRouter(*this), + _httpSimpleCtrlsRouter(*this, _httpCtrlsRouter), _websockCtrlsRouter(*this), _uploadPath(_rootPath + "uploads"), _connectionNum(0) @@ -157,8 +157,9 @@ class HttpAppFrameworkImpl : public HttpAppFramework std::unique_ptr> _sessionMapPtr; std::unique_ptr> _responseCachingMap; - HttpSimpleControllersRouter _httpSimpleCtrlsRouter; HttpControllersRouter _httpCtrlsRouter; + HttpSimpleControllersRouter _httpSimpleCtrlsRouter; + WebsocketControllersRouter _websockCtrlsRouter; bool _enableLastModify = true; diff --git a/lib/src/HttpControllersRouter.cc b/lib/src/HttpControllersRouter.cc index 6cf2b514..ef6c7fec 100644 --- a/lib/src/HttpControllersRouter.cc +++ b/lib/src/HttpControllersRouter.cc @@ -138,9 +138,9 @@ void HttpControllersRouter::addHttpPath(const std::string &path, } void HttpControllersRouter::route(const HttpRequestImplPtr &req, - const std::shared_ptr> &callbackPtr, + std::function &&callback, bool needSetJsessionid, - const std::shared_ptr &sessionIdPtr) + std::string &&session_id) { //find http controller if (_ctrlRegex.mark_count() > 0) @@ -165,20 +165,22 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req, //Invalid Http Method auto res = drogon::HttpResponse::newHttpResponse(); res->setStatusCode(HttpResponse::k405MethodNotAllowed); - (*callbackPtr)(res); + callback(res); return; } auto &filters = binder->filtersName; if (!filters.empty()) { + auto sessionIdPtr = std::make_shared(std::move(session_id)); + auto callbackPtr = std::make_shared>(std::move(callback)); _appImpl.doFilters(filters, req, callbackPtr, needSetJsessionid, sessionIdPtr, [=]() { doControllerHandler(binder, routerItem, req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); }); } else { - doControllerHandler(binder, routerItem, req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); + doControllerHandler(binder, routerItem, req, std::move(callback), needSetJsessionid, std::move(session_id)); } } } @@ -188,20 +190,17 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req, //No controller found auto res = drogon::HttpResponse::newNotFoundResponse(); if (needSetJsessionid) - res->addCookie("JSESSIONID", *sessionIdPtr); - - (*callbackPtr)(res); + res->addCookie("JSESSIONID", session_id); + callback(res); } } else { //No controller found auto res = drogon::HttpResponse::newNotFoundResponse(); - if (needSetJsessionid) - res->addCookie("JSESSIONID", *sessionIdPtr); - - (*callbackPtr)(res); + res->addCookie("JSESSIONID", session_id); + callback(res); } } @@ -285,9 +284,12 @@ void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderP } if (needSetJsessionid) { - //make a copy - newResp = std::make_shared(*std::dynamic_pointer_cast(resp)); - newResp->setExpiredTime(-1); //make it temporary + if (resp->expiredTime() >= 0) + { + //make a copy + newResp = std::make_shared(*std::dynamic_pointer_cast(resp)); + newResp->setExpiredTime(-1); //make it temporary + } newResp->addCookie("JSESSIONID", session_id); } callback(newResp); diff --git a/lib/src/HttpControllersRouter.h b/lib/src/HttpControllersRouter.h index 5b18d019..7af3a1e4 100644 --- a/lib/src/HttpControllersRouter.h +++ b/lib/src/HttpControllersRouter.h @@ -36,9 +36,9 @@ class HttpControllersRouter : public trantor::NonCopyable const std::vector &validMethods, const std::vector &filters); void route(const HttpRequestImplPtr &req, - const std::shared_ptr> &callbackPtr, + std::function &&callback, bool needSetJsessionid, - const std::shared_ptr &sessionIdPtr); + std::string &&session_id); private: struct CtrlBinder diff --git a/lib/src/HttpSimpleControllersRouter.cc b/lib/src/HttpSimpleControllersRouter.cc index f85c1361..8370983b 100644 --- a/lib/src/HttpSimpleControllersRouter.cc +++ b/lib/src/HttpSimpleControllersRouter.cc @@ -64,18 +64,18 @@ void HttpSimpleControllersRouter::registerHttpSimpleController(const std::string } } -bool HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req, - const std::shared_ptr> &callbackPtr, +void HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req, + std::function &&callback, bool needSetJsessionid, - const std::shared_ptr &sessionIdPtr) + std::string &&session_id) { - std::string pathLower(req->path()); - std::transform(pathLower.begin(), pathLower.end(), pathLower.begin(), tolower); + std::string pathLower(req->path().length(), 0); + std::transform(req->path().begin(), req->path().end(), pathLower.begin(), tolower); if (_simpCtrlMap.find(pathLower) != _simpCtrlMap.end()) { auto &ctrlInfo = _simpCtrlMap[pathLower]; - if (ctrlInfo._validMethodsFlags.size() > 0) + if (!ctrlInfo._validMethodsFlags.empty()) { assert(ctrlInfo._validMethodsFlags.size() > req->method()); if (ctrlInfo._validMethodsFlags[req->method()] == 0) @@ -83,24 +83,26 @@ bool HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req, //Invalid Http Method auto res = drogon::HttpResponse::newHttpResponse(); res->setStatusCode(HttpResponse::k405MethodNotAllowed); - (*callbackPtr)(res); - return true; + callback(res); + return; } } auto &filters = ctrlInfo.filtersName; if (!filters.empty()) { + auto sessionIdPtr = std::make_shared(std::move(session_id)); + auto callbackPtr = std::make_shared>(std::move(callback)); _appImpl.doFilters(filters, req, callbackPtr, needSetJsessionid, sessionIdPtr, [=, pathLower = std::move(pathLower)]() mutable { doControllerHandler(std::move(pathLower), req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); }); } else { - doControllerHandler(std::move(pathLower), req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); + doControllerHandler(std::move(pathLower), req, std::move(callback), needSetJsessionid, std::move(session_id)); } - return true; + return; } - return false; + _httpCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(session_id)); } void HttpSimpleControllersRouter::doControllerHandler(std::string &&pathLower, @@ -146,7 +148,7 @@ void HttpSimpleControllersRouter::doControllerHandler(std::string &&pathLower, } else { - controller->asyncHandleHttpRequest(req, [callback = std::move(callback), this, pathLower = std::move(pathLower), needSetJsessionid, session_id = std::move(session_id)](const HttpResponsePtr &resp) { + controller->asyncHandleHttpRequest(req, [=, callback = std::move(callback), pathLower = std::move(pathLower), session_id = std::move(session_id)](const HttpResponsePtr &resp) { auto newResp = resp; if (resp->expiredTime() >= 0) { @@ -160,12 +162,14 @@ void HttpSimpleControllersRouter::doControllerHandler(std::string &&pathLower, } if (needSetJsessionid) { - //make a copy - newResp = std::make_shared(*std::dynamic_pointer_cast(resp)); - newResp->setExpiredTime(-1); //make it temporary + if (resp->expiredTime() >= 0) + { + //make a copy + newResp = std::make_shared(*std::dynamic_pointer_cast(resp)); + newResp->setExpiredTime(-1); //make it temporary + } newResp->addCookie("JSESSIONID", session_id); } - callback(newResp); }); } diff --git a/lib/src/HttpSimpleControllersRouter.h b/lib/src/HttpSimpleControllersRouter.h index 8d596011..65ab8c60 100644 --- a/lib/src/HttpSimpleControllersRouter.h +++ b/lib/src/HttpSimpleControllersRouter.h @@ -27,20 +27,24 @@ namespace drogon { class HttpAppFrameworkImpl; +class HttpControllersRouter; class HttpSimpleControllersRouter : public trantor::NonCopyable { public: - HttpSimpleControllersRouter(HttpAppFrameworkImpl &app) : _appImpl(app) {} + HttpSimpleControllersRouter(HttpAppFrameworkImpl &app, HttpControllersRouter &httpCtrlRouter) + : _appImpl(app), + _httpCtrlsRouter(httpCtrlRouter) {} void registerHttpSimpleController(const std::string &pathName, const std::string &ctrlName, const std::vector &filtersAndMethods); - bool route(const HttpRequestImplPtr &req, - const std::shared_ptr> &callbackPtr, + void route(const HttpRequestImplPtr &req, + std::function &&callback, bool needSetJsessionid, - const std::shared_ptr &sessionIdPtr); + std::string &&session_id); private: HttpAppFrameworkImpl &_appImpl; + HttpControllersRouter &_httpCtrlsRouter; struct SimpleControllerRouterItem { std::string controllerName; diff --git a/lib/src/WebsocketControllersRouter.cc b/lib/src/WebsocketControllersRouter.cc index f7509ed6..abbfa862 100644 --- a/lib/src/WebsocketControllersRouter.cc +++ b/lib/src/WebsocketControllersRouter.cc @@ -39,7 +39,7 @@ void WebsocketControllersRouter::registerWebSocketController(const std::string & } void WebsocketControllersRouter::route(const HttpRequestImplPtr &req, - const std::shared_ptr> &callbackPtr, + std::function &&callback, const WebSocketConnectionPtr &wsConnPtr) { std::string wsKey = req->getHeaderBy("sec-websocket-key"); @@ -62,20 +62,21 @@ void WebsocketControllersRouter::route(const HttpRequestImplPtr &req, { if (!filtersName.empty()) { + auto callbackPtr = std::make_shared>(std::move(callback)); _appImpl.doFilters(filtersName, req, callbackPtr, false, nullptr, [=]() mutable { doControllerHandler(ctrlPtr, wsKey, req, *callbackPtr, wsConnPtr); }); } else { - doControllerHandler(ctrlPtr, wsKey, req, *callbackPtr, wsConnPtr); + doControllerHandler(ctrlPtr, wsKey, req, callback, wsConnPtr); } return; } } auto resp = drogon::HttpResponse::newNotFoundResponse(); resp->setCloseConnection(true); - (*callbackPtr)(resp); + callback(resp); } void WebsocketControllersRouter::doControllerHandler(const WebSocketControllerBasePtr &ctrlPtr, diff --git a/lib/src/WebsocketControllersRouter.h b/lib/src/WebsocketControllersRouter.h index 08f22949..1d955aaa 100644 --- a/lib/src/WebsocketControllersRouter.h +++ b/lib/src/WebsocketControllersRouter.h @@ -34,7 +34,7 @@ class WebsocketControllersRouter : public trantor::NonCopyable const std::string &ctrlName, const std::vector &filters); void route(const HttpRequestImplPtr &req, - const std::shared_ptr> &callbackPtr, + std::function &&callback, const WebSocketConnectionPtr &wsConnPtr); private: