config/handler: add host -> dest mappings
This commit is contained in:
@@ -12,6 +12,22 @@
|
|||||||
// this address should be local (127.0.0.1). Other configurations are not supported.
|
// this address should be local (127.0.0.1). Other configurations are not supported.
|
||||||
"forward_address": "127.0.0.1:3000",
|
"forward_address": "127.0.0.1:3000",
|
||||||
|
|
||||||
|
// if you want to separate domains, you can set up proxy rules for Host -> dest
|
||||||
|
// if none match, forward_address will be used.
|
||||||
|
"proxy_rules": [
|
||||||
|
{
|
||||||
|
// If there is a port specified, it will have to match.
|
||||||
|
// If there is no port specified, it's any port.
|
||||||
|
"host": "myepic.domain.com:80",
|
||||||
|
"destination": "127.0.0.1:8080"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Anything to myepic.domain.com that isn't myepic.domain.com:80 goes to 127.0.0.1:8081
|
||||||
|
"host": "myepic.domain.com",
|
||||||
|
"destination": "127.0.0.1:8081"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
// max request size of 10MB
|
// max request size of 10MB
|
||||||
"max_request_size": 10000000,
|
"max_request_size": 10000000,
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ class CConfig {
|
|||||||
std::string resource = "";
|
std::string resource = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SProxyRule {
|
||||||
|
std::string host = "";
|
||||||
|
std::string destination = "";
|
||||||
|
};
|
||||||
|
|
||||||
struct SConfig {
|
struct SConfig {
|
||||||
int port = 3001;
|
int port = 3001;
|
||||||
std::string forward_address = "127.0.0.1:3000";
|
std::string forward_address = "127.0.0.1:3000";
|
||||||
@@ -31,6 +36,7 @@ class CConfig {
|
|||||||
std::vector<SConfigRule> rules = {};
|
std::vector<SConfigRule> rules = {};
|
||||||
int default_challenge_difficulty = 4;
|
int default_challenge_difficulty = 4;
|
||||||
bool async_proxy = true;
|
bool async_proxy = true;
|
||||||
|
std::vector<SProxyRule> proxy_rules;
|
||||||
} m_config;
|
} m_config;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -204,12 +204,9 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt
|
|||||||
if (g_pConfig->m_config.git_host) {
|
if (g_pConfig->m_config.git_host) {
|
||||||
// TODO: ratelimit this, probably.
|
// TODO: ratelimit this, probably.
|
||||||
|
|
||||||
const auto RES = req.resource();
|
const auto RES = req.resource();
|
||||||
bool validGitResource =
|
bool validGitResource = RES.ends_with("/info/refs") || RES.ends_with("/info/packs") || RES.ends_with("HEAD") || RES.ends_with(".git") ||
|
||||||
RES.ends_with("/info/refs") || RES.ends_with("/info/packs") ||
|
RES.ends_with("/git-upload-pack") || RES.ends_with("/git-receive-pack");
|
||||||
RES.ends_with("HEAD") || RES.ends_with(".git") ||
|
|
||||||
RES.ends_with("/git-upload-pack") ||
|
|
||||||
RES.ends_with("/git-receive-pack");
|
|
||||||
|
|
||||||
if (RES.contains("/objects/")) {
|
if (RES.contains("/objects/")) {
|
||||||
const std::string_view repo = std::string_view{RES}.substr(0, RES.find("/objects/"));
|
const std::string_view repo = std::string_view{RES}.substr(0, RES.find("/objects/"));
|
||||||
@@ -253,8 +250,7 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt
|
|||||||
Debug::log(LOG, " | Action: CHALLENGE (rule)");
|
Debug::log(LOG, " | Action: CHALLENGE (rule)");
|
||||||
challengeDifficulty = ic.difficulty.value_or(g_pConfig->m_config.default_challenge_difficulty);
|
challengeDifficulty = ic.difficulty.value_or(g_pConfig->m_config.default_challenge_difficulty);
|
||||||
break;
|
break;
|
||||||
default:
|
default: Debug::log(LOG, " | Invalid rule found (no action) skipping");
|
||||||
Debug::log(LOG, " | Invalid rule found (no action) skipping");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ic.action == IP_ACTION_CHALLENGE)
|
if (ic.action == IP_ACTION_CHALLENGE)
|
||||||
@@ -369,9 +365,9 @@ void CServerHandler::serveStop(const Pistache::Http::Request& req, Pistache::Htt
|
|||||||
const auto NONCE = generateNonce();
|
const auto NONCE = generateNonce();
|
||||||
const auto CHALLENGE = CChallenge(fingerprintForRequest(req), NONCE, difficulty);
|
const auto CHALLENGE = CChallenge(fingerprintForRequest(req), NONCE, difficulty);
|
||||||
|
|
||||||
auto hostDomain = req.headers().getRaw("Host").value();
|
auto hostDomain = req.headers().getRaw("Host").value();
|
||||||
if (hostDomain.contains(":"))
|
if (hostDomain.contains(":"))
|
||||||
hostDomain = hostDomain.substr(0, hostDomain.find(':'));
|
hostDomain = hostDomain.substr(0, hostDomain.find(':'));
|
||||||
|
|
||||||
page.add("challengeDifficulty", CTinylatesProp(std::to_string(difficulty)));
|
page.add("challengeDifficulty", CTinylatesProp(std::to_string(difficulty)));
|
||||||
page.add("challengeNonce", CTinylatesProp(NONCE));
|
page.add("challengeNonce", CTinylatesProp(NONCE));
|
||||||
@@ -417,14 +413,27 @@ void CServerHandler::proxyPassAsync(const Pistache::Http::Request& req, Pistache
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CServerHandler::proxyPassInternal(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response, bool async) {
|
void CServerHandler::proxyPassInternal(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response, bool async) {
|
||||||
const std::string FORWARD_ADDR = g_pConfig->m_config.forward_address;
|
std::string forwardAddress = g_pConfig->m_config.forward_address;
|
||||||
|
const auto HOST = Pistache::Http::Header::header_cast<Pistache::Http::Header::Host>(req.headers().get("Host"));
|
||||||
|
|
||||||
Debug::log(TRACE, "Method ({}): Forwarding to {}", (uint32_t)req.method(), FORWARD_ADDR + req.resource());
|
for (const auto& R : g_pConfig->m_config.proxy_rules) {
|
||||||
|
if (R.host.contains(":")) {
|
||||||
|
if (R.host == HOST->host() + ":" + std::to_string(HOST->port())) {
|
||||||
|
forwardAddress = R.destination;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (HOST->host() == R.host) {
|
||||||
|
forwardAddress = R.destination;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(TRACE, "Method ({}): Forwarding to {}", (uint32_t)req.method(), forwardAddress + req.resource());
|
||||||
|
|
||||||
Pistache::Http::Experimental::Client client;
|
Pistache::Http::Experimental::Client client;
|
||||||
client.init(Pistache::Http::Experimental::Client::options().maxConnectionsPerHost(32).maxResponseSize(g_pConfig->m_config.max_request_size).threads(4));
|
client.init(Pistache::Http::Experimental::Client::options().maxConnectionsPerHost(32).maxResponseSize(g_pConfig->m_config.max_request_size).threads(4));
|
||||||
|
|
||||||
auto builder = client.prepareRequest(FORWARD_ADDR + req.resource(), req.method());
|
auto builder = client.prepareRequest(forwardAddress + req.resource(), req.method());
|
||||||
builder.body(req.body());
|
builder.body(req.body());
|
||||||
for (auto it = req.cookies().begin(); it != req.cookies().end(); ++it) {
|
for (auto it = req.cookies().begin(); it != req.cookies().end(); ++it) {
|
||||||
builder.cookie(*it);
|
builder.cookie(*it);
|
||||||
|
|||||||
Reference in New Issue
Block a user