|
|
|
@ -1,6 +1,6 @@ |
|
|
|
|
use crate::error::unexpected::{self, Mappable}; |
|
|
|
|
use crate::{domain, origin}; |
|
|
|
|
use http::header::HeaderValue; |
|
|
|
|
use http::header::{HeaderName, HeaderValue}; |
|
|
|
|
use std::{net, str::FromStr}; |
|
|
|
|
|
|
|
|
|
// proxy is a special case because it is so tied to the underlying protocol that a request is
|
|
|
|
@ -30,33 +30,37 @@ pub async fn serve_http_request( |
|
|
|
|
mut req: hyper::Request<hyper::Body>, |
|
|
|
|
req_is_https: bool, |
|
|
|
|
) -> unexpected::Result<hyper::Response<hyper::Body>> { |
|
|
|
|
let proxy_url = if let origin::Descr::Proxy { ref url } = settings.origin_descr { |
|
|
|
|
url |
|
|
|
|
let (proxy_url, request_http_headers) = if let origin::Descr::Proxy { |
|
|
|
|
ref url, |
|
|
|
|
ref request_http_headers, |
|
|
|
|
} = settings.origin_descr |
|
|
|
|
{ |
|
|
|
|
(url, request_http_headers) |
|
|
|
|
} else { |
|
|
|
|
panic!("non-proxy domain settings passed in: {settings:?}") |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
let parsed_proxy_url = |
|
|
|
|
http::Uri::from_str(proxy_url).or_unexpected_while("parsing proxy url {proxy_url}")?; |
|
|
|
|
|
|
|
|
|
// figure out what the host header should be, based on the host[:port] of the proxy_url
|
|
|
|
|
let host = { |
|
|
|
|
let authority = parsed_proxy_url.authority().or_unexpected_while(format!( |
|
|
|
|
"getting host from proxy url {proxy_url}, there is no host" |
|
|
|
|
))?; |
|
|
|
|
for header in request_http_headers { |
|
|
|
|
let name: HeaderName = header |
|
|
|
|
.name |
|
|
|
|
.as_str() |
|
|
|
|
.try_into() |
|
|
|
|
.map_unexpected_while(|| format!("parsing header name {}", &header.name))?; |
|
|
|
|
|
|
|
|
|
let host_and_port; |
|
|
|
|
let mut host = authority.host(); |
|
|
|
|
if header.value == "" { |
|
|
|
|
req.headers_mut().remove(name); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if let Some(port) = authority.port() { |
|
|
|
|
host_and_port = format!("{host}:{port}"); |
|
|
|
|
host = host_and_port.as_str(); |
|
|
|
|
}; |
|
|
|
|
let value = HeaderValue::from_str(&header.value).map_unexpected_while(|| { |
|
|
|
|
format!( |
|
|
|
|
"parsing {} as value for header {}", |
|
|
|
|
&header.value, &header.name |
|
|
|
|
) |
|
|
|
|
})?; |
|
|
|
|
|
|
|
|
|
HeaderValue::from_str(host).or_unexpected()? |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
req.headers_mut().insert("host", host); |
|
|
|
|
req.headers_mut().insert(name, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if req_is_https { |
|
|
|
|
req.headers_mut() |
|
|
|
|