Modify the HttpController template to be able to specify absolute paths in HttpController

This commit is contained in:
antao 2019-03-31 19:32:16 +08:00
parent e76e49cc7a
commit d216a663aa
3 changed files with 61 additions and 22 deletions

View File

@ -15,7 +15,8 @@ class ApiTest : public drogon::HttpController<ApiTest>
METHOD_ADD(ApiTest::get, "/get/{2}/{1}", Get); //path is /api/v1/apitest/get/{arg2}/{arg1}
METHOD_ADD(ApiTest::your_method_name, "/{1}/List?P2={2}", Get); //path is /api/v1/apitest/{arg1}/list
METHOD_ADD(ApiTest::staticApi, "/static", Get, Post);
METHOD_ADD(ApiTest::get2, "/get/{1}", Get);
METHOD_ADD(ApiTest::get2, "/get/{1}", Get); //path is /api/v1/apitest/get/{arg1}
ADD_METHOD_TO(ApiTest::get2, "/absolute/{1}", Get); //path is /absolute/{arg1}
METHOD_ADD(ApiTest::jsonTest, "/json", Post);
METHOD_ADD(ApiTest::formTest, "/form", Post);
METHOD_LIST_END
@ -28,7 +29,6 @@ class ApiTest : public drogon::HttpController<ApiTest>
void rootPost(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback);
void jsonTest(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback);
void formTest(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback);
public:
ApiTest()
{

View File

@ -533,8 +533,7 @@ void doTest(const HttpClientPtr &client, std::promise<int> &pro, bool isHttps =
}
});
/// Test controllers created and initialized by users
req = HttpRequest::newHttpFormPostRequest();
req->setMethod(drogon::Get);
req = HttpRequest::newHttpRequest();
req->setPath("/customctrl/antao");
req->addHeader("custom_header", "yes");
client->sendRequest(req, [=](ReqResult result, const HttpResponsePtr &resp) {
@ -558,6 +557,29 @@ void doTest(const HttpClientPtr &client, std::promise<int> &pro, bool isHttps =
exit(1);
}
});
/// Test controllers created and initialized by users
req = HttpRequest::newHttpRequest();
req->setPath("/absolute/123");
client->sendRequest(req, [=](ReqResult result, const HttpResponsePtr &resp) {
if (result == ReqResult::Ok)
{
if (resp->statusCode() == k200OK)
{
outputGood(req, isHttps);
}
else
{
LOG_DEBUG << resp->getBody();
LOG_ERROR << "Error!";
exit(1);
}
}
else
{
LOG_ERROR << "Error!";
exit(1);
}
});
/// Test form post
req = HttpRequest::newHttpFormPostRequest();
req->setPath("/api/v1/apitest/form");

View File

@ -27,14 +27,15 @@
static void initPathRouting() \
{
#define METHOD_ADD(method, pattern, filters...) \
{ \
registerMethod(&method, pattern, {filters}); \
}
#define METHOD_ADD(method, pattern, filters...) \
registerMethod(&method, pattern, {filters})
#define ADD_METHOD_TO(method, path_pattern, filters...) \
registerMethod(&method, path_pattern, {filters}, false)
#define METHOD_LIST_END \
return; \
}
}
namespace drogon
{
@ -53,25 +54,41 @@ class HttpController : public DrObject<T>, public HttpControllerBase
template <typename FUNCTION>
static void registerMethod(FUNCTION &&function,
const std::string &pattern,
const std::vector<any> &filtersAndMethods = std::vector<any>())
const std::vector<any> &filtersAndMethods = std::vector<any>(),
bool classNameInPath = true)
{
std::string path = std::string("/") + HttpController<T>::classTypeName();
LOG_TRACE << "classname:" << HttpController<T>::classTypeName();
//transform(path.begin(), path.end(), path.begin(), tolower);
std::string::size_type pos;
while ((pos = path.find("::")) != std::string::npos)
if (classNameInPath)
{
path.replace(pos, 2, "/");
std::string path = "/";
path.append(HttpController<T>::classTypeName());
LOG_TRACE << "classname:" << HttpController<T>::classTypeName();
//transform(path.begin(), path.end(), path.begin(), tolower);
std::string::size_type pos;
while ((pos = path.find("::")) != std::string::npos)
{
path.replace(pos, 2, "/");
}
if (pattern.empty() || pattern[0] == '/')
app().registerHandler(path + pattern,
std::forward<FUNCTION>(function),
filtersAndMethods);
else
app().registerHandler(path + "/" + pattern,
std::forward<FUNCTION>(function),
filtersAndMethods);
}
if (pattern.empty() || pattern[0] == '/')
app().registerHandler(path + pattern,
std::forward<FUNCTION>(function),
filtersAndMethods);
else
app().registerHandler(path + "/" + pattern,
{
std::string path = pattern;
if (path.empty() || path[0] != '/')
{
path = "/" + path;
}
app().registerHandler(path,
std::forward<FUNCTION>(function),
filtersAndMethods);
}
}
private: