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(
&self,
proxy_client: sync::Arc<service::http::proxy::Client>,
client_ip: net::IpAddr,
req: Request,
req_is_https: bool,
@ -614,6 +615,7 @@ impl Service {
let http_url = config.http_url.as_ref().unwrap();
return service::http::proxy::serve_http_request(
proxy_client.as_ref(),
http_url.original_url.as_str(),
&config.http_request_headers.0,
client_ip,
@ -667,6 +669,7 @@ fn strip_port(host: &str) -> &str {
struct HyperServiceImpl {
service: sync::Arc<Service>,
proxy_client: sync::Arc<service::http::proxy::Client>,
client_ip: net::IpAddr,
is_https: bool,
}
@ -675,6 +678,7 @@ impl HyperServiceImpl {
pub fn new(service: sync::Arc<Service>, client_ip: net::IpAddr, is_https: bool) -> Self {
Self {
service,
proxy_client: service::http::proxy::new_client().into(),
client_ip,
is_https,
}
@ -688,8 +692,13 @@ impl hyper::service::Service<Request> for HyperServiceImpl {
fn call(&self, req: Request) -> Self::Future {
let service = self.service.clone();
let proxy_client = self.proxy_client.clone();
let client_ip = self.client_ip;
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::rt::TokioExecutor;
fn proxy_client() -> &'static ReverseProxy<HttpConnector> {
use std::sync::OnceLock;
static PROXY_CLIENT: OnceLock<ReverseProxy<HttpConnector>> = OnceLock::new();
PROXY_CLIENT.get_or_init(|| {
pub type Client = ReverseProxy<HttpConnector>;
pub fn new_client() -> Client {
ReverseProxy::new(
hyper_util::client::legacy::Builder::new(TokioExecutor::new())
.build::<_, Incoming>(HttpConnector::new()),
)
})
}
pub async fn serve_http_request(
proxy_client: &Client,
proxy_addr: &str,
headers: &http::header::HeaderMap,
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),
// ProxyError doesn't actually implement Error :facepalm: so we have to format the error
// manually