mirror of
https://github.com/drogonframework/drogon.git
synced 2025-07-18 00:00:46 -04:00
Compare commits
No commits in common. "b37cf6ff97df73b54aa42fb5ca5caa4dbc04df7c" and "e1163234ccef4e16b0907f1fd1ce4f5e9aa12a25" have entirely different histories.
b37cf6ff97
...
e1163234cc
@ -22,35 +22,11 @@ namespace drogon
|
||||
{
|
||||
namespace plugin
|
||||
{
|
||||
/**
|
||||
* @brief The RedirectorHandler is a function object that can be registered to
|
||||
* the Redirector plugin. It is used to redirect requests to proper URLs. Users
|
||||
* can modify the protocol, host and path of the request. If a false value is
|
||||
* returned, the request will be considered as invalid and a 404 response will
|
||||
* be sent to the client.
|
||||
*/
|
||||
using RedirectorHandler =
|
||||
std::function<bool(const drogon::HttpRequestPtr &,
|
||||
std::string &, //"http://" or "https://"
|
||||
std::string &, // host
|
||||
bool &)>; // path changed or not
|
||||
/**
|
||||
* @brief The PathRewriteHandler is a function object that can be registered to
|
||||
* the Redirector plugin. It is used to rewrite the path of the request. The
|
||||
* Redirector plugin will call all registered PathRewriteHandlers in the order
|
||||
* of registration. If one or more handlers return true, the request will be
|
||||
* redirected to the new path.
|
||||
*/
|
||||
using PathRewriteHandler = std::function<bool(const drogon::HttpRequestPtr &)>;
|
||||
|
||||
/**
|
||||
* @brief The ForwardHandler is a function object that can be registered to the
|
||||
* Redirector plugin. It is used to forward the request to next processing steps
|
||||
* in the framework. The Redirector plugin will call all registered
|
||||
* ForwardHandlers in the order of registration. Users can use this handler to
|
||||
* change the request path or any other part of the request.
|
||||
*/
|
||||
using ForwardHandler = std::function<void(const drogon::HttpRequestPtr &)>;
|
||||
|
||||
/**
|
||||
* @brief This plugin is used to redirect requests to proper URLs. It is a
|
||||
@ -80,40 +56,18 @@ class DROGON_EXPORT Redirector : public drogon::Plugin<Redirector>,
|
||||
void initAndStart(const Json::Value &config) override;
|
||||
void shutdown() override;
|
||||
|
||||
void registerRedirectHandler(RedirectorHandler &&handler)
|
||||
void registerHandler(RedirectorHandler &&handler)
|
||||
{
|
||||
handlers_.emplace_back(std::move(handler));
|
||||
}
|
||||
|
||||
void registerRedirectHandler(const RedirectorHandler &handler)
|
||||
void registerHandler(const RedirectorHandler &handler)
|
||||
{
|
||||
handlers_.emplace_back(handler);
|
||||
}
|
||||
|
||||
void registerPathRewriteHandler(PathRewriteHandler &&handler)
|
||||
{
|
||||
pathRewriteHandlers_.emplace_back(std::move(handler));
|
||||
}
|
||||
|
||||
void registerPathRewriteHandler(const PathRewriteHandler &handler)
|
||||
{
|
||||
pathRewriteHandlers_.emplace_back(handler);
|
||||
}
|
||||
|
||||
void registerForwardHandler(ForwardHandler &&handler)
|
||||
{
|
||||
forwardHandlers_.emplace_back(std::move(handler));
|
||||
}
|
||||
|
||||
void registerForwardHandler(const ForwardHandler &handler)
|
||||
{
|
||||
forwardHandlers_.emplace_back(handler);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<RedirectorHandler> handlers_;
|
||||
std::vector<PathRewriteHandler> pathRewriteHandlers_;
|
||||
std::vector<ForwardHandler> forwardHandlers_;
|
||||
};
|
||||
|
||||
} // namespace plugin
|
||||
|
@ -66,10 +66,12 @@ class DROGON_EXPORT SecureSSLRedirector
|
||||
private:
|
||||
bool redirectingAdvice(const HttpRequestPtr &,
|
||||
std::string &,
|
||||
std::string &) const;
|
||||
std::string &,
|
||||
bool &) const;
|
||||
bool redirectToSSL(const HttpRequestPtr &,
|
||||
std::string &,
|
||||
std::string &) const;
|
||||
std::string &,
|
||||
bool &) const;
|
||||
|
||||
std::regex exemptPegex_;
|
||||
bool regexFlag_{false};
|
||||
|
@ -37,10 +37,6 @@ void Redirector::initAndStart(const Json::Value &config)
|
||||
return HttpResponse::newNotFoundResponse();
|
||||
}
|
||||
}
|
||||
for (auto &handler : thisPtr->pathRewriteHandlers_)
|
||||
{
|
||||
pathChanged |= handler(req);
|
||||
}
|
||||
if (!protocol.empty() || !host.empty() || pathChanged)
|
||||
{
|
||||
std::string url;
|
||||
@ -52,6 +48,10 @@ void Redirector::initAndStart(const Json::Value &config)
|
||||
: "http://";
|
||||
url.append(host);
|
||||
}
|
||||
if (pathChanged)
|
||||
{
|
||||
url.append(req->path());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -64,8 +64,11 @@ void Redirector::initAndStart(const Json::Value &config)
|
||||
{
|
||||
url.append(req->getHeader("host"));
|
||||
}
|
||||
if (pathChanged)
|
||||
{
|
||||
url.append(req->path());
|
||||
}
|
||||
}
|
||||
url.append(req->path());
|
||||
auto &query = req->query();
|
||||
if (!query.empty())
|
||||
{
|
||||
@ -73,10 +76,6 @@ void Redirector::initAndStart(const Json::Value &config)
|
||||
}
|
||||
return HttpResponse::newRedirectionResponse(url);
|
||||
}
|
||||
for (auto &handler : thisPtr->forwardHandlers_)
|
||||
{
|
||||
handler(req);
|
||||
}
|
||||
return HttpResponsePtr{};
|
||||
});
|
||||
}
|
||||
|
@ -49,18 +49,17 @@ void SecureSSLRedirector::initAndStart(const Json::Value &config)
|
||||
LOG_ERROR << "Redirector plugin is not found!";
|
||||
return;
|
||||
}
|
||||
redirector->registerRedirectHandler(
|
||||
[weakPtr](const drogon::HttpRequestPtr &req,
|
||||
std::string &protocol,
|
||||
std::string &host,
|
||||
bool &) -> bool {
|
||||
auto thisPtr = weakPtr.lock();
|
||||
if (!thisPtr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return thisPtr->redirectingAdvice(req, protocol, host);
|
||||
});
|
||||
redirector->registerHandler([weakPtr](const drogon::HttpRequestPtr &req,
|
||||
std::string &protocol,
|
||||
std::string &host,
|
||||
bool &pathChanged) -> bool {
|
||||
auto thisPtr = weakPtr.lock();
|
||||
if (!thisPtr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return thisPtr->redirectingAdvice(req, protocol, host, pathChanged);
|
||||
});
|
||||
}
|
||||
|
||||
void SecureSSLRedirector::shutdown()
|
||||
@ -70,7 +69,8 @@ void SecureSSLRedirector::shutdown()
|
||||
|
||||
bool SecureSSLRedirector::redirectingAdvice(const HttpRequestPtr &req,
|
||||
std::string &protocol,
|
||||
std::string &host) const
|
||||
std::string &host,
|
||||
bool &pathChanged) const
|
||||
{
|
||||
if (req->isOnSecureConnection() || protocol == "https://")
|
||||
{
|
||||
@ -85,19 +85,21 @@ bool SecureSSLRedirector::redirectingAdvice(const HttpRequestPtr &req,
|
||||
}
|
||||
else
|
||||
{
|
||||
return redirectToSSL(req, protocol, host);
|
||||
return redirectToSSL(req, protocol, host, pathChanged);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return redirectToSSL(req, protocol, host);
|
||||
return redirectToSSL(req, protocol, host, pathChanged);
|
||||
}
|
||||
}
|
||||
|
||||
bool SecureSSLRedirector::redirectToSSL(const HttpRequestPtr &req,
|
||||
std::string &protocol,
|
||||
std::string &host) const
|
||||
std::string &host,
|
||||
bool &pathChanged) const
|
||||
{
|
||||
(void)pathChanged;
|
||||
if (!secureHost_.empty())
|
||||
{
|
||||
host = secureHost_;
|
||||
|
@ -66,31 +66,6 @@ static inline void removeExcessiveSlashes(string& url)
|
||||
removeDuplicateSlashes(url);
|
||||
}
|
||||
|
||||
static inline bool handleReq(const drogon::HttpRequestPtr& req, int removeMode)
|
||||
{
|
||||
static const std::regex regex(regexes[removeMode - 1]);
|
||||
if (std::regex_match(req->path(), regex))
|
||||
{
|
||||
string newPath = req->path();
|
||||
switch (removeMode)
|
||||
{
|
||||
case trailing:
|
||||
removeTrailingSlashes(newPath);
|
||||
break;
|
||||
case duplicate:
|
||||
removeDuplicateSlashes(newPath);
|
||||
break;
|
||||
case both:
|
||||
default:
|
||||
removeExcessiveSlashes(newPath);
|
||||
break;
|
||||
}
|
||||
req->setPath(std::move(newPath));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SlashRemover::initAndStart(const Json::Value& config)
|
||||
{
|
||||
trailingSlashes_ = config.get("remove_trailing_slashes", true).asBool();
|
||||
@ -106,17 +81,36 @@ void SlashRemover::initAndStart(const Json::Value& config)
|
||||
LOG_ERROR << "Redirector plugin is not found!";
|
||||
return;
|
||||
}
|
||||
auto func = [removeMode](const HttpRequestPtr& req) -> bool {
|
||||
return handleReq(req, removeMode);
|
||||
};
|
||||
if (redirect_)
|
||||
{
|
||||
redirector->registerPathRewriteHandler(std::move(func));
|
||||
}
|
||||
else
|
||||
{
|
||||
redirector->registerForwardHandler(std::move(func));
|
||||
}
|
||||
redirector->registerHandler(
|
||||
[removeMode, redirect = redirect_](const HttpRequestPtr& req,
|
||||
std::string& protocol,
|
||||
std::string& host,
|
||||
bool& pathChanged) -> bool {
|
||||
static const std::regex regex(regexes[removeMode - 1]);
|
||||
if (std::regex_match(req->path(), regex))
|
||||
{
|
||||
string newPath = req->path();
|
||||
switch (removeMode)
|
||||
{
|
||||
case trailing:
|
||||
removeTrailingSlashes(newPath);
|
||||
break;
|
||||
case duplicate:
|
||||
removeDuplicateSlashes(newPath);
|
||||
break;
|
||||
case both:
|
||||
default:
|
||||
removeExcessiveSlashes(newPath);
|
||||
break;
|
||||
}
|
||||
req->setPath(std::move(newPath));
|
||||
if (redirect)
|
||||
{
|
||||
pathChanged = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void SlashRemover::shutdown()
|
||||
|
Loading…
x
Reference in New Issue
Block a user