From fb5779fe8f4399ed3dc759a709bfbc420d81ea54 Mon Sep 17 00:00:00 2001 From: Sven-Hendrik Haase Date: Wed, 9 Oct 2019 00:56:55 +0200 Subject: [PATCH 1/2] Always send body whole and don't use transfer encoding Without doing this, body size would be unknown at the time of sending, causing awc to use transfer encoding which is probably unexpected in most cases. This change makes behavior more obvious. --- http-proxy/src/main.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/http-proxy/src/main.rs b/http-proxy/src/main.rs index a68b46f1..de05dbe8 100644 --- a/http-proxy/src/main.rs +++ b/http-proxy/src/main.rs @@ -7,7 +7,7 @@ use url::Url; fn forward( req: HttpRequest, - payload: web::Payload, + body: web::Bytes, url: web::Data, client: web::Data, ) -> impl Future { @@ -25,14 +25,16 @@ fn forward( }; forwarded_req - .send_stream(payload) + .send_body(body) .map_err(Error::from) .map(|res| { let mut client_resp = HttpResponse::build(res.status()); + // Remove `Connection` as per + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection#Directives for (header_name, header_value) in res .headers() .iter() - .filter(|(h, _)| *h != "connection" && *h != "content-length") + .filter(|(h, _)| *h != "connection") { client_resp.header(header_name.clone(), header_value.clone()); } From 7ff7accd79df8a5c41e0287be4f6efb37d59e12b Mon Sep 17 00:00:00 2001 From: Sven-Hendrik Haase Date: Fri, 15 Nov 2019 19:47:18 +0100 Subject: [PATCH 2/2] Don't stream body but wait for it to complete and only send it then --- http-proxy/src/main.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/http-proxy/src/main.rs b/http-proxy/src/main.rs index de05dbe8..51f44408 100644 --- a/http-proxy/src/main.rs +++ b/http-proxy/src/main.rs @@ -1,6 +1,7 @@ use actix_web::client::Client; use actix_web::{middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer}; use clap::{value_t, Arg}; +use futures::stream::Stream; use futures::Future; use std::net::ToSocketAddrs; use url::Url; @@ -15,6 +16,8 @@ fn forward( new_url.set_path(req.uri().path()); new_url.set_query(req.uri().query()); + // TODO: This forwarded implementation is incomplete as it only handles the inofficial + // X-Forwarded-For header but not the official Forwarded one. let forwarded_req = client .request_from(new_url.as_str(), req.head()) .no_decompress(); @@ -27,19 +30,22 @@ fn forward( forwarded_req .send_body(body) .map_err(Error::from) - .map(|res| { + .map(|mut res| { let mut client_resp = HttpResponse::build(res.status()); // Remove `Connection` as per // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection#Directives - for (header_name, header_value) in res - .headers() - .iter() - .filter(|(h, _)| *h != "connection") + for (header_name, header_value) in + res.headers().iter().filter(|(h, _)| *h != "connection") { client_resp.header(header_name.clone(), header_value.clone()); } - client_resp.streaming(res) + res.body() + .into_stream() + .concat2() + .map(move |b| client_resp.body(b)) + .map_err(|e| e.into()) }) + .flatten() } fn main() -> std::io::Result<()> {