Skip to content

Commit 6025dd5

Browse files
committed
add x-forwarded-host header
1 parent 1f924d6 commit 6025dd5

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

src/lib.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ lazy_static! {
140140
];
141141

142142
static ref X_FORWARDED_FOR: HeaderName = HeaderName::from_static("x-forwarded-for");
143+
static ref X_FORWARDED_HOST: HeaderName = HeaderName::from_static("x-forwarded-host");
143144
}
144145

145146
#[derive(Debug)]
@@ -334,7 +335,7 @@ fn create_proxied_request<B>(
334335
debug!("Setting headers of proxied request");
335336

336337
// remove the original HOST header. It will be set by the client that sends the request
337-
request.headers_mut().remove(HOST);
338+
let original_host = request.headers_mut().remove(HOST);
338339

339340
*request.uri_mut() = uri;
340341

@@ -361,22 +362,27 @@ fn create_proxied_request<B>(
361362
}
362363

363364
// Add forwarding information in the headers
365+
let forwarded_for_value = client_ip.to_string().parse()?;
364366
match request.headers_mut().entry(&*X_FORWARDED_FOR) {
365367
hyper::header::Entry::Vacant(entry) => {
366-
debug!("X-Fowraded-for header was vacant");
367-
entry.insert(client_ip.to_string().parse()?);
368+
debug!("x-forwarded-for header was vacant");
369+
entry.insert(forwarded_for_value);
368370
}
371+
hyper::header::Entry::Occupied(mut entry) => {
372+
debug!("x-forwarded-for header was occupied");
373+
entry.append(forwarded_for_value);
374+
}
375+
}
369376

370-
hyper::header::Entry::Occupied(entry) => {
371-
debug!("X-Fowraded-for header was occupied");
372-
let client_ip_str = client_ip.to_string();
373-
let mut addr =
374-
String::with_capacity(entry.get().as_bytes().len() + 2 + client_ip_str.len());
375-
376-
addr.push_str(std::str::from_utf8(entry.get().as_bytes()).unwrap());
377-
addr.push(',');
378-
addr.push(' ');
379-
addr.push_str(&client_ip_str);
377+
if let Some(host) = original_host {
378+
match request.headers_mut().entry(&*X_FORWARDED_HOST) {
379+
hyper::header::Entry::Vacant(entry) => {
380+
debug!("x-forwarded-host header was vacant");
381+
entry.insert(host.to_owned());
382+
}
383+
hyper::header::Entry::Occupied(mut _entry) => {
384+
debug!("x-forwarded-host header was occupied");
385+
}
380386
}
381387
}
382388

tests/test_http.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,27 @@ async fn test_get(ctx: &mut ProxyTestContext) {
9090
HOST,
9191
format!("127.0.0.1:{}", ctx.http_back.port).parse().unwrap(),
9292
);
93+
94+
ctx.http_back.add(
95+
HandlerBuilder::new("/foo")
96+
.status_code(StatusCode::OK)
97+
.headers(headers)
98+
.build(),
99+
);
100+
let resp = Client::new().get(ctx.uri("/foo")).await.unwrap();
101+
assert_eq!(200, resp.status());
102+
}
103+
104+
#[test_context(ProxyTestContext)]
105+
#[tokio::test]
106+
async fn test_headers(ctx: &mut ProxyTestContext) {
107+
let mut headers = HeaderMap::new();
108+
headers.insert("x-forwarded-for", "127.0.0.1".parse().unwrap());
109+
headers.insert(
110+
"x-forwarded-host",
111+
format!("localhost:{}", ctx.port).parse().unwrap(),
112+
);
113+
93114
ctx.http_back.add(
94115
HandlerBuilder::new("/foo")
95116
.status_code(StatusCode::OK)

0 commit comments

Comments
 (0)