Make user can use any string as a placeholder's name in routing patterns (#282)
This commit is contained in:
parent
d830c4f057
commit
228bac1cfb
|
@ -18,10 +18,10 @@ class ApiTest : public drogon::HttpController<ApiTest>
|
||||||
"drogon::IntranetIpFilter");
|
"drogon::IntranetIpFilter");
|
||||||
METHOD_ADD(ApiTest::rootPost, "", Post, Options);
|
METHOD_ADD(ApiTest::rootPost, "", Post, Options);
|
||||||
METHOD_ADD(ApiTest::get,
|
METHOD_ADD(ApiTest::get,
|
||||||
"/get/{2}/{1}",
|
"/get/{2:p2}/{1}",
|
||||||
Get); // path is /api/v1/apitest/get/{arg2}/{arg1}
|
Get); // path is /api/v1/apitest/get/{arg2}/{arg1}
|
||||||
METHOD_ADD(ApiTest::your_method_name,
|
METHOD_ADD(ApiTest::your_method_name,
|
||||||
"/{1}/List?P2={2}",
|
"/{PI}/List?P2={}",
|
||||||
Get); // path is /api/v1/apitest/{arg1}/list
|
Get); // path is /api/v1/apitest/{arg1}/list
|
||||||
METHOD_ADD(ApiTest::staticApi, "/static", Get, Options); // CORS
|
METHOD_ADD(ApiTest::staticApi, "/static", Get, Options); // CORS
|
||||||
METHOD_ADD(ApiTest::staticApi, "/static", Post, Put, Delete);
|
METHOD_ADD(ApiTest::staticApi, "/static", Post, Put, Delete);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "StaticFileRouter.h"
|
#include "StaticFileRouter.h"
|
||||||
#include "HttpAppFrameworkImpl.h"
|
#include "HttpAppFrameworkImpl.h"
|
||||||
#include "FiltersFunction.h"
|
#include "FiltersFunction.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace drogon;
|
using namespace drogon;
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ void HttpControllersRouter::addHttpPath(
|
||||||
std::vector<size_t> places;
|
std::vector<size_t> places;
|
||||||
std::string tmpPath = path;
|
std::string tmpPath = path;
|
||||||
std::string paras = "";
|
std::string paras = "";
|
||||||
std::regex regex = std::regex("\\{([0-9]+)\\}");
|
std::regex regex = std::regex("\\{([^/]*)\\}");
|
||||||
std::smatch results;
|
std::smatch results;
|
||||||
auto pos = tmpPath.find('?');
|
auto pos = tmpPath.find('?');
|
||||||
if (pos != std::string::npos)
|
if (pos != std::string::npos)
|
||||||
|
@ -107,40 +108,194 @@ void HttpControllersRouter::addHttpPath(
|
||||||
tmpPath = tmpPath.substr(0, pos);
|
tmpPath = tmpPath.substr(0, pos);
|
||||||
}
|
}
|
||||||
std::string originPath = tmpPath;
|
std::string originPath = tmpPath;
|
||||||
|
size_t placeIndex = 1;
|
||||||
while (std::regex_search(tmpPath, results, regex))
|
while (std::regex_search(tmpPath, results, regex))
|
||||||
{
|
{
|
||||||
if (results.size() > 1)
|
if (results.size() > 1)
|
||||||
{
|
{
|
||||||
size_t place = (size_t)std::stoi(results[1].str());
|
auto result = results[1].str();
|
||||||
|
if (!result.empty() &&
|
||||||
|
std::all_of(result.begin(), result.end(), [](const char c) {
|
||||||
|
return std::isdigit(c);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
size_t place = (size_t)std::stoi(result);
|
||||||
if (place > binder->paramCount() || place == 0)
|
if (place > binder->paramCount() || place == 0)
|
||||||
{
|
{
|
||||||
LOG_ERROR << "parameter placeholder(value=" << place
|
LOG_ERROR << "Parameter placeholder(value=" << place
|
||||||
<< ") out of range (1 to " << binder->paramCount()
|
<< ") out of range (1 to " << binder->paramCount()
|
||||||
<< ")";
|
<< ")";
|
||||||
exit(0);
|
LOG_ERROR << "Path pattern: " << path;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!std::all_of(places.begin(),
|
||||||
|
places.end(),
|
||||||
|
[place](size_t i) { return i != place; }))
|
||||||
|
{
|
||||||
|
LOG_ERROR << "Parameter placeholders are duplicated: index="
|
||||||
|
<< place;
|
||||||
|
LOG_ERROR << "Path pattern: " << path;
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
places.push_back(place);
|
places.push_back(place);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::regex regNumberAndName("([0-9]+):.*");
|
||||||
|
std::smatch regexResult;
|
||||||
|
if (std::regex_match(result, regexResult, regNumberAndName))
|
||||||
|
{
|
||||||
|
assert(regexResult.size() == 2 && regexResult[1].matched);
|
||||||
|
auto num = regexResult[1].str();
|
||||||
|
size_t place = (size_t)std::stoi(num);
|
||||||
|
if (place > binder->paramCount() || place == 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR << "Parameter placeholder(value=" << place
|
||||||
|
<< ") out of range (1 to "
|
||||||
|
<< binder->paramCount() << ")";
|
||||||
|
LOG_ERROR << "Path pattern: " << path;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!std::all_of(places.begin(),
|
||||||
|
places.end(),
|
||||||
|
[place](size_t i) { return i != place; }))
|
||||||
|
{
|
||||||
|
LOG_ERROR
|
||||||
|
<< "Parameter placeholders are duplicated: index="
|
||||||
|
<< place;
|
||||||
|
LOG_ERROR << "Path pattern: " << path;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
places.push_back(place);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!std::all_of(places.begin(),
|
||||||
|
places.end(),
|
||||||
|
[placeIndex](size_t i) {
|
||||||
|
return i != placeIndex;
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
LOG_ERROR
|
||||||
|
<< "Parameter placeholders are duplicated: index="
|
||||||
|
<< placeIndex;
|
||||||
|
LOG_ERROR << "Path pattern: " << path;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
places.push_back(placeIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++placeIndex;
|
||||||
|
}
|
||||||
tmpPath = results.suffix();
|
tmpPath = results.suffix();
|
||||||
}
|
}
|
||||||
std::map<std::string, size_t> parametersPlaces;
|
std::map<std::string, size_t> parametersPlaces;
|
||||||
if (!paras.empty())
|
if (!paras.empty())
|
||||||
{
|
{
|
||||||
std::regex pregex("([^&]*)=\\{([0-9]+)\\}&*");
|
std::regex pregex("([^&]*)=\\{([^&]*)\\}&*");
|
||||||
while (std::regex_search(paras, results, pregex))
|
while (std::regex_search(paras, results, pregex))
|
||||||
{
|
{
|
||||||
if (results.size() > 2)
|
if (results.size() > 2)
|
||||||
{
|
{
|
||||||
size_t place = (size_t)std::stoi(results[2].str());
|
auto result = results[2].str();
|
||||||
|
if (!result.empty() &&
|
||||||
|
std::all_of(result.begin(), result.end(), [](const char c) {
|
||||||
|
return std::isdigit(c);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
size_t place = (size_t)std::stoi(result);
|
||||||
if (place > binder->paramCount() || place == 0)
|
if (place > binder->paramCount() || place == 0)
|
||||||
{
|
{
|
||||||
LOG_ERROR << "parameter placeholder(value=" << place
|
LOG_ERROR << "Parameter placeholder(value=" << place
|
||||||
<< ") out of range (1 to " << binder->paramCount()
|
<< ") out of range (1 to "
|
||||||
<< ")";
|
<< binder->paramCount() << ")";
|
||||||
exit(0);
|
LOG_ERROR << "Path pattern: " << path;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!std::all_of(places.begin(),
|
||||||
|
places.end(),
|
||||||
|
[place](size_t i) {
|
||||||
|
return i != place;
|
||||||
|
}) ||
|
||||||
|
!all_of(parametersPlaces.begin(),
|
||||||
|
parametersPlaces.end(),
|
||||||
|
[place](const std::pair<std::string, size_t>
|
||||||
|
&item) {
|
||||||
|
return item.second != place;
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
LOG_ERROR << "Parameter placeholders are "
|
||||||
|
"duplicated: index="
|
||||||
|
<< place;
|
||||||
|
LOG_ERROR << "Path pattern: " << path;
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
parametersPlaces[results[1].str()] = place;
|
parametersPlaces[results[1].str()] = place;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::regex regNumberAndName("([0-9]+):.*");
|
||||||
|
std::smatch regexResult;
|
||||||
|
if (std::regex_match(result, regexResult, regNumberAndName))
|
||||||
|
{
|
||||||
|
assert(regexResult.size() == 2 &&
|
||||||
|
regexResult[1].matched);
|
||||||
|
auto num = regexResult[1].str();
|
||||||
|
size_t place = (size_t)std::stoi(num);
|
||||||
|
if (place > binder->paramCount() || place == 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR << "Parameter placeholder(value=" << place
|
||||||
|
<< ") out of range (1 to "
|
||||||
|
<< binder->paramCount() << ")";
|
||||||
|
LOG_ERROR << "Path pattern: " << path;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!std::all_of(places.begin(),
|
||||||
|
places.end(),
|
||||||
|
[place](size_t i) {
|
||||||
|
return i != place;
|
||||||
|
}) ||
|
||||||
|
!all_of(parametersPlaces.begin(),
|
||||||
|
parametersPlaces.end(),
|
||||||
|
[place](const std::pair<std::string, size_t>
|
||||||
|
&item) {
|
||||||
|
return item.second != place;
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
LOG_ERROR << "Parameter placeholders are "
|
||||||
|
"duplicated: index="
|
||||||
|
<< place;
|
||||||
|
LOG_ERROR << "Path pattern: " << path;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
parametersPlaces[results[1].str()] = place;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!std::all_of(places.begin(),
|
||||||
|
places.end(),
|
||||||
|
[placeIndex](size_t i) {
|
||||||
|
return i != placeIndex;
|
||||||
|
}) ||
|
||||||
|
!all_of(parametersPlaces.begin(),
|
||||||
|
parametersPlaces.end(),
|
||||||
|
[placeIndex](
|
||||||
|
const std::pair<std::string, size_t>
|
||||||
|
&item) {
|
||||||
|
return item.second != placeIndex;
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
LOG_ERROR << "Parameter placeholders are "
|
||||||
|
"duplicated: index="
|
||||||
|
<< placeIndex;
|
||||||
|
LOG_ERROR << "Path pattern: " << path;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
parametersPlaces[results[1].str()] = placeIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++placeIndex;
|
||||||
|
}
|
||||||
paras = results.suffix();
|
paras = results.suffix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue