mirror of
https://gitee.com/an-tao/drogon.git
synced 2024-12-02 11:47:56 +08:00
Add support for regular expressions when routing (#329)
This commit is contained in:
parent
668533fbbd
commit
62fc82cba1
@ -442,4 +442,16 @@ void ApiTest::attributesTest(
|
||||
|
||||
callback(HttpResponse::newHttpJsonResponse(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
void ApiTest::regexTest(const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
int p1,
|
||||
std::string &&p2)
|
||||
{
|
||||
Json::Value ret;
|
||||
ret["p1"] = p1;
|
||||
ret["p2"] = std::move(p2);
|
||||
auto resp = HttpResponse::newHttpJsonResponse(std::move(ret));
|
||||
callback(resp);
|
||||
}
|
@ -34,6 +34,7 @@ class ApiTest : public drogon::HttpController<ApiTest>
|
||||
METHOD_ADD(ApiTest::jsonTest, "/json", Post);
|
||||
METHOD_ADD(ApiTest::formTest, "/form", Post);
|
||||
METHOD_ADD(ApiTest::attributesTest, "/attrs", Get);
|
||||
ADD_METHOD_VIA_REGEX(ApiTest::regexTest, "/reg/([0-9]*)/(.*)", Get);
|
||||
METHOD_LIST_END
|
||||
|
||||
void get(const HttpRequestPtr &req,
|
||||
@ -61,6 +62,10 @@ class ApiTest : public drogon::HttpController<ApiTest>
|
||||
void attributesTest(
|
||||
const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback);
|
||||
void regexTest(const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
int p1,
|
||||
std::string &&p2);
|
||||
|
||||
public:
|
||||
ApiTest()
|
||||
|
@ -560,6 +560,34 @@ void doTest(const HttpClientPtr &client,
|
||||
}
|
||||
});
|
||||
|
||||
req = HttpRequest::newHttpRequest();
|
||||
req->setMethod(drogon::Get);
|
||||
req->setPath("/reg/123/rest/of/the/path");
|
||||
client->sendRequest(
|
||||
req, [=](ReqResult result, const HttpResponsePtr &resp) {
|
||||
if (result == ReqResult::Ok && resp->getJsonObject())
|
||||
{
|
||||
auto &json = resp->getJsonObject();
|
||||
if (json->isMember("p1") && json->get("p1", 0).asInt() == 123 &&
|
||||
json->isMember("p2") &&
|
||||
json->get("p2", "").asString() == "rest/of/the/path")
|
||||
{
|
||||
outputGood(req, isHttps);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG << resp->getBody();
|
||||
LOG_ERROR << "Error!";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR << "Error!";
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
req = HttpRequest::newHttpRequest();
|
||||
req->setMethod(drogon::Get);
|
||||
req->setPath("/api/v1/apitest/static");
|
||||
|
@ -388,6 +388,58 @@ class HttpAppFramework : public trantor::NonCopyable
|
||||
pathPattern, binder, validMethods, filters, handlerName);
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* @brief Register a handler into the framework via a regular expression.
|
||||
*
|
||||
* @param regExp A regular expression string, when the path of a http
|
||||
* request matches the regular expression, the handler indicated by the
|
||||
* function parameter is called.
|
||||
* @note When the match is successful, Each string that matches a
|
||||
* subexpression is sequentially mapped to a handler parameter.
|
||||
* @param function indicates any type of callable object with a valid
|
||||
* processing interface.
|
||||
* @param filtersAndMethods is the same as the third parameter in the above
|
||||
* method.
|
||||
* @param handlerName a name for the handler.
|
||||
* @return HttpAppFramework&
|
||||
*/
|
||||
template <typename FUNCTION>
|
||||
HttpAppFramework ®isterHandlerViaRegex(
|
||||
const std::string ®Exp,
|
||||
FUNCTION &&function,
|
||||
const std::vector<internal::HttpConstraint> &filtersAndMethods =
|
||||
std::vector<internal::HttpConstraint>{},
|
||||
const std::string &handlerName = "")
|
||||
{
|
||||
LOG_TRACE << "regex:" << regExp;
|
||||
internal::HttpBinderBasePtr binder;
|
||||
|
||||
binder = std::make_shared<internal::HttpBinder<FUNCTION>>(
|
||||
std::forward<FUNCTION>(function));
|
||||
|
||||
std::vector<HttpMethod> validMethods;
|
||||
std::vector<std::string> filters;
|
||||
for (auto const &filterOrMethod : filtersAndMethods)
|
||||
{
|
||||
if (filterOrMethod.type() == internal::ConstraintType::HttpFilter)
|
||||
{
|
||||
filters.push_back(filterOrMethod.getFilterName());
|
||||
}
|
||||
else if (filterOrMethod.type() ==
|
||||
internal::ConstraintType::HttpMethod)
|
||||
{
|
||||
validMethods.push_back(filterOrMethod.getHttpMethod());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR << "Invalid controller constraint type";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
registerHttpControllerViaRegex(
|
||||
regExp, binder, validMethods, filters, handlerName);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Register a WebSocketController into the framework.
|
||||
/**
|
||||
@ -947,6 +999,12 @@ class HttpAppFramework : public trantor::NonCopyable
|
||||
const std::vector<HttpMethod> &validMethods = std::vector<HttpMethod>(),
|
||||
const std::vector<std::string> &filters = std::vector<std::string>(),
|
||||
const std::string &handlerName = "") = 0;
|
||||
virtual void registerHttpControllerViaRegex(
|
||||
const std::string ®Exp,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
const std::vector<HttpMethod> &validMethods,
|
||||
const std::vector<std::string> &filters,
|
||||
const std::string &handlerName) = 0;
|
||||
};
|
||||
|
||||
/// A wrapper of the instance() method
|
||||
|
@ -34,6 +34,9 @@
|
||||
#define ADD_METHOD_TO(method, path_pattern, filters...) \
|
||||
registerMethod(&method, path_pattern, {filters}, false, #method)
|
||||
|
||||
#define ADD_METHOD_VIA_REGEX(method, regex, filters...) \
|
||||
registerMethodViaRegex(&method, regex, {filters}, #method)
|
||||
|
||||
#define METHOD_LIST_END \
|
||||
return; \
|
||||
}
|
||||
@ -108,6 +111,20 @@ class HttpController : public DrObject<T>, public HttpControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FUNCTION>
|
||||
static void registerMethodViaRegex(
|
||||
FUNCTION &&function,
|
||||
const std::string ®Exp,
|
||||
const std::vector<internal::HttpConstraint> &filtersAndMethods =
|
||||
std::vector<internal::HttpConstraint>{},
|
||||
const std::string &handlerName = "")
|
||||
{
|
||||
app().registerHandlerViaRegex(regExp,
|
||||
std::forward<FUNCTION>(function),
|
||||
filtersAndMethods,
|
||||
handlerName);
|
||||
}
|
||||
|
||||
private:
|
||||
class methodRegistrator
|
||||
{
|
||||
|
@ -222,6 +222,21 @@ void HttpAppFrameworkImpl::registerHttpController(
|
||||
httpCtrlsRouterPtr_->addHttpPath(
|
||||
pathPattern, binder, validMethods, filters, handlerName);
|
||||
}
|
||||
|
||||
void HttpAppFrameworkImpl::registerHttpControllerViaRegex(
|
||||
const std::string ®Exp,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
const std::vector<HttpMethod> &validMethods,
|
||||
const std::vector<std::string> &filters,
|
||||
const std::string &handlerName)
|
||||
{
|
||||
assert(!regExp.empty());
|
||||
assert(binder);
|
||||
assert(!running_);
|
||||
httpCtrlsRouterPtr_->addHttpRegex(
|
||||
regExp, binder, validMethods, filters, handlerName);
|
||||
}
|
||||
|
||||
HttpAppFramework &HttpAppFrameworkImpl::setThreadNum(size_t threadNum)
|
||||
{
|
||||
if (threadNum == 0)
|
||||
|
@ -414,6 +414,12 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
||||
const std::vector<HttpMethod> &validMethods = std::vector<HttpMethod>(),
|
||||
const std::vector<std::string> &filters = std::vector<std::string>(),
|
||||
const std::string &handlerName = "") override;
|
||||
virtual void registerHttpControllerViaRegex(
|
||||
const std::string ®Exp,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
const std::vector<HttpMethod> &validMethods,
|
||||
const std::vector<std::string> &filters,
|
||||
const std::string &handlerName) override;
|
||||
void onAsyncRequest(
|
||||
const HttpRequestImplPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback);
|
||||
|
@ -40,15 +40,10 @@ void HttpControllersRouter::doWhenNoHandlerFound(
|
||||
void HttpControllersRouter::init(
|
||||
const std::vector<trantor::EventLoop *> &ioLoops)
|
||||
{
|
||||
std::string regString;
|
||||
for (auto &router : ctrlVector_)
|
||||
{
|
||||
std::regex reg("\\(\\[\\^/\\]\\*\\)");
|
||||
std::string tmp =
|
||||
std::regex_replace(router.pathParameterPattern_, reg, "[^/]*");
|
||||
router.regex_ = std::regex(router.pathParameterPattern_,
|
||||
std::regex_constants::icase);
|
||||
regString.append("(").append(tmp).append(")|");
|
||||
for (auto &binder : router.binders_)
|
||||
{
|
||||
if (binder)
|
||||
@ -58,10 +53,6 @@ void HttpControllersRouter::init(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (regString.length() > 0)
|
||||
regString.resize(regString.length() - 1); // remove the last '|'
|
||||
LOG_TRACE << "regex string:" << regString;
|
||||
ctrlRegex_ = std::regex(regString, std::regex_constants::icase);
|
||||
}
|
||||
|
||||
std::vector<std::tuple<std::string, HttpMethod, std::string>>
|
||||
@ -88,6 +79,66 @@ HttpControllersRouter::getHandlersInfo() const
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void HttpControllersRouter::addHttpRegex(
|
||||
const std::string ®Exp,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
const std::vector<HttpMethod> &validMethods,
|
||||
const std::vector<std::string> &filters,
|
||||
const std::string &handlerName)
|
||||
{
|
||||
auto binderInfo = std::make_shared<CtrlBinder>();
|
||||
binderInfo->filterNames_ = filters;
|
||||
binderInfo->handlerName_ = handlerName;
|
||||
binderInfo->binderPtr_ = binder;
|
||||
drogon::app().getLoop()->queueInLoop([binderInfo]() {
|
||||
// Recreate this with the correct number of threads.
|
||||
binderInfo->responseCache_ = IOThreadStorage<HttpResponsePtr>();
|
||||
});
|
||||
{
|
||||
for (auto &router : ctrlVector_)
|
||||
{
|
||||
if (router.pathParameterPattern_ == regExp)
|
||||
{
|
||||
if (validMethods.size() > 0)
|
||||
{
|
||||
for (auto const &method : validMethods)
|
||||
{
|
||||
router.binders_[method] = binderInfo;
|
||||
if (method == Options)
|
||||
binderInfo->isCORS_ = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
binderInfo->isCORS_ = true;
|
||||
for (int i = 0; i < Invalid; ++i)
|
||||
router.binders_[i] = binderInfo;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
struct HttpControllerRouterItem router;
|
||||
router.pathParameterPattern_ = regExp;
|
||||
router.pathPattern_ = regExp;
|
||||
if (validMethods.size() > 0)
|
||||
{
|
||||
for (auto const &method : validMethods)
|
||||
{
|
||||
router.binders_[method] = binderInfo;
|
||||
if (method == Options)
|
||||
binderInfo->isCORS_ = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
binderInfo->isCORS_ = true;
|
||||
for (int i = 0; i < Invalid; ++i)
|
||||
router.binders_[i] = binderInfo;
|
||||
}
|
||||
ctrlVector_.push_back(std::move(router));
|
||||
}
|
||||
void HttpControllersRouter::addHttpPath(
|
||||
const std::string &path,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
@ -312,7 +363,6 @@ void HttpControllersRouter::addHttpPath(
|
||||
binderInfo->responseCache_ = IOThreadStorage<HttpResponsePtr>();
|
||||
});
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(ctrlMutex_);
|
||||
for (auto &router : ctrlVector_)
|
||||
{
|
||||
if (router.pathParameterPattern_ == pathParameterPattern)
|
||||
@ -354,10 +404,7 @@ void HttpControllersRouter::addHttpPath(
|
||||
for (int i = 0; i < Invalid; ++i)
|
||||
router.binders_[i] = binderInfo;
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(ctrlMutex_);
|
||||
ctrlVector_.push_back(std::move(router));
|
||||
}
|
||||
ctrlVector_.push_back(std::move(router));
|
||||
}
|
||||
|
||||
void HttpControllersRouter::route(
|
||||
@ -365,62 +412,100 @@ void HttpControllersRouter::route(
|
||||
std::function<void(const HttpResponsePtr &)> &&callback)
|
||||
{
|
||||
// Find http controller
|
||||
if (ctrlRegex_.mark_count() > 0)
|
||||
for (auto &routerItem : ctrlVector_)
|
||||
{
|
||||
std::smatch result;
|
||||
if (std::regex_match(req->path(), result, ctrlRegex_))
|
||||
auto const &ctrlRegex = routerItem.regex_;
|
||||
if (std::regex_match(req->path(), result, ctrlRegex))
|
||||
{
|
||||
for (size_t i = 1; i < result.size(); ++i)
|
||||
assert(Invalid > req->method());
|
||||
req->setMatchedPathPattern(routerItem.pathPattern_);
|
||||
auto &binder = routerItem.binders_[req->method()];
|
||||
if (!binder)
|
||||
{
|
||||
// TODO: Is there any better way to find the sub-match index
|
||||
// without using loop?
|
||||
if (!result[i].matched)
|
||||
continue;
|
||||
if (i <= ctrlVector_.size())
|
||||
// Invalid Http Method
|
||||
auto res = drogon::HttpResponse::newHttpResponse();
|
||||
if (req->method() != Options)
|
||||
{
|
||||
size_t ctlIndex = i - 1;
|
||||
auto &routerItem = ctrlVector_[ctlIndex];
|
||||
assert(Invalid > req->method());
|
||||
req->setMatchedPathPattern(routerItem.pathPattern_);
|
||||
auto &binder = routerItem.binders_[req->method()];
|
||||
if (!binder)
|
||||
{
|
||||
// Invalid Http Method
|
||||
auto res = drogon::HttpResponse::newHttpResponse();
|
||||
if (req->method() != Options)
|
||||
{
|
||||
res->setStatusCode(k405MethodNotAllowed);
|
||||
}
|
||||
else
|
||||
{
|
||||
res->setStatusCode(k403Forbidden);
|
||||
}
|
||||
callback(res);
|
||||
return;
|
||||
}
|
||||
if (!postRoutingObservers_.empty())
|
||||
{
|
||||
for (auto &observer : postRoutingObservers_)
|
||||
{
|
||||
observer(req);
|
||||
}
|
||||
}
|
||||
if (postRoutingAdvices_.empty())
|
||||
{
|
||||
res->setStatusCode(k405MethodNotAllowed);
|
||||
}
|
||||
else
|
||||
{
|
||||
res->setStatusCode(k403Forbidden);
|
||||
}
|
||||
callback(res);
|
||||
return;
|
||||
}
|
||||
if (!postRoutingObservers_.empty())
|
||||
{
|
||||
for (auto &observer : postRoutingObservers_)
|
||||
{
|
||||
observer(req);
|
||||
}
|
||||
}
|
||||
if (postRoutingAdvices_.empty())
|
||||
{
|
||||
if (!binder->filters_.empty())
|
||||
{
|
||||
auto &filters = binder->filters_;
|
||||
auto callbackPtr = std::make_shared<
|
||||
std::function<void(const HttpResponsePtr &)>>(
|
||||
std::move(callback));
|
||||
filters_function::doFilters(
|
||||
filters,
|
||||
req,
|
||||
callbackPtr,
|
||||
[=,
|
||||
&binder,
|
||||
&routerItem,
|
||||
result = std::move(result)]() mutable {
|
||||
doPreHandlingAdvices(binder,
|
||||
routerItem,
|
||||
req,
|
||||
std::move(result),
|
||||
std::move(*callbackPtr));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
doPreHandlingAdvices(binder,
|
||||
routerItem,
|
||||
req,
|
||||
std::move(result),
|
||||
std::move(callback));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto callbackPtr = std::make_shared<
|
||||
std::function<void(const HttpResponsePtr &)>>(
|
||||
std::move(callback));
|
||||
doAdvicesChain(
|
||||
postRoutingAdvices_,
|
||||
0,
|
||||
req,
|
||||
callbackPtr,
|
||||
[&binder,
|
||||
callbackPtr,
|
||||
req,
|
||||
this,
|
||||
&routerItem,
|
||||
result = std::move(result)]() mutable {
|
||||
if (!binder->filters_.empty())
|
||||
{
|
||||
auto &filters = binder->filters_;
|
||||
auto callbackPtr = std::make_shared<
|
||||
std::function<void(const HttpResponsePtr &)>>(
|
||||
std::move(callback));
|
||||
filters_function::doFilters(
|
||||
filters,
|
||||
req,
|
||||
callbackPtr,
|
||||
[=, &binder, &routerItem]() {
|
||||
[=,
|
||||
&binder,
|
||||
&routerItem,
|
||||
result = std::move(result)]() mutable {
|
||||
doPreHandlingAdvices(binder,
|
||||
routerItem,
|
||||
req,
|
||||
std::move(result),
|
||||
std::move(
|
||||
*callbackPtr));
|
||||
});
|
||||
@ -430,69 +515,23 @@ void HttpControllersRouter::route(
|
||||
doPreHandlingAdvices(binder,
|
||||
routerItem,
|
||||
req,
|
||||
std::move(callback));
|
||||
std::move(result),
|
||||
std::move(*callbackPtr));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto callbackPtr = std::make_shared<
|
||||
std::function<void(const HttpResponsePtr &)>>(
|
||||
std::move(callback));
|
||||
doAdvicesChain(postRoutingAdvices_,
|
||||
0,
|
||||
req,
|
||||
callbackPtr,
|
||||
[&binder,
|
||||
callbackPtr,
|
||||
req,
|
||||
this,
|
||||
&routerItem]() mutable {
|
||||
if (!binder->filters_.empty())
|
||||
{
|
||||
auto &filters = binder->filters_;
|
||||
filters_function::doFilters(
|
||||
filters,
|
||||
req,
|
||||
callbackPtr,
|
||||
[=, &binder, &routerItem]() {
|
||||
doPreHandlingAdvices(
|
||||
binder,
|
||||
routerItem,
|
||||
req,
|
||||
std::move(
|
||||
*callbackPtr));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
doPreHandlingAdvices(
|
||||
binder,
|
||||
routerItem,
|
||||
req,
|
||||
std::move(*callbackPtr));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No handler found
|
||||
doWhenNoHandlerFound(req, std::move(callback));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No handler found
|
||||
doWhenNoHandlerFound(req, std::move(callback));
|
||||
}
|
||||
// No handler found
|
||||
doWhenNoHandlerFound(req, std::move(callback));
|
||||
}
|
||||
|
||||
void HttpControllersRouter::doControllerHandler(
|
||||
const CtrlBinderPtr &ctrlBinderPtr,
|
||||
const HttpControllerRouterItem &routerItem,
|
||||
const HttpRequestImplPtr &req,
|
||||
const std::smatch &matchResult,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback)
|
||||
{
|
||||
auto &responsePtr = *(ctrlBinderPtr->responseCache_);
|
||||
@ -514,18 +553,22 @@ void HttpControllersRouter::doControllerHandler(
|
||||
}
|
||||
|
||||
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 < matchResult.size(); ++j)
|
||||
{
|
||||
for (size_t j = 1; j < r.size(); ++j)
|
||||
if (!matchResult[j].matched)
|
||||
continue;
|
||||
size_t place = j;
|
||||
if (j <= ctrlBinderPtr->parameterPlaces_.size())
|
||||
{
|
||||
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];
|
||||
place = ctrlBinderPtr->parameterPlaces_[j - 1];
|
||||
}
|
||||
if (place > params.size())
|
||||
params.resize(place);
|
||||
params[place - 1] = matchResult[j].str();
|
||||
LOG_TRACE << "place=" << place << " para:" << params[place - 1];
|
||||
}
|
||||
|
||||
if (ctrlBinderPtr->queryParametersPlaces_.size() > 0)
|
||||
{
|
||||
auto qureyPara = req->getParameters();
|
||||
@ -578,6 +621,7 @@ void HttpControllersRouter::doPreHandlingAdvices(
|
||||
const CtrlBinderPtr &ctrlBinderPtr,
|
||||
const HttpControllerRouterItem &routerItem,
|
||||
const HttpRequestImplPtr &req,
|
||||
std::smatch &&matchResult,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback)
|
||||
{
|
||||
if (req->method() == Options)
|
||||
@ -627,10 +671,8 @@ void HttpControllersRouter::doPreHandlingAdvices(
|
||||
}
|
||||
if (preHandlingAdvices_.empty())
|
||||
{
|
||||
doControllerHandler(ctrlBinderPtr,
|
||||
routerItem,
|
||||
req,
|
||||
std::move(callback));
|
||||
doControllerHandler(
|
||||
ctrlBinderPtr, routerItem, req, matchResult, std::move(callback));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -647,10 +689,16 @@ void HttpControllersRouter::doPreHandlingAdvices(
|
||||
resp,
|
||||
*callbackPtr);
|
||||
}),
|
||||
[this, ctrlBinderPtr, &routerItem, req, callbackPtr]() {
|
||||
[this,
|
||||
ctrlBinderPtr,
|
||||
&routerItem,
|
||||
req,
|
||||
callbackPtr,
|
||||
result = std::move(matchResult)]() {
|
||||
doControllerHandler(ctrlBinderPtr,
|
||||
routerItem,
|
||||
req,
|
||||
result,
|
||||
std::move(*callbackPtr));
|
||||
});
|
||||
}
|
||||
|
@ -64,6 +64,11 @@ class HttpControllersRouter : public trantor::NonCopyable
|
||||
const std::vector<HttpMethod> &validMethods,
|
||||
const std::vector<std::string> &filters,
|
||||
const std::string &handlerName = "");
|
||||
void addHttpRegex(const std::string ®Exp,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
const std::vector<HttpMethod> &validMethods,
|
||||
const std::vector<std::string> &filters,
|
||||
const std::string &handlerName = "");
|
||||
void route(const HttpRequestImplPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback);
|
||||
std::vector<std::tuple<std::string, HttpMethod, std::string>>
|
||||
@ -92,8 +97,6 @@ class HttpControllersRouter : public trantor::NonCopyable
|
||||
nullptr}; // The enum value of Invalid is the http methods number
|
||||
};
|
||||
std::vector<HttpControllerRouterItem> ctrlVector_;
|
||||
std::mutex ctrlMutex_;
|
||||
std::regex ctrlRegex_;
|
||||
|
||||
const std::vector<std::function<void(const HttpRequestPtr &,
|
||||
AdviceCallback &&,
|
||||
@ -115,12 +118,14 @@ class HttpControllersRouter : public trantor::NonCopyable
|
||||
const CtrlBinderPtr &ctrlBinderPtr,
|
||||
const HttpControllerRouterItem &routerItem,
|
||||
const HttpRequestImplPtr &req,
|
||||
std::smatch &&matchResult,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback);
|
||||
|
||||
void doControllerHandler(
|
||||
const CtrlBinderPtr &ctrlBinderPtr,
|
||||
const HttpControllerRouterItem &routerItem,
|
||||
const HttpRequestImplPtr &req,
|
||||
const std::smatch &matchResult,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback);
|
||||
void invokeCallback(
|
||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
||||
|
Loading…
Reference in New Issue
Block a user