create reverse proxy client on a per-http handler basis

This commit is contained in:
Brian Picciano 2024-03-02 17:49:24 +01:00
parent e73a120655
commit 56796e91b8
2 changed files with 19 additions and 11 deletions

View File

@ -548,6 +548,7 @@ impl Service {
async fn handle_request( async fn handle_request(
&self, &self,
proxy_client: sync::Arc<service::http::proxy::Client>,
client_ip: net::IpAddr, client_ip: net::IpAddr,
req: Request, req: Request,
req_is_https: bool, req_is_https: bool,
@ -614,6 +615,7 @@ impl Service {
let http_url = config.http_url.as_ref().unwrap(); let http_url = config.http_url.as_ref().unwrap();
return service::http::proxy::serve_http_request( return service::http::proxy::serve_http_request(
proxy_client.as_ref(),
http_url.original_url.as_str(), http_url.original_url.as_str(),
&config.http_request_headers.0, &config.http_request_headers.0,
client_ip, client_ip,
@ -667,6 +669,7 @@ fn strip_port(host: &str) -> &str {
struct HyperServiceImpl { struct HyperServiceImpl {
service: sync::Arc<Service>, service: sync::Arc<Service>,
proxy_client: sync::Arc<service::http::proxy::Client>,
client_ip: net::IpAddr, client_ip: net::IpAddr,
is_https: bool, is_https: bool,
} }
@ -675,6 +678,7 @@ impl HyperServiceImpl {
pub fn new(service: sync::Arc<Service>, client_ip: net::IpAddr, is_https: bool) -> Self { pub fn new(service: sync::Arc<Service>, client_ip: net::IpAddr, is_https: bool) -> Self {
Self { Self {
service, service,
proxy_client: service::http::proxy::new_client().into(),
client_ip, client_ip,
is_https, is_https,
} }
@ -688,8 +692,13 @@ impl hyper::service::Service<Request> for HyperServiceImpl {
fn call(&self, req: Request) -> Self::Future { fn call(&self, req: Request) -> Self::Future {
let service = self.service.clone(); let service = self.service.clone();
let proxy_client = self.proxy_client.clone();
let client_ip = self.client_ip; let client_ip = self.client_ip;
let is_https = self.is_https; let is_https = self.is_https;
Box::pin(async move { Ok(service.handle_request(client_ip, req, is_https).await) }) Box::pin(async move {
Ok(service
.handle_request(proxy_client, client_ip, req, is_https)
.await)
})
} }
} }

View File

@ -6,18 +6,17 @@ use hyper_reverse_proxy::ReverseProxy;
use hyper_util::client::legacy::connect::HttpConnector; use hyper_util::client::legacy::connect::HttpConnector;
use hyper_util::rt::TokioExecutor; use hyper_util::rt::TokioExecutor;
fn proxy_client() -> &'static ReverseProxy<HttpConnector> { pub type Client = ReverseProxy<HttpConnector>;
use std::sync::OnceLock;
static PROXY_CLIENT: OnceLock<ReverseProxy<HttpConnector>> = OnceLock::new(); pub fn new_client() -> Client {
PROXY_CLIENT.get_or_init(|| { ReverseProxy::new(
ReverseProxy::new( hyper_util::client::legacy::Builder::new(TokioExecutor::new())
hyper_util::client::legacy::Builder::new(TokioExecutor::new()) .build::<_, Incoming>(HttpConnector::new()),
.build::<_, Incoming>(HttpConnector::new()), )
)
})
} }
pub async fn serve_http_request( pub async fn serve_http_request(
proxy_client: &Client,
proxy_addr: &str, proxy_addr: &str,
headers: &http::header::HeaderMap, headers: &http::header::HeaderMap,
client_ip: net::IpAddr, client_ip: net::IpAddr,
@ -40,7 +39,7 @@ pub async fn serve_http_request(
); );
} }
match proxy_client().call(client_ip, proxy_addr, req).await { match proxy_client.call(client_ip, proxy_addr, req).await {
Ok(res) => Ok(res), Ok(res) => Ok(res),
// ProxyError doesn't actually implement Error :facepalm: so we have to format the error // ProxyError doesn't actually implement Error :facepalm: so we have to format the error
// manually // manually