mirror of
https://gitee.com/an-tao/drogon.git
synced 2024-12-04 04:38:14 +08:00
commit
5ae35abc5b
@ -10,7 +10,7 @@ class ApiTest : public drogon::HttpController<ApiTest>
|
|||||||
public:
|
public:
|
||||||
METHOD_LIST_BEGIN
|
METHOD_LIST_BEGIN
|
||||||
//use METHOD_ADD to add your custom processing function here;
|
//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::rootPost, "", Post);
|
||||||
METHOD_ADD(ApiTest::get, "/get/{2}/{1}", Get); //path will be /api/v1/apitest/get/{arg2}/{arg1}
|
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
|
METHOD_ADD(ApiTest::your_method_name, "/{1}/List?P2={2}", Get); //path will be /api/v1/apitest/{arg1}/list
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
GIT_VER=$(git log|grep ^commit|wc -l|sed -e "s/^ *//")
|
GIT_VER=$(git log|grep ^commit|wc -l|sed -e "s/^ *//")
|
||||||
MD5=$(git log|head -1|awk '{printf $2}')
|
MD5=$(git log|head -1|awk '{printf $2}')
|
||||||
TMP_FILE=/tmp/version
|
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}
|
echo "#define VERSION_MD5 \"$MD5\"" >> ${TMP_FILE}
|
||||||
if [ ! -f $1 ];then
|
if [ ! -f $1 ];then
|
||||||
mv -f ${TMP_FILE} $1
|
mv -f ${TMP_FILE} $1
|
||||||
|
@ -379,19 +379,24 @@ void HttpAppFrameworkImpl::run()
|
|||||||
|
|
||||||
void HttpAppFrameworkImpl::doFilterChain(const std::shared_ptr<std::queue<std::shared_ptr<HttpFilterBase>>> &chain,
|
void HttpAppFrameworkImpl::doFilterChain(const std::shared_ptr<std::queue<std::shared_ptr<HttpFilterBase>>> &chain,
|
||||||
const HttpRequestImplPtr &req,
|
const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
const std::shared_ptr<const std::function<void(const HttpResponsePtr &)>> &callbackPtr,
|
||||||
bool needSetJsessionid,
|
bool needSetJsessionid,
|
||||||
const std::string &session_id,
|
const std::shared_ptr<std::string> &sessionIdPtr,
|
||||||
const std::function<void()> &missCallback)
|
std::function<void()> &&missCallback)
|
||||||
{
|
{
|
||||||
if (chain && chain->size() > 0)
|
if (chain && chain->size() > 0)
|
||||||
{
|
{
|
||||||
auto filter = chain->front();
|
auto filter = chain->front();
|
||||||
chain->pop();
|
chain->pop();
|
||||||
filter->doFilter(req, [=](HttpResponsePtr res) {
|
filter->doFilter(req,
|
||||||
if (needSetJsessionid)
|
[=](HttpResponsePtr res) {
|
||||||
res->addCookie("JSESSIONID", session_id);
|
if (needSetJsessionid)
|
||||||
callback(res); }, [=]() { doFilterChain(chain, req, callback, needSetJsessionid, session_id, missCallback); });
|
res->addCookie("JSESSIONID", *sessionIdPtr);
|
||||||
|
(*callbackPtr)(res);
|
||||||
|
},
|
||||||
|
[=, missCallback = std::move(missCallback)]() mutable {
|
||||||
|
doFilterChain(chain, req, callbackPtr, needSetJsessionid, sessionIdPtr, std::move(missCallback));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -400,10 +405,10 @@ void HttpAppFrameworkImpl::doFilterChain(const std::shared_ptr<std::queue<std::s
|
|||||||
}
|
}
|
||||||
void HttpAppFrameworkImpl::doFilters(const std::vector<std::string> &filters,
|
void HttpAppFrameworkImpl::doFilters(const std::vector<std::string> &filters,
|
||||||
const HttpRequestImplPtr &req,
|
const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
const std::shared_ptr<const std::function<void(const HttpResponsePtr &)>> &callbackPtr,
|
||||||
bool needSetJsessionid,
|
bool needSetJsessionid,
|
||||||
const std::string &session_id,
|
const std::shared_ptr<std::string> &sessionIdPtr,
|
||||||
const std::function<void()> &missCallback)
|
std::function<void()> &&missCallback)
|
||||||
{
|
{
|
||||||
std::shared_ptr<std::queue<std::shared_ptr<HttpFilterBase>>> filterPtrs;
|
std::shared_ptr<std::queue<std::shared_ptr<HttpFilterBase>>> filterPtrs;
|
||||||
if (!filters.empty())
|
if (!filters.empty())
|
||||||
@ -421,7 +426,7 @@ void HttpAppFrameworkImpl::doFilters(const std::vector<std::string> &filters,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
doFilterChain(filterPtrs, req, callback, needSetJsessionid, session_id, missCallback);
|
doFilterChain(filterPtrs, req, callbackPtr, needSetJsessionid, sessionIdPtr, std::move(missCallback));
|
||||||
}
|
}
|
||||||
void HttpAppFrameworkImpl::onWebsockDisconnect(const WebSocketConnectionPtr &wsConnPtr)
|
void HttpAppFrameworkImpl::onWebsockDisconnect(const WebSocketConnectionPtr &wsConnPtr)
|
||||||
{
|
{
|
||||||
@ -575,12 +580,12 @@ void HttpAppFrameworkImpl::setUploadPath(const std::string &uploadPath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void HttpAppFrameworkImpl::onNewWebsockRequest(const HttpRequestImplPtr &req,
|
void HttpAppFrameworkImpl::onNewWebsockRequest(const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
const WebSocketConnectionPtr &wsConnPtr)
|
const WebSocketConnectionPtr &wsConnPtr)
|
||||||
{
|
{
|
||||||
_websockCtrlsRouter.route(req, callback, wsConnPtr);
|
_websockCtrlsRouter.route(req, std::move(callback), wsConnPtr);
|
||||||
}
|
}
|
||||||
void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, const std::function<void(const HttpResponsePtr &)> &callback)
|
void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
|
||||||
{
|
{
|
||||||
LOG_TRACE << "new request:" << req->peerAddr().toIpPort() << "->" << req->localAddr().toIpPort();
|
LOG_TRACE << "new request:" << req->peerAddr().toIpPort() << "->" << req->localAddr().toIpPort();
|
||||||
LOG_TRACE << "Headers " << req->methodString() << " " << req->path();
|
LOG_TRACE << "Headers " << req->methodString() << " " << req->path();
|
||||||
@ -624,7 +629,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, const s
|
|||||||
(std::dynamic_pointer_cast<HttpRequestImpl>(req))->setSession((*_sessionMapPtr)[session_id]);
|
(std::dynamic_pointer_cast<HttpRequestImpl>(req))->setSession((*_sessionMapPtr)[session_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string path = req->path();
|
const std::string &path = req->path();
|
||||||
auto pos = path.rfind(".");
|
auto pos = path.rfind(".");
|
||||||
if (pos != std::string::npos)
|
if (pos != std::string::npos)
|
||||||
{
|
{
|
||||||
@ -775,11 +780,8 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, const s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//find simple controller
|
//Route to controller
|
||||||
if (_httpSimpleCtrlsRouter.route(req, callback, needSetJsessionid, session_id))
|
_httpSimpleCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(session_id));
|
||||||
return;
|
|
||||||
//Find http controller
|
|
||||||
_httpCtrlsRouter.route(req, callback, needSetJsessionid, session_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpAppFrameworkImpl::readSendFile(const std::string &filePath, const HttpRequestImplPtr &req, const HttpResponsePtr &resp)
|
void HttpAppFrameworkImpl::readSendFile(const std::string &filePath, const HttpRequestImplPtr &req, const HttpResponsePtr &resp)
|
||||||
|
@ -39,8 +39,8 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HttpAppFrameworkImpl()
|
HttpAppFrameworkImpl()
|
||||||
: _httpSimpleCtrlsRouter(*this),
|
: _httpCtrlsRouter(*this),
|
||||||
_httpCtrlsRouter(*this),
|
_httpSimpleCtrlsRouter(*this, _httpCtrlsRouter),
|
||||||
_websockCtrlsRouter(*this),
|
_websockCtrlsRouter(*this),
|
||||||
_uploadPath(_rootPath + "uploads"),
|
_uploadPath(_rootPath + "uploads"),
|
||||||
_connectionNum(0)
|
_connectionNum(0)
|
||||||
@ -118,19 +118,19 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||||||
#endif
|
#endif
|
||||||
void doFilters(const std::vector<std::string> &filters,
|
void doFilters(const std::vector<std::string> &filters,
|
||||||
const HttpRequestImplPtr &req,
|
const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
const std::shared_ptr<const std::function<void(const HttpResponsePtr &)>> &callbackPtr,
|
||||||
bool needSetJsessionid,
|
bool needSetJsessionid,
|
||||||
const std::string &session_id,
|
const std::shared_ptr<std::string> &sessionIdPtr,
|
||||||
const std::function<void()> &missCallback);
|
std::function<void()> &&missCallback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void registerHttpController(const std::string &pathPattern,
|
virtual void registerHttpController(const std::string &pathPattern,
|
||||||
const internal::HttpBinderBasePtr &binder,
|
const internal::HttpBinderBasePtr &binder,
|
||||||
const std::vector<HttpMethod> &validMethods = std::vector<HttpMethod>(),
|
const std::vector<HttpMethod> &validMethods = std::vector<HttpMethod>(),
|
||||||
const std::vector<std::string> &filters = std::vector<std::string>()) override;
|
const std::vector<std::string> &filters = std::vector<std::string>()) override;
|
||||||
void onAsyncRequest(const HttpRequestImplPtr &req, const std::function<void(const HttpResponsePtr &)> &callback);
|
void onAsyncRequest(const HttpRequestImplPtr &req, std::function<void(const HttpResponsePtr &)> &&callback);
|
||||||
void onNewWebsockRequest(const HttpRequestImplPtr &req,
|
void onNewWebsockRequest(const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
const WebSocketConnectionPtr &wsConnPtr);
|
const WebSocketConnectionPtr &wsConnPtr);
|
||||||
void onWebsockMessage(const WebSocketConnectionPtr &wsConnPtr, trantor::MsgBuffer *buffer);
|
void onWebsockMessage(const WebSocketConnectionPtr &wsConnPtr, trantor::MsgBuffer *buffer);
|
||||||
void onWebsockDisconnect(const WebSocketConnectionPtr &wsConnPtr);
|
void onWebsockDisconnect(const WebSocketConnectionPtr &wsConnPtr);
|
||||||
@ -142,10 +142,10 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||||||
const std::vector<std::string> &filters);
|
const std::vector<std::string> &filters);
|
||||||
void doFilterChain(const std::shared_ptr<std::queue<std::shared_ptr<HttpFilterBase>>> &chain,
|
void doFilterChain(const std::shared_ptr<std::queue<std::shared_ptr<HttpFilterBase>>> &chain,
|
||||||
const HttpRequestImplPtr &req,
|
const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
const std::shared_ptr<const std::function<void(const HttpResponsePtr &)>> &callbackPtr,
|
||||||
bool needSetJsessionid,
|
bool needSetJsessionid,
|
||||||
const std::string &session_id,
|
const std::shared_ptr<std::string> &sessionIdPtr,
|
||||||
const std::function<void()> &missCallback);
|
std::function<void()> &&missCallback);
|
||||||
|
|
||||||
//We use a uuid string as session id;
|
//We use a uuid string as session id;
|
||||||
//set _sessionTimeout=0 to make location session valid forever based on cookies;
|
//set _sessionTimeout=0 to make location session valid forever based on cookies;
|
||||||
@ -157,8 +157,9 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||||||
std::unique_ptr<CacheMap<std::string, SessionPtr>> _sessionMapPtr;
|
std::unique_ptr<CacheMap<std::string, SessionPtr>> _sessionMapPtr;
|
||||||
std::unique_ptr<CacheMap<std::string, HttpResponsePtr>> _responseCachingMap;
|
std::unique_ptr<CacheMap<std::string, HttpResponsePtr>> _responseCachingMap;
|
||||||
|
|
||||||
HttpSimpleControllersRouter _httpSimpleCtrlsRouter;
|
|
||||||
HttpControllersRouter _httpCtrlsRouter;
|
HttpControllersRouter _httpCtrlsRouter;
|
||||||
|
HttpSimpleControllersRouter _httpSimpleCtrlsRouter;
|
||||||
|
|
||||||
WebsocketControllersRouter _websockCtrlsRouter;
|
WebsocketControllersRouter _websockCtrlsRouter;
|
||||||
|
|
||||||
bool _enableLastModify = true;
|
bool _enableLastModify = true;
|
||||||
|
@ -138,9 +138,9 @@ void HttpControllersRouter::addHttpPath(const std::string &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HttpControllersRouter::route(const HttpRequestImplPtr &req,
|
void HttpControllersRouter::route(const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
bool needSetJsessionid,
|
bool needSetJsessionid,
|
||||||
const std::string &session_id)
|
std::string &&session_id)
|
||||||
{
|
{
|
||||||
//find http controller
|
//find http controller
|
||||||
if (_ctrlRegex.mark_count() > 0)
|
if (_ctrlRegex.mark_count() > 0)
|
||||||
@ -156,10 +156,10 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req,
|
|||||||
if (result[i].str() == req->path() && i <= _ctrlVector.size())
|
if (result[i].str() == req->path() && i <= _ctrlVector.size())
|
||||||
{
|
{
|
||||||
size_t ctlIndex = i - 1;
|
size_t ctlIndex = i - 1;
|
||||||
auto &router = _ctrlVector[ctlIndex];
|
auto &routerItem = _ctrlVector[ctlIndex];
|
||||||
//LOG_TRACE << "got http access,regex=" << binder.pathParameterPattern;
|
//LOG_TRACE << "got http access,regex=" << binder.pathParameterPattern;
|
||||||
assert(Invalid > req->method());
|
assert(Invalid > req->method());
|
||||||
auto &binder = router._binders[req->method()];
|
auto &binder = routerItem._binders[req->method()];
|
||||||
if (!binder)
|
if (!binder)
|
||||||
{
|
{
|
||||||
//Invalid Http Method
|
//Invalid Http Method
|
||||||
@ -170,89 +170,18 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto &filters = binder->filtersName;
|
auto &filters = binder->filtersName;
|
||||||
_appImpl.doFilters(filters, req, callback, needSetJsessionid, session_id, [=]() {
|
if (!filters.empty())
|
||||||
HttpResponsePtr responsePtr;
|
{
|
||||||
{
|
auto sessionIdPtr = std::make_shared<std::string>(std::move(session_id));
|
||||||
std::lock_guard<std::mutex> guard(*(binder->binderMtx));
|
auto callbackPtr = std::make_shared<std::function<void(const HttpResponsePtr &)>>(std::move(callback));
|
||||||
responsePtr = binder->responsePtr;
|
_appImpl.doFilters(filters, req, callbackPtr, needSetJsessionid, sessionIdPtr, [=]() {
|
||||||
}
|
doControllerHandler(binder, routerItem, req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr));
|
||||||
|
|
||||||
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<HttpResponseImpl>(*std::dynamic_pointer_cast<HttpResponseImpl>(responsePtr));
|
|
||||||
newResp->setExpiredTime(-1); //make it temporary
|
|
||||||
newResp->addCookie("JSESSIONID", session_id);
|
|
||||||
callback(newResp);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> 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<std::string> 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<HttpResponseImpl>(resp)->makeHeaderString();
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> guard(*(binder->binderMtx));
|
|
||||||
binder->responsePtr = resp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (needSetJsessionid)
|
|
||||||
{
|
|
||||||
//make a copy
|
|
||||||
newResp = std::make_shared<HttpResponseImpl>(*std::dynamic_pointer_cast<HttpResponseImpl>(resp));
|
|
||||||
newResp->setExpiredTime(-1); //make it temporary
|
|
||||||
newResp->addCookie("JSESSIONID", session_id);
|
|
||||||
}
|
|
||||||
callback(newResp);
|
|
||||||
});
|
});
|
||||||
return;
|
}
|
||||||
});
|
else
|
||||||
|
{
|
||||||
|
doControllerHandler(binder, routerItem, req, std::move(callback), needSetJsessionid, std::move(session_id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,7 +191,6 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req,
|
|||||||
auto res = drogon::HttpResponse::newNotFoundResponse();
|
auto res = drogon::HttpResponse::newNotFoundResponse();
|
||||||
if (needSetJsessionid)
|
if (needSetJsessionid)
|
||||||
res->addCookie("JSESSIONID", session_id);
|
res->addCookie("JSESSIONID", session_id);
|
||||||
|
|
||||||
callback(res);
|
callback(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,10 +198,101 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req,
|
|||||||
{
|
{
|
||||||
//No controller found
|
//No controller found
|
||||||
auto res = drogon::HttpResponse::newNotFoundResponse();
|
auto res = drogon::HttpResponse::newNotFoundResponse();
|
||||||
|
|
||||||
if (needSetJsessionid)
|
if (needSetJsessionid)
|
||||||
res->addCookie("JSESSIONID", session_id);
|
res->addCookie("JSESSIONID", session_id);
|
||||||
|
|
||||||
callback(res);
|
callback(res);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderPtr,
|
||||||
|
const HttpControllerRouterItem &routerItem,
|
||||||
|
const HttpRequestImplPtr &req,
|
||||||
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
|
bool needSetJsessionid,
|
||||||
|
std::string &&session_id)
|
||||||
|
{
|
||||||
|
HttpResponsePtr responsePtr;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> 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<HttpResponseImpl>(*std::dynamic_pointer_cast<HttpResponseImpl>(responsePtr));
|
||||||
|
newResp->setExpiredTime(-1); //make it temporary
|
||||||
|
newResp->addCookie("JSESSIONID", session_id);
|
||||||
|
callback(newResp);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> 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<std::string> 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<HttpResponseImpl>(resp)->makeHeaderString();
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(*(ctrlBinderPtr->binderMtx));
|
||||||
|
ctrlBinderPtr->responsePtr = resp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needSetJsessionid)
|
||||||
|
{
|
||||||
|
if (resp->expiredTime() >= 0)
|
||||||
|
{
|
||||||
|
//make a copy
|
||||||
|
newResp = std::make_shared<HttpResponseImpl>(*std::dynamic_pointer_cast<HttpResponseImpl>(resp));
|
||||||
|
newResp->setExpiredTime(-1); //make it temporary
|
||||||
|
}
|
||||||
|
newResp->addCookie("JSESSIONID", session_id);
|
||||||
|
}
|
||||||
|
callback(newResp);
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
@ -36,9 +36,9 @@ class HttpControllersRouter : public trantor::NonCopyable
|
|||||||
const std::vector<HttpMethod> &validMethods,
|
const std::vector<HttpMethod> &validMethods,
|
||||||
const std::vector<std::string> &filters);
|
const std::vector<std::string> &filters);
|
||||||
void route(const HttpRequestImplPtr &req,
|
void route(const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
bool needSetJsessionid,
|
bool needSetJsessionid,
|
||||||
const std::string &session_id);
|
std::string &&session_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CtrlBinder
|
struct CtrlBinder
|
||||||
@ -61,5 +61,12 @@ class HttpControllersRouter : public trantor::NonCopyable
|
|||||||
std::mutex _ctrlMutex;
|
std::mutex _ctrlMutex;
|
||||||
std::regex _ctrlRegex;
|
std::regex _ctrlRegex;
|
||||||
HttpAppFrameworkImpl &_appImpl;
|
HttpAppFrameworkImpl &_appImpl;
|
||||||
|
|
||||||
|
void doControllerHandler(const CtrlBinderPtr &ctrlBinderPtr,
|
||||||
|
const HttpControllerRouterItem &routerItem,
|
||||||
|
const HttpRequestImplPtr &req,
|
||||||
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
|
bool needSetJsessionid,
|
||||||
|
std::string &&session_id);
|
||||||
};
|
};
|
||||||
} // namespace drogon
|
} // namespace drogon
|
@ -26,7 +26,7 @@ using namespace std::placeholders;
|
|||||||
using namespace drogon;
|
using namespace drogon;
|
||||||
using namespace trantor;
|
using namespace trantor;
|
||||||
|
|
||||||
static void defaultHttpAsyncCallback(const HttpRequestPtr &, const std::function<void(const HttpResponsePtr &resp)> &callback)
|
static void defaultHttpAsyncCallback(const HttpRequestPtr &, std::function<void(const HttpResponsePtr &resp)> &&callback)
|
||||||
{
|
{
|
||||||
auto resp = HttpResponse::newNotFoundResponse();
|
auto resp = HttpResponse::newNotFoundResponse();
|
||||||
resp->setCloseConnection(true);
|
resp->setCloseConnection(true);
|
||||||
@ -34,7 +34,7 @@ static void defaultHttpAsyncCallback(const HttpRequestPtr &, const std::function
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void defaultWebSockAsyncCallback(const HttpRequestPtr &,
|
static void defaultWebSockAsyncCallback(const HttpRequestPtr &,
|
||||||
const std::function<void(const HttpResponsePtr &resp)> &callback,
|
std::function<void(const HttpResponsePtr &resp)> &&callback,
|
||||||
const WebSocketConnectionPtr &wsConnPtr)
|
const WebSocketConnectionPtr &wsConnPtr)
|
||||||
{
|
{
|
||||||
auto resp = HttpResponse::newNotFoundResponse();
|
auto resp = HttpResponse::newNotFoundResponse();
|
||||||
|
@ -32,9 +32,9 @@ typedef std::shared_ptr<HttpRequest> HttpRequestPtr;
|
|||||||
class HttpServer : trantor::NonCopyable
|
class HttpServer : trantor::NonCopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<void(const HttpRequestImplPtr &, const std::function<void(const HttpResponsePtr &)> &)> HttpAsyncCallback;
|
typedef std::function<void(const HttpRequestImplPtr &, std::function<void(const HttpResponsePtr &)> &&)> HttpAsyncCallback;
|
||||||
typedef std::function<void(const HttpRequestImplPtr &,
|
typedef std::function<void(const HttpRequestImplPtr &,
|
||||||
const std::function<void(const HttpResponsePtr &)> &,
|
std::function<void(const HttpResponsePtr &)> &&,
|
||||||
const WebSocketConnectionPtr &)>
|
const WebSocketConnectionPtr &)>
|
||||||
WebSocketNewAsyncCallback;
|
WebSocketNewAsyncCallback;
|
||||||
typedef std::function<void(const WebSocketConnectionPtr &)>
|
typedef std::function<void(const WebSocketConnectionPtr &)>
|
||||||
|
@ -64,18 +64,18 @@ void HttpSimpleControllersRouter::registerHttpSimpleController(const std::string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req,
|
void HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
bool needSetJsessionid,
|
bool needSetJsessionid,
|
||||||
const std::string &session_id)
|
std::string &&session_id)
|
||||||
{
|
{
|
||||||
std::string pathLower(req->path());
|
std::string pathLower(req->path().length(), 0);
|
||||||
std::transform(pathLower.begin(), pathLower.end(), pathLower.begin(), tolower);
|
std::transform(req->path().begin(), req->path().end(), pathLower.begin(), tolower);
|
||||||
|
|
||||||
if (_simpCtrlMap.find(pathLower) != _simpCtrlMap.end())
|
if (_simpCtrlMap.find(pathLower) != _simpCtrlMap.end())
|
||||||
{
|
{
|
||||||
auto &ctrlInfo = _simpCtrlMap[pathLower];
|
auto &ctrlInfo = _simpCtrlMap[pathLower];
|
||||||
if (ctrlInfo._validMethodsFlags.size() > 0)
|
if (!ctrlInfo._validMethodsFlags.empty())
|
||||||
{
|
{
|
||||||
assert(ctrlInfo._validMethodsFlags.size() > req->method());
|
assert(ctrlInfo._validMethodsFlags.size() > req->method());
|
||||||
if (ctrlInfo._validMethodsFlags[req->method()] == 0)
|
if (ctrlInfo._validMethodsFlags[req->method()] == 0)
|
||||||
@ -84,85 +84,105 @@ bool HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req,
|
|||||||
auto res = drogon::HttpResponse::newHttpResponse();
|
auto res = drogon::HttpResponse::newHttpResponse();
|
||||||
res->setStatusCode(HttpResponse::k405MethodNotAllowed);
|
res->setStatusCode(HttpResponse::k405MethodNotAllowed);
|
||||||
callback(res);
|
callback(res);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto &filters = ctrlInfo.filtersName;
|
auto &filters = ctrlInfo.filtersName;
|
||||||
_appImpl.doFilters(filters, req, callback, needSetJsessionid, session_id, [=]() {
|
if (!filters.empty())
|
||||||
auto &ctrlItem = _simpCtrlMap[pathLower];
|
{
|
||||||
const std::string &ctrlName = ctrlItem.controllerName;
|
auto sessionIdPtr = std::make_shared<std::string>(std::move(session_id));
|
||||||
std::shared_ptr<HttpSimpleControllerBase> controller;
|
auto callbackPtr = std::make_shared<std::function<void(const HttpResponsePtr &)>>(std::move(callback));
|
||||||
HttpResponsePtr responsePtr;
|
_appImpl.doFilters(filters, req, callbackPtr, needSetJsessionid, sessionIdPtr, [=, pathLower = std::move(pathLower)]() mutable {
|
||||||
{
|
doControllerHandler(std::move(pathLower), req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr));
|
||||||
//maybe update controller,so we use lock_guard to protect;
|
});
|
||||||
std::lock_guard<std::mutex> guard(ctrlItem._mutex);
|
}
|
||||||
controller = ctrlItem.controller;
|
else
|
||||||
responsePtr = ctrlItem.responsePtr;
|
{
|
||||||
if (!controller)
|
doControllerHandler(std::move(pathLower), req, std::move(callback), needSetJsessionid, std::move(session_id));
|
||||||
{
|
}
|
||||||
auto _object = std::shared_ptr<DrObjectBase>(DrClassMap::newObject(ctrlName));
|
return;
|
||||||
controller = std::dynamic_pointer_cast<HttpSimpleControllerBase>(_object);
|
}
|
||||||
ctrlItem.controller = controller;
|
_httpCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(session_id));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (controller)
|
void HttpSimpleControllersRouter::doControllerHandler(std::string &&pathLower,
|
||||||
{
|
const HttpRequestImplPtr &req,
|
||||||
if (responsePtr && (responsePtr->expiredTime() == 0 || (trantor::Date::now() < responsePtr->createDate().after(responsePtr->expiredTime()))))
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
{
|
bool needSetJsessionid,
|
||||||
//use cached response!
|
std::string &&session_id)
|
||||||
LOG_TRACE << "Use cached response";
|
{
|
||||||
if (!needSetJsessionid)
|
auto &ctrlItem = _simpCtrlMap[pathLower];
|
||||||
callback(responsePtr);
|
const std::string &ctrlName = ctrlItem.controllerName;
|
||||||
else
|
std::shared_ptr<HttpSimpleControllerBase> controller;
|
||||||
{
|
HttpResponsePtr responsePtr;
|
||||||
//make a copy response;
|
{
|
||||||
auto newResp = std::make_shared<HttpResponseImpl>(*std::dynamic_pointer_cast<HttpResponseImpl>(responsePtr));
|
//maybe update controller,so we use lock_guard to protect;
|
||||||
newResp->setExpiredTime(-1); //make it temporary
|
std::lock_guard<std::mutex> guard(ctrlItem._mutex);
|
||||||
newResp->addCookie("JSESSIONID", session_id);
|
controller = ctrlItem.controller;
|
||||||
callback(newResp);
|
responsePtr = ctrlItem.responsePtr;
|
||||||
}
|
if (!controller)
|
||||||
return;
|
{
|
||||||
}
|
auto _object = std::shared_ptr<DrObjectBase>(DrClassMap::newObject(ctrlName));
|
||||||
else
|
controller = std::dynamic_pointer_cast<HttpSimpleControllerBase>(_object);
|
||||||
{
|
ctrlItem.controller = controller;
|
||||||
controller->asyncHandleHttpRequest(req, [=](const HttpResponsePtr &resp) {
|
}
|
||||||
auto newResp = resp;
|
}
|
||||||
if (resp->expiredTime() >= 0)
|
|
||||||
{
|
|
||||||
//cache the response;
|
|
||||||
std::dynamic_pointer_cast<HttpResponseImpl>(resp)->makeHeaderString();
|
|
||||||
{
|
|
||||||
auto &item = _simpCtrlMap[pathLower];
|
|
||||||
std::lock_guard<std::mutex> guard(item._mutex);
|
|
||||||
item.responsePtr = resp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (needSetJsessionid)
|
|
||||||
{
|
|
||||||
//make a copy
|
|
||||||
newResp = std::make_shared<HttpResponseImpl>(*std::dynamic_pointer_cast<HttpResponseImpl>(resp));
|
|
||||||
newResp->setExpiredTime(-1); //make it temporary
|
|
||||||
newResp->addCookie("JSESSIONID", session_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(newResp);
|
if (controller)
|
||||||
});
|
{
|
||||||
}
|
if (responsePtr && (responsePtr->expiredTime() == 0 || (trantor::Date::now() < responsePtr->createDate().after(responsePtr->expiredTime()))))
|
||||||
|
{
|
||||||
return;
|
//use cached response!
|
||||||
}
|
LOG_TRACE << "Use cached response";
|
||||||
|
if (!needSetJsessionid)
|
||||||
|
callback(responsePtr);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_ERROR << "can't find controller " << ctrlName;
|
//make a copy response;
|
||||||
auto res = drogon::HttpResponse::newNotFoundResponse();
|
auto newResp = std::make_shared<HttpResponseImpl>(*std::dynamic_pointer_cast<HttpResponseImpl>(responsePtr));
|
||||||
if (needSetJsessionid)
|
newResp->setExpiredTime(-1); //make it temporary
|
||||||
res->addCookie("JSESSIONID", session_id);
|
newResp->addCookie("JSESSIONID", session_id);
|
||||||
|
callback(newResp);
|
||||||
callback(res);
|
|
||||||
}
|
}
|
||||||
});
|
return;
|
||||||
return true;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//cache the response;
|
||||||
|
std::dynamic_pointer_cast<HttpResponseImpl>(resp)->makeHeaderString();
|
||||||
|
{
|
||||||
|
auto &item = _simpCtrlMap[pathLower];
|
||||||
|
std::lock_guard<std::mutex> guard(item._mutex);
|
||||||
|
item.responsePtr = resp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needSetJsessionid)
|
||||||
|
{
|
||||||
|
if (resp->expiredTime() >= 0)
|
||||||
|
{
|
||||||
|
//make a copy
|
||||||
|
newResp = std::make_shared<HttpResponseImpl>(*std::dynamic_pointer_cast<HttpResponseImpl>(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);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
@ -27,20 +27,24 @@
|
|||||||
namespace drogon
|
namespace drogon
|
||||||
{
|
{
|
||||||
class HttpAppFrameworkImpl;
|
class HttpAppFrameworkImpl;
|
||||||
|
class HttpControllersRouter;
|
||||||
class HttpSimpleControllersRouter : public trantor::NonCopyable
|
class HttpSimpleControllersRouter : public trantor::NonCopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HttpSimpleControllersRouter(HttpAppFrameworkImpl &app) : _appImpl(app) {}
|
HttpSimpleControllersRouter(HttpAppFrameworkImpl &app, HttpControllersRouter &httpCtrlRouter)
|
||||||
|
: _appImpl(app),
|
||||||
|
_httpCtrlsRouter(httpCtrlRouter) {}
|
||||||
void registerHttpSimpleController(const std::string &pathName,
|
void registerHttpSimpleController(const std::string &pathName,
|
||||||
const std::string &ctrlName,
|
const std::string &ctrlName,
|
||||||
const std::vector<any> &filtersAndMethods);
|
const std::vector<any> &filtersAndMethods);
|
||||||
bool route(const HttpRequestImplPtr &req,
|
void route(const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
bool needSetJsessionid,
|
bool needSetJsessionid,
|
||||||
const std::string &session_id);
|
std::string &&session_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HttpAppFrameworkImpl &_appImpl;
|
HttpAppFrameworkImpl &_appImpl;
|
||||||
|
HttpControllersRouter &_httpCtrlsRouter;
|
||||||
struct SimpleControllerRouterItem
|
struct SimpleControllerRouterItem
|
||||||
{
|
{
|
||||||
std::string controllerName;
|
std::string controllerName;
|
||||||
@ -52,5 +56,11 @@ class HttpSimpleControllersRouter : public trantor::NonCopyable
|
|||||||
};
|
};
|
||||||
std::unordered_map<std::string, SimpleControllerRouterItem> _simpCtrlMap;
|
std::unordered_map<std::string, SimpleControllerRouterItem> _simpCtrlMap;
|
||||||
std::mutex _simpCtrlMutex;
|
std::mutex _simpCtrlMutex;
|
||||||
|
|
||||||
|
void doControllerHandler(std::string &&pathLower,
|
||||||
|
const HttpRequestImplPtr &req,
|
||||||
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
|
bool needSetJsessionid,
|
||||||
|
std::string &&session_id);
|
||||||
};
|
};
|
||||||
} // namespace drogon
|
} // namespace drogon
|
||||||
|
@ -39,7 +39,7 @@ void WebsocketControllersRouter::registerWebSocketController(const std::string &
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WebsocketControllersRouter::route(const HttpRequestImplPtr &req,
|
void WebsocketControllersRouter::route(const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
const WebSocketConnectionPtr &wsConnPtr)
|
const WebSocketConnectionPtr &wsConnPtr)
|
||||||
{
|
{
|
||||||
std::string wsKey = req->getHeaderBy("sec-websocket-key");
|
std::string wsKey = req->getHeaderBy("sec-websocket-key");
|
||||||
@ -60,27 +60,44 @@ void WebsocketControllersRouter::route(const HttpRequestImplPtr &req,
|
|||||||
}
|
}
|
||||||
if (ctrlPtr)
|
if (ctrlPtr)
|
||||||
{
|
{
|
||||||
_appImpl.doFilters(filtersName, req, callback, false, "", [=]() mutable {
|
if (!filtersName.empty())
|
||||||
wsKey.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
|
{
|
||||||
unsigned char accKey[SHA_DIGEST_LENGTH];
|
auto callbackPtr = std::make_shared<std::function<void(const HttpResponsePtr &)>>(std::move(callback));
|
||||||
SHA1(reinterpret_cast<const unsigned char *>(wsKey.c_str()), wsKey.length(), accKey);
|
_appImpl.doFilters(filtersName, req, callbackPtr, false, nullptr, [=]() mutable {
|
||||||
auto base64Key = base64Encode(accKey, SHA_DIGEST_LENGTH);
|
doControllerHandler(ctrlPtr, wsKey, req, *callbackPtr, wsConnPtr);
|
||||||
auto resp = HttpResponse::newHttpResponse();
|
});
|
||||||
resp->setStatusCode(HttpResponse::k101SwitchingProtocols);
|
}
|
||||||
resp->addHeader("Upgrade", "websocket");
|
else
|
||||||
resp->addHeader("Connection", "Upgrade");
|
{
|
||||||
resp->addHeader("Sec-WebSocket-Accept", base64Key);
|
doControllerHandler(ctrlPtr, wsKey, req, callback, wsConnPtr);
|
||||||
callback(resp);
|
}
|
||||||
auto wsConnImplPtr = std::dynamic_pointer_cast<WebSocketConnectionImpl>(wsConnPtr);
|
|
||||||
assert(wsConnImplPtr);
|
|
||||||
wsConnImplPtr->setController(ctrlPtr);
|
|
||||||
ctrlPtr->handleNewConnection(req, wsConnPtr);
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto resp = drogon::HttpResponse::newNotFoundResponse();
|
auto resp = drogon::HttpResponse::newNotFoundResponse();
|
||||||
resp->setCloseConnection(true);
|
resp->setCloseConnection(true);
|
||||||
callback(resp);
|
callback(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebsocketControllersRouter::doControllerHandler(const WebSocketControllerBasePtr &ctrlPtr,
|
||||||
|
std::string &wsKey,
|
||||||
|
const HttpRequestImplPtr &req,
|
||||||
|
const std::function<void(const HttpResponsePtr &)> &callback,
|
||||||
|
const WebSocketConnectionPtr &wsConnPtr)
|
||||||
|
{
|
||||||
|
wsKey.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
|
||||||
|
unsigned char accKey[SHA_DIGEST_LENGTH];
|
||||||
|
SHA1(reinterpret_cast<const unsigned char *>(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<WebSocketConnectionImpl>(wsConnPtr);
|
||||||
|
assert(wsConnImplPtr);
|
||||||
|
wsConnImplPtr->setController(ctrlPtr);
|
||||||
|
ctrlPtr->handleNewConnection(req, wsConnPtr);
|
||||||
|
return;
|
||||||
}
|
}
|
@ -34,7 +34,7 @@ class WebsocketControllersRouter : public trantor::NonCopyable
|
|||||||
const std::string &ctrlName,
|
const std::string &ctrlName,
|
||||||
const std::vector<std::string> &filters);
|
const std::vector<std::string> &filters);
|
||||||
void route(const HttpRequestImplPtr &req,
|
void route(const HttpRequestImplPtr &req,
|
||||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
const WebSocketConnectionPtr &wsConnPtr);
|
const WebSocketConnectionPtr &wsConnPtr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -46,5 +46,11 @@ class WebsocketControllersRouter : public trantor::NonCopyable
|
|||||||
};
|
};
|
||||||
std::unordered_map<std::string, WebSocketControllerRouterItem> _websockCtrlMap;
|
std::unordered_map<std::string, WebSocketControllerRouterItem> _websockCtrlMap;
|
||||||
std::mutex _websockCtrlMutex;
|
std::mutex _websockCtrlMutex;
|
||||||
|
|
||||||
|
void doControllerHandler(const WebSocketControllerBasePtr &ctrlPtr,
|
||||||
|
std::string &wsKey,
|
||||||
|
const HttpRequestImplPtr &req,
|
||||||
|
const std::function<void(const HttpResponsePtr &)> &callback,
|
||||||
|
const WebSocketConnectionPtr &wsConnPtr);
|
||||||
};
|
};
|
||||||
} // namespace drogon
|
} // namespace drogon
|
Loading…
Reference in New Issue
Block a user