diff --git a/examples/simple_example/api_v1_ApiTest.h b/examples/simple_example/api_v1_ApiTest.h index 6e53f16c..3f5ed7c4 100755 --- a/examples/simple_example/api_v1_ApiTest.h +++ b/examples/simple_example/api_v1_ApiTest.h @@ -10,7 +10,7 @@ class ApiTest : public drogon::HttpController public: METHOD_LIST_BEGIN //use METHOD_ADD to add your custom processing function here; - METHOD_ADD(ApiTest::rootGet, "", Get); + METHOD_ADD(ApiTest::rootGet, "", "TimeFilter", Get, "drogon::LocalHostFilter"); METHOD_ADD(ApiTest::rootPost, "", Post); METHOD_ADD(ApiTest::get, "/get/{2}/{1}", Get); //path will be /api/v1/apitest/get/{arg2}/{arg1} METHOD_ADD(ApiTest::your_method_name, "/{1}/List?P2={2}", Get); //path will be /api/v1/apitest/{arg1}/list diff --git a/get_version.sh b/get_version.sh index 918ca54b..15c1d2af 100755 --- a/get_version.sh +++ b/get_version.sh @@ -3,7 +3,7 @@ GIT_VER=$(git log|grep ^commit|wc -l|sed -e "s/^ *//") MD5=$(git log|head -1|awk '{printf $2}') TMP_FILE=/tmp/version -echo "#define VERSION \"0.9.15.$GIT_VER\"" > ${TMP_FILE} +echo "#define VERSION \"0.9.16.$GIT_VER\"" > ${TMP_FILE} echo "#define VERSION_MD5 \"$MD5\"" >> ${TMP_FILE} if [ ! -f $1 ];then mv -f ${TMP_FILE} $1 diff --git a/lib/src/HttpAppFrameworkImpl.cc b/lib/src/HttpAppFrameworkImpl.cc index d49ef074..f850624a 100755 --- a/lib/src/HttpAppFrameworkImpl.cc +++ b/lib/src/HttpAppFrameworkImpl.cc @@ -379,19 +379,24 @@ void HttpAppFrameworkImpl::run() void HttpAppFrameworkImpl::doFilterChain(const std::shared_ptr>> &chain, const HttpRequestImplPtr &req, - const std::function &callback, + const std::shared_ptr> &callbackPtr, bool needSetJsessionid, - const std::string &session_id, - const std::function &missCallback) + const std::shared_ptr &sessionIdPtr, + std::function &&missCallback) { if (chain && chain->size() > 0) { auto filter = chain->front(); chain->pop(); - filter->doFilter(req, [=](HttpResponsePtr res) { - if (needSetJsessionid) - res->addCookie("JSESSIONID", session_id); - callback(res); }, [=]() { doFilterChain(chain, req, callback, needSetJsessionid, session_id, missCallback); }); + filter->doFilter(req, + [=](HttpResponsePtr res) { + if (needSetJsessionid) + res->addCookie("JSESSIONID", *sessionIdPtr); + (*callbackPtr)(res); + }, + [=, missCallback = std::move(missCallback)]() mutable { + doFilterChain(chain, req, callbackPtr, needSetJsessionid, sessionIdPtr, std::move(missCallback)); + }); } else { @@ -400,10 +405,10 @@ void HttpAppFrameworkImpl::doFilterChain(const std::shared_ptr &filters, const HttpRequestImplPtr &req, - const std::function &callback, + const std::shared_ptr> &callbackPtr, bool needSetJsessionid, - const std::string &session_id, - const std::function &missCallback) + const std::shared_ptr &sessionIdPtr, + std::function &&missCallback) { std::shared_ptr>> filterPtrs; if (!filters.empty()) @@ -421,7 +426,7 @@ void HttpAppFrameworkImpl::doFilters(const std::vector &filters, } } } - doFilterChain(filterPtrs, req, callback, needSetJsessionid, session_id, missCallback); + doFilterChain(filterPtrs, req, callbackPtr, needSetJsessionid, sessionIdPtr, std::move(missCallback)); } void HttpAppFrameworkImpl::onWebsockDisconnect(const WebSocketConnectionPtr &wsConnPtr) { @@ -575,12 +580,13 @@ void HttpAppFrameworkImpl::setUploadPath(const std::string &uploadPath) } } void HttpAppFrameworkImpl::onNewWebsockRequest(const HttpRequestImplPtr &req, - const std::function &callback, + std::function &&callback, const WebSocketConnectionPtr &wsConnPtr) { - _websockCtrlsRouter.route(req, callback, wsConnPtr); + auto callbackPtr = std::make_shared>(std::move(callback)); + _websockCtrlsRouter.route(req, callbackPtr, wsConnPtr); } -void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, const std::function &callback) +void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::function &&callback) { LOG_TRACE << "new request:" << req->peerAddr().toIpPort() << "->" << req->localAddr().toIpPort(); LOG_TRACE << "Headers " << req->methodString() << " " << req->path(); @@ -624,7 +630,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, const s (std::dynamic_pointer_cast(req))->setSession((*_sessionMapPtr)[session_id]); } - std::string path = req->path(); + const std::string &path = req->path(); auto pos = path.rfind("."); if (pos != std::string::npos) { @@ -774,12 +780,13 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, const s 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, callback, needSetJsessionid, session_id)) + if (_httpSimpleCtrlsRouter.route(req, callbackPtr, needSetJsessionid, sessionIdPtr)) return; //Find http controller - _httpCtrlsRouter.route(req, callback, needSetJsessionid, session_id); + _httpCtrlsRouter.route(req, callbackPtr, needSetJsessionid, sessionIdPtr); } 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 53b56d66..f3c939d8 100644 --- a/lib/src/HttpAppFrameworkImpl.h +++ b/lib/src/HttpAppFrameworkImpl.h @@ -118,19 +118,19 @@ class HttpAppFrameworkImpl : public HttpAppFramework #endif void doFilters(const std::vector &filters, const HttpRequestImplPtr &req, - const std::function &callback, + const std::shared_ptr> &callbackPtr, bool needSetJsessionid, - const std::string &session_id, - const std::function &missCallback); + const std::shared_ptr &sessionIdPtr, + std::function &&missCallback); private: virtual void registerHttpController(const std::string &pathPattern, const internal::HttpBinderBasePtr &binder, const std::vector &validMethods = std::vector(), const std::vector &filters = std::vector()) override; - void onAsyncRequest(const HttpRequestImplPtr &req, const std::function &callback); + void onAsyncRequest(const HttpRequestImplPtr &req, std::function &&callback); void onNewWebsockRequest(const HttpRequestImplPtr &req, - const std::function &callback, + std::function &&callback, const WebSocketConnectionPtr &wsConnPtr); void onWebsockMessage(const WebSocketConnectionPtr &wsConnPtr, trantor::MsgBuffer *buffer); void onWebsockDisconnect(const WebSocketConnectionPtr &wsConnPtr); @@ -142,10 +142,10 @@ class HttpAppFrameworkImpl : public HttpAppFramework const std::vector &filters); void doFilterChain(const std::shared_ptr>> &chain, const HttpRequestImplPtr &req, - const std::function &callback, + const std::shared_ptr> &callbackPtr, bool needSetJsessionid, - const std::string &session_id, - const std::function &missCallback); + const std::shared_ptr &sessionIdPtr, + std::function &&missCallback); //We use a uuid string as session id; //set _sessionTimeout=0 to make location session valid forever based on cookies; diff --git a/lib/src/HttpControllersRouter.cc b/lib/src/HttpControllersRouter.cc index 53128ec3..6cf2b514 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::function &callback, + const std::shared_ptr> &callbackPtr, bool needSetJsessionid, - const std::string &session_id) + const std::shared_ptr &sessionIdPtr) { //find http controller if (_ctrlRegex.mark_count() > 0) @@ -156,103 +156,30 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req, if (result[i].str() == req->path() && i <= _ctrlVector.size()) { size_t ctlIndex = i - 1; - auto &router = _ctrlVector[ctlIndex]; + auto &routerItem = _ctrlVector[ctlIndex]; //LOG_TRACE << "got http access,regex=" << binder.pathParameterPattern; assert(Invalid > req->method()); - auto &binder = router._binders[req->method()]; + auto &binder = routerItem._binders[req->method()]; if (!binder) { //Invalid Http Method auto res = drogon::HttpResponse::newHttpResponse(); res->setStatusCode(HttpResponse::k405MethodNotAllowed); - callback(res); + (*callbackPtr)(res); return; } auto &filters = binder->filtersName; - _appImpl.doFilters(filters, req, callback, needSetJsessionid, session_id, [=]() { - HttpResponsePtr responsePtr; - { - std::lock_guard guard(*(binder->binderMtx)); - responsePtr = binder->responsePtr; - } - - if (responsePtr && (responsePtr->expiredTime() == 0 || (trantor::Date::now() < responsePtr->createDate().after(responsePtr->expiredTime())))) - { - //use cached response! - LOG_TRACE << "Use cached response"; - - if (!needSetJsessionid) - callback(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", session_id); - callback(newResp); - } - return; - } - - std::vector params(binder->parameterPlaces.size()); - std::smatch r; - if (std::regex_match(req->path(), r, router._regex)) - { - for (size_t j = 1; j < r.size(); j++) - { - size_t place = binder->parameterPlaces[j - 1]; - if (place > params.size()) - params.resize(place); - params[place - 1] = r[j].str(); - LOG_TRACE << "place=" << place << " para:" << params[place - 1]; - } - } - if (binder->queryParametersPlaces.size() > 0) - { - auto qureyPara = req->getParameters(); - for (auto parameter : qureyPara) - { - if (binder->queryParametersPlaces.find(parameter.first) != - binder->queryParametersPlaces.end()) - { - auto place = binder->queryParametersPlaces.find(parameter.first)->second; - if (place > params.size()) - params.resize(place); - params[place - 1] = parameter.second; - } - } - } - std::list paraList; - for (auto p : params) - { - LOG_TRACE << p; - paraList.push_back(std::move(p)); - } - - binder->binderPtr->handleHttpRequest(paraList, req, [=](const HttpResponsePtr &resp) { - LOG_TRACE << "http resp:needSetJsessionid=" << needSetJsessionid << ";JSESSIONID=" << session_id; - auto newResp = resp; - if (resp->expiredTime() >= 0) - { - //cache the response; - std::dynamic_pointer_cast(resp)->makeHeaderString(); - { - std::lock_guard guard(*(binder->binderMtx)); - binder->responsePtr = resp; - } - } - if (needSetJsessionid) - { - //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); + if (!filters.empty()) + { + _appImpl.doFilters(filters, req, callbackPtr, needSetJsessionid, sessionIdPtr, [=]() { + doControllerHandler(binder, routerItem, req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); }); - return; - }); + } + else + { + doControllerHandler(binder, routerItem, req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); + } } } } @@ -261,9 +188,9 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req, //No controller found auto res = drogon::HttpResponse::newNotFoundResponse(); if (needSetJsessionid) - res->addCookie("JSESSIONID", session_id); + res->addCookie("JSESSIONID", *sessionIdPtr); - callback(res); + (*callbackPtr)(res); } } else @@ -272,8 +199,98 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req, auto res = drogon::HttpResponse::newNotFoundResponse(); if (needSetJsessionid) - res->addCookie("JSESSIONID", session_id); + res->addCookie("JSESSIONID", *sessionIdPtr); - callback(res); + (*callbackPtr)(res); } +} + +void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderPtr, + const HttpControllerRouterItem &routerItem, + const HttpRequestImplPtr &req, + std::function &&callback, + bool needSetJsessionid, + std::string &&session_id) +{ + HttpResponsePtr responsePtr; + { + std::lock_guard guard(*(ctrlBinderPtr->binderMtx)); + responsePtr = ctrlBinderPtr->responsePtr; + } + + if (responsePtr && (responsePtr->expiredTime() == 0 || (trantor::Date::now() < responsePtr->createDate().after(responsePtr->expiredTime())))) + { + //use cached response! + LOG_TRACE << "Use cached response"; + + if (!needSetJsessionid) + callback(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", session_id); + callback(newResp); + } + return; + } + + std::vector params(ctrlBinderPtr->parameterPlaces.size()); + std::smatch r; + if (std::regex_match(req->path(), r, routerItem._regex)) + { + for (size_t j = 1; j < r.size(); j++) + { + size_t place = ctrlBinderPtr->parameterPlaces[j - 1]; + if (place > params.size()) + params.resize(place); + params[place - 1] = r[j].str(); + LOG_TRACE << "place=" << place << " para:" << params[place - 1]; + } + } + if (ctrlBinderPtr->queryParametersPlaces.size() > 0) + { + auto qureyPara = req->getParameters(); + for (auto parameter : qureyPara) + { + if (ctrlBinderPtr->queryParametersPlaces.find(parameter.first) != + ctrlBinderPtr->queryParametersPlaces.end()) + { + auto place = ctrlBinderPtr->queryParametersPlaces.find(parameter.first)->second; + if (place > params.size()) + params.resize(place); + params[place - 1] = parameter.second; + } + } + } + std::list paraList; + for (auto p : params) + { + LOG_TRACE << p; + paraList.push_back(std::move(p)); + } + + ctrlBinderPtr->binderPtr->handleHttpRequest(paraList, req, [=, callback = std::move(callback), session_id = std::move(session_id)](const HttpResponsePtr &resp) { + LOG_TRACE << "http resp:needSetJsessionid=" << needSetJsessionid << ";JSESSIONID=" << session_id; + auto newResp = resp; + if (resp->expiredTime() >= 0) + { + //cache the response; + std::dynamic_pointer_cast(resp)->makeHeaderString(); + { + std::lock_guard guard(*(ctrlBinderPtr->binderMtx)); + ctrlBinderPtr->responsePtr = resp; + } + } + if (needSetJsessionid) + { + //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); + }); + return; } \ No newline at end of file diff --git a/lib/src/HttpControllersRouter.h b/lib/src/HttpControllersRouter.h index 92353109..5b18d019 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::function &callback, + const std::shared_ptr> &callbackPtr, bool needSetJsessionid, - const std::string &session_id); + const std::shared_ptr &sessionIdPtr); private: struct CtrlBinder @@ -61,5 +61,12 @@ class HttpControllersRouter : public trantor::NonCopyable std::mutex _ctrlMutex; std::regex _ctrlRegex; HttpAppFrameworkImpl &_appImpl; + + void doControllerHandler(const CtrlBinderPtr &ctrlBinderPtr, + const HttpControllerRouterItem &routerItem, + const HttpRequestImplPtr &req, + std::function &&callback, + bool needSetJsessionid, + std::string &&session_id); }; } // namespace drogon \ No newline at end of file diff --git a/lib/src/HttpServer.cc b/lib/src/HttpServer.cc index 9c9cd7fc..b18d615c 100755 --- a/lib/src/HttpServer.cc +++ b/lib/src/HttpServer.cc @@ -26,7 +26,7 @@ using namespace std::placeholders; using namespace drogon; using namespace trantor; -static void defaultHttpAsyncCallback(const HttpRequestPtr &, const std::function &callback) +static void defaultHttpAsyncCallback(const HttpRequestPtr &, std::function &&callback) { auto resp = HttpResponse::newNotFoundResponse(); resp->setCloseConnection(true); @@ -34,7 +34,7 @@ static void defaultHttpAsyncCallback(const HttpRequestPtr &, const std::function } static void defaultWebSockAsyncCallback(const HttpRequestPtr &, - const std::function &callback, + std::function &&callback, const WebSocketConnectionPtr &wsConnPtr) { auto resp = HttpResponse::newNotFoundResponse(); diff --git a/lib/src/HttpServer.h b/lib/src/HttpServer.h index f0688e71..89d6dc71 100755 --- a/lib/src/HttpServer.h +++ b/lib/src/HttpServer.h @@ -32,9 +32,9 @@ typedef std::shared_ptr HttpRequestPtr; class HttpServer : trantor::NonCopyable { public: - typedef std::function &)> HttpAsyncCallback; + typedef std::function &&)> HttpAsyncCallback; typedef std::function &, + std::function &&, const WebSocketConnectionPtr &)> WebSocketNewAsyncCallback; typedef std::function diff --git a/lib/src/HttpSimpleControllersRouter.cc b/lib/src/HttpSimpleControllersRouter.cc index 8e541f5a..f85c1361 100644 --- a/lib/src/HttpSimpleControllersRouter.cc +++ b/lib/src/HttpSimpleControllersRouter.cc @@ -65,9 +65,9 @@ void HttpSimpleControllersRouter::registerHttpSimpleController(const std::string } bool HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req, - const std::function &callback, + const std::shared_ptr> &callbackPtr, bool needSetJsessionid, - const std::string &session_id) + const std::shared_ptr &sessionIdPtr) { std::string pathLower(req->path()); std::transform(pathLower.begin(), pathLower.end(), pathLower.begin(), tolower); @@ -83,86 +83,102 @@ bool HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req, //Invalid Http Method auto res = drogon::HttpResponse::newHttpResponse(); res->setStatusCode(HttpResponse::k405MethodNotAllowed); - callback(res); + (*callbackPtr)(res); return true; } } auto &filters = ctrlInfo.filtersName; - _appImpl.doFilters(filters, req, callback, needSetJsessionid, session_id, [=]() { - auto &ctrlItem = _simpCtrlMap[pathLower]; - const std::string &ctrlName = ctrlItem.controllerName; - std::shared_ptr controller; - HttpResponsePtr responsePtr; - { - //maybe update controller,so we use lock_guard to protect; - std::lock_guard guard(ctrlItem._mutex); - controller = ctrlItem.controller; - responsePtr = ctrlItem.responsePtr; - if (!controller) - { - auto _object = std::shared_ptr(DrClassMap::newObject(ctrlName)); - controller = std::dynamic_pointer_cast(_object); - ctrlItem.controller = controller; - } - } - - if (controller) - { - if (responsePtr && (responsePtr->expiredTime() == 0 || (trantor::Date::now() < responsePtr->createDate().after(responsePtr->expiredTime())))) - { - //use cached response! - LOG_TRACE << "Use cached response"; - if (!needSetJsessionid) - callback(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", session_id); - callback(newResp); - } - return; - } - else - { - controller->asyncHandleHttpRequest(req, [=](const HttpResponsePtr &resp) { - auto newResp = resp; - if (resp->expiredTime() >= 0) - { - //cache the response; - std::dynamic_pointer_cast(resp)->makeHeaderString(); - { - auto &item = _simpCtrlMap[pathLower]; - std::lock_guard guard(item._mutex); - item.responsePtr = resp; - } - } - if (needSetJsessionid) - { - //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); - }); - } - - return; - } - else - { - LOG_ERROR << "can't find controller " << ctrlName; - auto res = drogon::HttpResponse::newNotFoundResponse(); - if (needSetJsessionid) - res->addCookie("JSESSIONID", session_id); - - callback(res); - } - }); + if (!filters.empty()) + { + _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)); + } return true; } return false; +} + +void HttpSimpleControllersRouter::doControllerHandler(std::string &&pathLower, + const HttpRequestImplPtr &req, + std::function &&callback, + bool needSetJsessionid, + std::string &&session_id) +{ + auto &ctrlItem = _simpCtrlMap[pathLower]; + const std::string &ctrlName = ctrlItem.controllerName; + std::shared_ptr controller; + HttpResponsePtr responsePtr; + { + //maybe update controller,so we use lock_guard to protect; + std::lock_guard guard(ctrlItem._mutex); + controller = ctrlItem.controller; + responsePtr = ctrlItem.responsePtr; + if (!controller) + { + auto _object = std::shared_ptr(DrClassMap::newObject(ctrlName)); + controller = std::dynamic_pointer_cast(_object); + ctrlItem.controller = controller; + } + } + + if (controller) + { + if (responsePtr && (responsePtr->expiredTime() == 0 || (trantor::Date::now() < responsePtr->createDate().after(responsePtr->expiredTime())))) + { + //use cached response! + LOG_TRACE << "Use cached response"; + if (!needSetJsessionid) + callback(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", session_id); + callback(newResp); + } + return; + } + else + { + controller->asyncHandleHttpRequest(req, [callback = std::move(callback), this, pathLower = std::move(pathLower), needSetJsessionid, session_id = std::move(session_id)](const HttpResponsePtr &resp) { + auto newResp = resp; + if (resp->expiredTime() >= 0) + { + //cache the response; + std::dynamic_pointer_cast(resp)->makeHeaderString(); + { + auto &item = _simpCtrlMap[pathLower]; + std::lock_guard guard(item._mutex); + item.responsePtr = resp; + } + } + if (needSetJsessionid) + { + //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); + }); + } + + return; + } + else + { + LOG_ERROR << "can't find controller " << ctrlName; + auto res = drogon::HttpResponse::newNotFoundResponse(); + if (needSetJsessionid) + res->addCookie("JSESSIONID", session_id); + + callback(res); + } } \ No newline at end of file diff --git a/lib/src/HttpSimpleControllersRouter.h b/lib/src/HttpSimpleControllersRouter.h index 347b4412..8d596011 100644 --- a/lib/src/HttpSimpleControllersRouter.h +++ b/lib/src/HttpSimpleControllersRouter.h @@ -35,9 +35,9 @@ class HttpSimpleControllersRouter : public trantor::NonCopyable const std::string &ctrlName, const std::vector &filtersAndMethods); bool route(const HttpRequestImplPtr &req, - const std::function &callback, + const std::shared_ptr> &callbackPtr, bool needSetJsessionid, - const std::string &session_id); + const std::shared_ptr &sessionIdPtr); private: HttpAppFrameworkImpl &_appImpl; @@ -52,5 +52,11 @@ class HttpSimpleControllersRouter : public trantor::NonCopyable }; std::unordered_map _simpCtrlMap; std::mutex _simpCtrlMutex; + + void doControllerHandler(std::string &&pathLower, + const HttpRequestImplPtr &req, + std::function &&callback, + bool needSetJsessionid, + std::string &&session_id); }; } // namespace drogon diff --git a/lib/src/WebsocketControllersRouter.cc b/lib/src/WebsocketControllersRouter.cc index af847274..f7509ed6 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::function &callback, + const std::shared_ptr> &callbackPtr, const WebSocketConnectionPtr &wsConnPtr) { std::string wsKey = req->getHeaderBy("sec-websocket-key"); @@ -60,27 +60,43 @@ void WebsocketControllersRouter::route(const HttpRequestImplPtr &req, } if (ctrlPtr) { - _appImpl.doFilters(filtersName, req, callback, false, "", [=]() mutable { - wsKey.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); - unsigned char accKey[SHA_DIGEST_LENGTH]; - SHA1(reinterpret_cast(wsKey.c_str()), wsKey.length(), accKey); - auto base64Key = base64Encode(accKey, SHA_DIGEST_LENGTH); - auto resp = HttpResponse::newHttpResponse(); - resp->setStatusCode(HttpResponse::k101SwitchingProtocols); - resp->addHeader("Upgrade", "websocket"); - resp->addHeader("Connection", "Upgrade"); - resp->addHeader("Sec-WebSocket-Accept", base64Key); - callback(resp); - auto wsConnImplPtr = std::dynamic_pointer_cast(wsConnPtr); - assert(wsConnImplPtr); - wsConnImplPtr->setController(ctrlPtr); - ctrlPtr->handleNewConnection(req, wsConnPtr); - return; - }); + if (!filtersName.empty()) + { + _appImpl.doFilters(filtersName, req, callbackPtr, false, nullptr, [=]() mutable { + doControllerHandler(ctrlPtr, wsKey, req, *callbackPtr, wsConnPtr); + }); + } + else + { + doControllerHandler(ctrlPtr, wsKey, req, *callbackPtr, wsConnPtr); + } return; } } auto resp = drogon::HttpResponse::newNotFoundResponse(); resp->setCloseConnection(true); + (*callbackPtr)(resp); +} + +void WebsocketControllersRouter::doControllerHandler(const WebSocketControllerBasePtr &ctrlPtr, + std::string &wsKey, + const HttpRequestImplPtr &req, + const std::function &callback, + const WebSocketConnectionPtr &wsConnPtr) +{ + wsKey.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + unsigned char accKey[SHA_DIGEST_LENGTH]; + SHA1(reinterpret_cast(wsKey.c_str()), wsKey.length(), accKey); + auto base64Key = base64Encode(accKey, SHA_DIGEST_LENGTH); + auto resp = HttpResponse::newHttpResponse(); + resp->setStatusCode(HttpResponse::k101SwitchingProtocols); + resp->addHeader("Upgrade", "websocket"); + resp->addHeader("Connection", "Upgrade"); + resp->addHeader("Sec-WebSocket-Accept", base64Key); callback(resp); + auto wsConnImplPtr = std::dynamic_pointer_cast(wsConnPtr); + assert(wsConnImplPtr); + wsConnImplPtr->setController(ctrlPtr); + ctrlPtr->handleNewConnection(req, wsConnPtr); + return; } \ No newline at end of file diff --git a/lib/src/WebsocketControllersRouter.h b/lib/src/WebsocketControllersRouter.h index 7dc21694..08f22949 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::function &callback, + const std::shared_ptr> &callbackPtr, const WebSocketConnectionPtr &wsConnPtr); private: @@ -46,5 +46,11 @@ class WebsocketControllersRouter : public trantor::NonCopyable }; std::unordered_map _websockCtrlMap; std::mutex _websockCtrlMutex; + + void doControllerHandler(const WebSocketControllerBasePtr &ctrlPtr, + std::string &wsKey, + const HttpRequestImplPtr &req, + const std::function &callback, + const WebSocketConnectionPtr &wsConnPtr); }; } // namespace drogon \ No newline at end of file