mirror of
https://github.com/XRPLF/clio.git
synced 2026-07-26 00:20:34 +00:00
fix: Proxy support (#3103)
Port of two changes onto release/2.7.1: - #3006 (d3381a1d): resolve proxy ip before processing any request - #3043 (d7bcf6e7): re-resolve client ip when a proxy reuses a TCP connection for different clients (resolveClientIp now returns std::optional; extractClientIp made public; isProxyConnection_ tracked)
This commit is contained in:
@@ -43,8 +43,10 @@
|
||||
#include <boost/beast/http/error.hpp>
|
||||
#include <boost/beast/http/field.hpp>
|
||||
#include <boost/beast/http/message.hpp>
|
||||
#include <boost/beast/http/message_fwd.hpp>
|
||||
#include <boost/beast/http/status.hpp>
|
||||
#include <boost/beast/http/string_body.hpp>
|
||||
#include <boost/beast/http/string_body_fwd.hpp>
|
||||
#include <boost/beast/http/verb.hpp>
|
||||
#include <boost/beast/ssl.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
@@ -139,6 +141,7 @@ class HttpBase : public ConnectionBase {
|
||||
SendLambda sender_;
|
||||
std::shared_ptr<AdminVerificationStrategy> adminVerification_;
|
||||
std::shared_ptr<ProxyIpResolver> proxyIpResolver_;
|
||||
bool isProxyConnection_ = false;
|
||||
|
||||
protected:
|
||||
boost::beast::flat_buffer buffer_;
|
||||
@@ -239,6 +242,23 @@ public:
|
||||
if (ec)
|
||||
return httpFail(ec, "read");
|
||||
|
||||
auto const updateClientIp = [&](std::string newIp) {
|
||||
if (newIp == clientIp_)
|
||||
return;
|
||||
LOG(log_.info()) << tag() << "Detected a forwarded request from proxy. Resolved client ip: " << newIp;
|
||||
dosGuard_.get().decrement(clientIp_);
|
||||
clientIp_ = std::move(newIp);
|
||||
dosGuard_.get().increment(clientIp_);
|
||||
};
|
||||
|
||||
if (isProxyConnection_) {
|
||||
if (auto resolvedIp = ProxyIpResolver::extractClientIp(req_); resolvedIp.has_value())
|
||||
updateClientIp(std::move(*resolvedIp));
|
||||
} else if (auto resolvedIp = proxyIpResolver_->resolveClientIp(clientIp_, req_); resolvedIp.has_value()) {
|
||||
updateClientIp(std::move(*resolvedIp));
|
||||
isProxyConnection_ = true;
|
||||
}
|
||||
|
||||
if (req_.method() == http::verb::get and req_.target() == "/health")
|
||||
return sender_(httpResponse(http::status::ok, "text/html", kHEALTH_CHECK_HTML));
|
||||
|
||||
@@ -249,14 +269,6 @@ public:
|
||||
return sender_(httpResponse(http::status::service_unavailable, "text/html", kCACHE_CHECK_NOT_LOADED_HTML));
|
||||
}
|
||||
|
||||
if (auto resolvedIp = proxyIpResolver_->resolveClientIp(clientIp_, req_); resolvedIp != clientIp_) {
|
||||
LOG(log_.info()) << tag() << "Detected a forwarded request from proxy. Proxy ip: " << clientIp_
|
||||
<< ". Resolved client ip: " << resolvedIp;
|
||||
dosGuard_.get().decrement(clientIp_);
|
||||
clientIp_ = std::move(resolvedIp);
|
||||
dosGuard_.get().increment(clientIp_);
|
||||
}
|
||||
|
||||
// Update isAdmin property of the connection
|
||||
ConnectionBase::isAdmin_ = adminVerification_->isAdmin(req_, clientIp_);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user