diff --git a/lib/inc/drogon/HttpAppFramework.h b/lib/inc/drogon/HttpAppFramework.h index be47698b..4e6a303d 100755 --- a/lib/inc/drogon/HttpAppFramework.h +++ b/lib/inc/drogon/HttpAppFramework.h @@ -203,7 +203,7 @@ class HttpAppFramework : public trantor::NonCopyable */ virtual void registerPreHandlingAdvice(const std::function &advice) = 0; - ///The @param advice is called immediately after the request is handled and a response object is created by handlers or by filters. + ///The @param advice is called immediately after the request is handled and a response object is created by handlers. virtual void registerPostHandlingAdvice(const std::function &advice) = 0; ///End of AOP methods diff --git a/lib/src/HttpAppFrameworkImpl.cc b/lib/src/HttpAppFrameworkImpl.cc index 53b413fd..42aecbb2 100755 --- a/lib/src/HttpAppFrameworkImpl.cc +++ b/lib/src/HttpAppFrameworkImpl.cc @@ -738,66 +738,29 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu observer(req); } } - if (_postHandlingAdvices.empty()) + if (_preRoutingAdvices.empty()) { - if (_preRoutingAdvices.empty()) - { - _httpSimpleCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(sessionId)); - } - else - { - auto callbackPtr = std::make_shared>(std::move(callback)); - auto sessionIdPtr = std::make_shared(std::move(sessionId)); - doAdvicesChain(_preRoutingAdvices, - 0, - req, - std::make_shared>([callbackPtr, needSetJsessionid, sessionIdPtr](const HttpResponsePtr &resp) { - if (!needSetJsessionid) - (*callbackPtr)(resp); - else - { - resp->addCookie("JSESSIONID", *sessionIdPtr); - (*callbackPtr)(resp); - } - }), - [this, callbackPtr, req, needSetJsessionid, sessionIdPtr]() { - _httpSimpleCtrlsRouter.route(req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); - }); - } + _httpSimpleCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(sessionId)); } else { - auto postHandlingCallback = [this, req, callback = std::move(callback)](const HttpResponsePtr &resp) -> void { - for (auto &advice : _postHandlingAdvices) - { - advice(req, resp); - } - callback(resp); - }; - if (_preRoutingAdvices.empty()) - { - _httpSimpleCtrlsRouter.route(req, std::move(postHandlingCallback), needSetJsessionid, std::move(sessionId)); - } - else - { - auto callbackPtr = std::make_shared>(std::move(postHandlingCallback)); - auto sessionIdPtr = std::make_shared(std::move(sessionId)); - doAdvicesChain(_preRoutingAdvices, - 0, - req, - std::make_shared>([callbackPtr, needSetJsessionid, sessionIdPtr](const HttpResponsePtr &resp) { - if (!needSetJsessionid) - (*callbackPtr)(resp); - else - { - resp->addCookie("JSESSIONID", *sessionIdPtr); - (*callbackPtr)(resp); - } - }), - [this, callbackPtr, req, needSetJsessionid, sessionIdPtr]() mutable { - _httpSimpleCtrlsRouter.route(req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); - }); - } + auto callbackPtr = std::make_shared>(std::move(callback)); + auto sessionIdPtr = std::make_shared(std::move(sessionId)); + doAdvicesChain(_preRoutingAdvices, + 0, + req, + std::make_shared>([callbackPtr, needSetJsessionid, sessionIdPtr](const HttpResponsePtr &resp) { + if (!needSetJsessionid) + (*callbackPtr)(resp); + else + { + resp->addCookie("JSESSIONID", *sessionIdPtr); + (*callbackPtr)(resp); + } + }), + [this, callbackPtr, req, needSetJsessionid, sessionIdPtr]() { + _httpSimpleCtrlsRouter.route(req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); + }); } } diff --git a/lib/src/HttpAppFrameworkImpl.h b/lib/src/HttpAppFrameworkImpl.h index ae5263f2..ae7e6871 100644 --- a/lib/src/HttpAppFrameworkImpl.h +++ b/lib/src/HttpAppFrameworkImpl.h @@ -47,10 +47,10 @@ struct InitBeforeMainFunction }; class HttpAppFrameworkImpl : public HttpAppFramework { -public: + public: HttpAppFrameworkImpl() - : _httpCtrlsRouter(_postRoutingAdvices, _postRoutingObservers, _preHandlingAdvices, _preHandlingObservers), - _httpSimpleCtrlsRouter(_httpCtrlsRouter, _postRoutingAdvices, _postRoutingObservers, _preHandlingAdvices, _preHandlingObservers), + : _httpCtrlsRouter(_postRoutingAdvices, _postRoutingObservers, _preHandlingAdvices, _preHandlingObservers, _postHandlingAdvices), + _httpSimpleCtrlsRouter(_httpCtrlsRouter, _postRoutingAdvices, _postRoutingObservers, _preHandlingAdvices, _preHandlingObservers, _postHandlingAdvices), _uploadPath(_rootPath + "uploads"), _connectionNum(0) { @@ -227,7 +227,7 @@ public: } bool useSendfile() { return _useSendfile; } -private: + private: virtual void registerHttpController(const std::string &pathPattern, const internal::HttpBinderBasePtr &binder, const std::vector &validMethods = std::vector(), diff --git a/lib/src/HttpControllersRouter.cc b/lib/src/HttpControllersRouter.cc index 09cfe457..671fc5c7 100644 --- a/lib/src/HttpControllersRouter.cc +++ b/lib/src/HttpControllersRouter.cc @@ -267,33 +267,6 @@ void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderP bool needSetJsessionid, std::string &&sessionId) { - if (req->method() == Options) - { - auto resp = HttpResponse::newHttpResponse(); - resp->setContentTypeCode(ContentType::CT_TEXT_PLAIN); - std::string methods = "OPTIONS,"; - if (routerItem._binders[Get] && routerItem._binders[Get]->_isCORS) - { - methods.append("GET,HEAD,"); - } - if (routerItem._binders[Post] && routerItem._binders[Post]->_isCORS) - { - methods.append("POST,"); - } - if (routerItem._binders[Put] && routerItem._binders[Put]->_isCORS) - { - methods.append("PUT,"); - } - if (routerItem._binders[Delete] && routerItem._binders[Delete]->_isCORS) - { - methods.append("DELETE,"); - } - methods.resize(methods.length() - 1); - resp->addHeader("ALLOW", methods); - callback(resp); - return; - } - HttpResponsePtr &responsePtr = ctrlBinderPtr->_responsePtrMap[req->getLoop()]; if (responsePtr && (responsePtr->expiredTime() == 0 || (trantor::Date::now() < responsePtr->creationDate().after(responsePtr->expiredTime())))) { @@ -301,14 +274,14 @@ void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderP LOG_TRACE << "Use cached response"; if (!needSetJsessionid) - callback(responsePtr); + invokeCallback(callback, req, responsePtr); else { //make a copy response; auto newResp = std::make_shared(*std::dynamic_pointer_cast(responsePtr)); newResp->setExpiredTime(-1); //make it temporary newResp->addCookie("JSESSIONID", sessionId); - callback(newResp); + invokeCallback(callback, req, newResp); } return; } @@ -376,7 +349,7 @@ void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderP } newResp->addCookie("JSESSIONID", sessionId); } - callback(newResp); + invokeCallback(callback, req, newResp); }); return; } @@ -388,6 +361,32 @@ void HttpControllersRouter::doPreHandlingAdvices(const CtrlBinderPtr &ctrlBinder bool needSetJsessionid, std::string &&sessionId) { + if (req->method() == Options) + { + auto resp = HttpResponse::newHttpResponse(); + resp->setContentTypeCode(ContentType::CT_TEXT_PLAIN); + std::string methods = "OPTIONS,"; + if (routerItem._binders[Get] && routerItem._binders[Get]->_isCORS) + { + methods.append("GET,HEAD,"); + } + if (routerItem._binders[Post] && routerItem._binders[Post]->_isCORS) + { + methods.append("POST,"); + } + if (routerItem._binders[Put] && routerItem._binders[Put]->_isCORS) + { + methods.append("PUT,"); + } + if (routerItem._binders[Delete] && routerItem._binders[Delete]->_isCORS) + { + methods.append("DELETE,"); + } + methods.resize(methods.length() - 1); + resp->addHeader("ALLOW", methods); + callback(resp); + return; + } if (!_preHandlingObservers.empty()) { for (auto &observer : _preHandlingObservers) diff --git a/lib/src/HttpControllersRouter.h b/lib/src/HttpControllersRouter.h index 09ff689b..c76cffc7 100644 --- a/lib/src/HttpControllersRouter.h +++ b/lib/src/HttpControllersRouter.h @@ -30,7 +30,7 @@ namespace drogon { class HttpControllersRouter : public trantor::NonCopyable { -public: + public: HttpControllersRouter(const std::deque> @@ -42,11 +42,15 @@ public: const AdviceChainCallback &)>> &preHandlingAdvices, const std::vector> - &preHandlingObservers) + &preHandlingObservers, + const std::deque> + &postHandlingAdvices) : _postRoutingAdvices(postRoutingAdvices), _preHandlingAdvices(preHandlingAdvices), _postRoutingObservers(postRoutingObservers), - _preHandlingObservers(preHandlingObservers) + _preHandlingObservers(preHandlingObservers), + _postHandlingAdvices(postHandlingAdvices) { } void init(const std::vector &ioLoops); @@ -59,7 +63,7 @@ public: bool needSetJsessionid, std::string &&sessionId); -private: + private: struct CtrlBinder { internal::HttpBinderBasePtr _binderPtr; @@ -92,6 +96,10 @@ private: &_postRoutingObservers; const std::vector> &_preHandlingObservers; + const std::deque> + &_postHandlingAdvices; + void doPreHandlingAdvices(const CtrlBinderPtr &ctrlBinderPtr, const HttpControllerRouterItem &routerItem, const HttpRequestImplPtr &req, @@ -105,5 +113,15 @@ private: std::function &&callback, bool needSetJsessionid, std::string &&sessionId); + void invokeCallback(const std::function &callback, + const HttpRequestImplPtr &req, + const HttpResponsePtr &resp) + { + for (auto &advice : _postHandlingAdvices) + { + advice(req, resp); + } + callback(resp); + } }; } // namespace drogon \ No newline at end of file diff --git a/lib/src/HttpSimpleControllersRouter.cc b/lib/src/HttpSimpleControllersRouter.cc index 0714f347..a3e81cbb 100644 --- a/lib/src/HttpSimpleControllersRouter.cc +++ b/lib/src/HttpSimpleControllersRouter.cc @@ -171,46 +171,20 @@ void HttpSimpleControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlB auto &controller = ctrlBinderPtr->_controller; if (controller) { - if (req->method() == Options) - { - auto resp = HttpResponse::newHttpResponse(); - resp->setContentTypeCode(ContentType::CT_TEXT_PLAIN); - std::string methods = "OPTIONS,"; - if (routerItem._binders[Get] && routerItem._binders[Get]->_isCORS) - { - methods.append("GET,HEAD,"); - } - if (routerItem._binders[Post] && routerItem._binders[Post]->_isCORS) - { - methods.append("POST,"); - } - if (routerItem._binders[Put] && routerItem._binders[Put]->_isCORS) - { - methods.append("PUT,"); - } - if (routerItem._binders[Delete] && routerItem._binders[Delete]->_isCORS) - { - methods.append("DELETE,"); - } - methods.resize(methods.length() - 1); - resp->addHeader("ALLOW", methods); - callback(resp); - return; - } HttpResponsePtr &responsePtr = ctrlBinderPtr->_responsePtrMap[req->getLoop()]; if (responsePtr && (responsePtr->expiredTime() == 0 || (trantor::Date::now() < responsePtr->creationDate().after(responsePtr->expiredTime())))) { //use cached response! LOG_TRACE << "Use cached response"; if (!needSetJsessionid) - callback(responsePtr); + invokeCallback(callback, req, responsePtr); else { //make a copy response; auto newResp = std::make_shared(*std::dynamic_pointer_cast(responsePtr)); newResp->setExpiredTime(-1); //make it temporary newResp->addCookie("JSESSIONID", sessionId); - callback(newResp); + invokeCallback(callback, req, newResp); } return; } @@ -244,7 +218,7 @@ void HttpSimpleControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlB } newResp->addCookie("JSESSIONID", sessionId); } - callback(newResp); + invokeCallback(callback, req, newResp); }); } @@ -257,8 +231,7 @@ void HttpSimpleControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlB auto res = drogon::HttpResponse::newNotFoundResponse(); if (needSetJsessionid) res->addCookie("JSESSIONID", sessionId); - - callback(res); + invokeCallback(callback, req, res); } } @@ -289,6 +262,32 @@ void HttpSimpleControllersRouter::doPreHandlingAdvices(const CtrlBinderPtr &ctrl bool needSetJsessionid, std::string &&sessionId) { + if (req->method() == Options) + { + auto resp = HttpResponse::newHttpResponse(); + resp->setContentTypeCode(ContentType::CT_TEXT_PLAIN); + std::string methods = "OPTIONS,"; + if (routerItem._binders[Get] && routerItem._binders[Get]->_isCORS) + { + methods.append("GET,HEAD,"); + } + if (routerItem._binders[Post] && routerItem._binders[Post]->_isCORS) + { + methods.append("POST,"); + } + if (routerItem._binders[Put] && routerItem._binders[Put]->_isCORS) + { + methods.append("PUT,"); + } + if (routerItem._binders[Delete] && routerItem._binders[Delete]->_isCORS) + { + methods.append("DELETE,"); + } + methods.resize(methods.length() - 1); + resp->addHeader("ALLOW", methods); + callback(resp); + return; + } if (!_preHandlingObservers.empty()) { for (auto &observer : _preHandlingObservers) diff --git a/lib/src/HttpSimpleControllersRouter.h b/lib/src/HttpSimpleControllersRouter.h index 8023b740..528cb01a 100644 --- a/lib/src/HttpSimpleControllersRouter.h +++ b/lib/src/HttpSimpleControllersRouter.h @@ -33,7 +33,7 @@ namespace drogon class HttpSimpleControllersRouter : public trantor::NonCopyable { -public: + public: HttpSimpleControllersRouter(HttpControllersRouter &httpCtrlRouter, const std::deque> &preHandlingAdvices, const std::vector> - &preHandlingObservers) + &preHandlingObservers, + const std::deque> + &postHandlingAdvices) : _httpCtrlsRouter(httpCtrlRouter), _postRoutingAdvices(postRoutingAdvices), _preHandlingAdvices(preHandlingAdvices), _postRoutingObservers(postRoutingObservers), - _preHandlingObservers(preHandlingObservers) + _preHandlingObservers(preHandlingObservers), + _postHandlingAdvices(postHandlingAdvices) { } @@ -64,7 +68,7 @@ public: std::string &&sessionId); void init(const std::vector &ioLoops); -private: + private: HttpControllersRouter &_httpCtrlsRouter; const std::deque> &_preHandlingObservers; + + const std::deque> + &_postHandlingAdvices; struct CtrlBinder { std::shared_ptr _controller; @@ -108,5 +116,15 @@ private: std::function &&callback, bool needSetJsessionid, std::string &&sessionId); + void invokeCallback(const std::function &callback, + const HttpRequestImplPtr &req, + const HttpResponsePtr &resp) + { + for (auto &advice : _postHandlingAdvices) + { + advice(req,resp); + } + callback(resp); + } }; } // namespace drogon