Skip to content

Commit

Permalink
Initial commit for HostRedirector
Browse files Browse the repository at this point in the history
  • Loading branch information
Mis1eader-dev committed Sep 26, 2023
1 parent fd7af81 commit f736cc0
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ set(DROGON_SOURCES
lib/src/Redirector.cc
lib/src/SessionManager.cc
lib/src/SlashRemover.cc
lib/src/HostRedirector.cc
lib/src/SlidingWindowRateLimiter.cc
lib/src/StaticFileRouter.cc
lib/src/TaskTimeoutFlag.cc
Expand Down Expand Up @@ -717,6 +718,7 @@ set(DROGON_PLUGIN_HEADERS
lib/inc/drogon/plugins/RealIpResolver.h
lib/inc/drogon/plugins/Hodor.h
lib/inc/drogon/plugins/SlashRemover.h
lib/inc/drogon/plugins/HostRedirector.h
lib/inc/drogon/plugins/GlobalFilters.h
lib/inc/drogon/plugins/PromExporter.h)

Expand Down
74 changes: 74 additions & 0 deletions lib/inc/drogon/plugins/HostRedirector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* @file HostRedirector.h
* @author Mis1eader
*
* Copyright 2023, Mis1eader. All rights reserved.
* https://github.com/an-tao/drogon
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* Drogon
*
*/

#pragma once

#include "drogon/plugins/Plugin.h"
#include "drogon/utils/FunctionTraits.h"
#include <json/value.h>
#include <memory>
#include <unordered_map>

namespace drogon::plugin
{
/**
* @brief The HostRedirector plugin redirects requests with respect to rules.
* The json configuration is as follows:
*
* @code
{
"name": "drogon::plugin::HostRedirector",
"dependencies": ["drogon::plugin::Redirector"],
"config": {
"rules": {
"www.example.com": [
"10.10.10.1",
"example.com",
"search.example.com",
"ww.example.com"
],
"images.example.com": [
"image.example.com"
],
"www.example.com/maps": [
"map.example.com",
"maps.example.com"
]
}
}
}
@endcode
*
* Enable the plugin by adding the configuration to the list of plugins in the
* configuration file.
* */
class DROGON_EXPORT HostRedirector
: public drogon::Plugin<HostRedirector>,
public std::enable_shared_from_this<HostRedirector>
{
public:
HostRedirector()
{
}

void initAndStart(const Json::Value &config) override;
void shutdown() override;

private:
bool redirectingAdvice(const drogon::HttpRequestPtr &,
std::string &,
bool &);

std::unordered_map<std::string, std::string> rules_;
};
} // namespace drogon::plugin
75 changes: 75 additions & 0 deletions lib/src/HostRedirector.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <drogon/plugins/HostRedirector.h>
#include <drogon/plugins/Redirector.h>
#include <drogon/HttpAppFramework.h>
#include "drogon/utils/FunctionTraits.h"
#include <functional>
#include <memory>
#include <string>
#include <string_view>

using namespace drogon;
using namespace drogon::plugin;
using std::string;
using std::string_view;

bool HostRedirector::redirectingAdvice(const HttpRequestPtr& req,
string& host,
bool& pathChanged)
{
const string& reqHost = host.empty() ? req->getHeader("host") : host;
auto find = rules_.find(reqHost);
if (find != rules_.end())
host = find->second;

// TODO: some may need to change the path as well

return true;
}

void HostRedirector::initAndStart(const Json::Value& config)
{
if (config.isMember("rules"))
{
const auto& rules = config["rules"];
if (rules.isObject())
{
for (const auto& redirectTo : rules)
{
if (!redirectTo.isString())
continue;

const string redirectToStr = redirectTo.asString();
for (const auto& redirectFrom : rules[redirectToStr])
{
if (!redirectFrom.isString())
continue;

rules_[redirectFrom.asString()] = redirectToStr;
}
}
}
}
std::weak_ptr<HostRedirector> weakPtr = shared_from_this();
auto redirector = app().getPlugin<Redirector>();
if (!redirector)
{
LOG_ERROR << "Redirector plugin is not found!";
return;
}
redirector->registerRedirectHandler([weakPtr](const HttpRequestPtr& req,
string&,
string& host,
bool& pathChanged) -> bool {
auto thisPtr = weakPtr.lock();
if (!thisPtr)
{
return false;
}
return thisPtr->redirectingAdvice(req, host, pathChanged);
});
}

void HostRedirector::shutdown()
{
LOG_TRACE << "HostRedirector plugin is shutdown!";
}
3 changes: 1 addition & 2 deletions lib/src/SlashRemover.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,7 @@ static inline void removeExcessiveSlashes(string& url,
removeDuplicateSlashes(url, start.second);
}

static inline bool handleReq(const drogon::HttpRequestPtr& req,
uint8_t removeMode)
static inline bool handleReq(const HttpRequestPtr& req, uint8_t removeMode)
{
switch (removeMode)
{
Expand Down

0 comments on commit f736cc0

Please sign in to comment.