mirror of
https://github.com/warp-tech/warpgate.git
synced 2025-10-07 22:07:46 +08:00
Add better support for X-Forward- headers when constructing external url
This commit is contained in:
parent
b0a9130a51
commit
d9af7470a4
2 changed files with 31 additions and 23 deletions
|
@ -141,7 +141,7 @@ pub struct HTTPConfig {
|
||||||
pub key: String,
|
pub key: String,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub trust_x_forwarded_for: bool,
|
pub trust_x_forwarded_headers: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for HTTPConfig {
|
impl Default for HTTPConfig {
|
||||||
|
@ -151,7 +151,7 @@ impl Default for HTTPConfig {
|
||||||
listen: _default_http_listen(),
|
listen: _default_http_listen(),
|
||||||
certificate: "".to_owned(),
|
certificate: "".to_owned(),
|
||||||
key: "".to_owned(),
|
key: "".to_owned(),
|
||||||
trust_x_forwarded_for: false,
|
trust_x_forwarded_headers: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,26 +299,34 @@ impl WarpgateConfig {
|
||||||
&self,
|
&self,
|
||||||
for_request: Option<&poem::Request>,
|
for_request: Option<&poem::Request>,
|
||||||
) -> Result<Url, WarpgateError> {
|
) -> Result<Url, WarpgateError> {
|
||||||
let url = if let Some(value) = for_request.and_then(|x| x.header(http::header::HOST)) {
|
// if trust x-forwarded, get x-forwarded-host, then try Host, then fallback on external_host
|
||||||
let value = value.to_string();
|
// if trust x-forwarded, get x-forwarded-proto, then try request scheme, then fallback https
|
||||||
let mut url = Url::parse(&format!("https://{value}/"))?;
|
// if trust x-forwarded, get x-forwarded-port, then try request port, then fallback http listen port
|
||||||
if let Some(value) = for_request.and_then(|x| x.header("x-forwarded-proto")) {
|
let trust_forwarded_headers = self.store.http.trust_x_forwarded_headers;
|
||||||
let _ = url.set_scheme(value);
|
let (scheme, host, port) = ("https".to_string(), self.store.external_host.clone(), self.store.http.listen.port());
|
||||||
}
|
|
||||||
url
|
let (scheme, host, port) = match for_request {
|
||||||
} else {
|
Some(req) => {
|
||||||
let ext_host = self.store.external_host.as_deref();
|
let scheme = req.uri().scheme().map(|x| x.to_string()).unwrap_or(scheme.clone());
|
||||||
let Some(ext_host) = ext_host else {
|
let host = req.uri().host().map(|x| x.to_string()).or(host);
|
||||||
return Err(WarpgateError::ExternalHostNotSet);
|
let host = req.header(http::header::HOST).map(|x| x.to_string()).or(host);
|
||||||
};
|
let port = req.uri().port_u16().unwrap_or(port);
|
||||||
let mut url = Url::parse(&format!("https://{ext_host}/"))?;
|
match trust_forwarded_headers {
|
||||||
let ext_port = self.store.http.listen.port();
|
true => {
|
||||||
if ext_port != 443 {
|
let scheme = for_request.and_then(|x| x.header("x-forwarded-proto")).map(|x| x.to_string()).unwrap_or(scheme);
|
||||||
let _ = url.set_port(Some(ext_port));
|
let host = for_request.and_then(|x| x.header("x-forwarded-host")).map(|x| x.to_string()).or(host);
|
||||||
}
|
let port = for_request.and_then(|x| x.header("x-forwarded-port")).and_then(|x| x.parse::<u16>().ok()).unwrap_or(port);
|
||||||
url
|
(scheme, host, port)
|
||||||
|
},
|
||||||
|
false =>(scheme, host, port)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => (scheme, host, port),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(url)
|
let Some(host) = host else {
|
||||||
|
return Err(WarpgateError::ExternalHostNotSet);
|
||||||
|
};
|
||||||
|
Url::parse(&format!("{}://{}:{}/", scheme, host, port)).map_err(|e| WarpgateError::UrlParse(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@ pub async fn span_for_request(req: &Request) -> poem::Result<Span> {
|
||||||
.map(|x| x.ip().to_string())
|
.map(|x| x.ip().to_string())
|
||||||
.unwrap_or("<unknown>".into());
|
.unwrap_or("<unknown>".into());
|
||||||
|
|
||||||
let client_ip = match config.store.http.trust_x_forwarded_for {
|
let client_ip = match config.store.http.trust_x_forwarded_headers {
|
||||||
true => req
|
true => req
|
||||||
.header("X-Forwarded-For")
|
.header("x-forwarded-for")
|
||||||
.map(|x| x.to_string())
|
.map(|x| x.to_string())
|
||||||
.unwrap_or(remote_ip),
|
.unwrap_or(remote_ip),
|
||||||
false => remote_ip,
|
false => remote_ip,
|
||||||
|
|
Loading…
Add table
Reference in a new issue