feat(client): add Request.set_proxy for HTTP proxy requests

Closes #1056
This commit is contained in:
Sean McArthur
2017-03-07 12:16:38 -08:00
parent 88eaaa0016
commit e871411627
2 changed files with 45 additions and 1 deletions

View File

@@ -16,6 +16,7 @@ pub struct Request<B = Body> {
version: HttpVersion, version: HttpVersion,
headers: Headers, headers: Headers,
body: Option<B>, body: Option<B>,
is_proxy: bool,
} }
impl<B> Request<B> { impl<B> Request<B> {
@@ -28,6 +29,7 @@ impl<B> Request<B> {
version: HttpVersion::default(), version: HttpVersion::default(),
headers: Headers::new(), headers: Headers::new(),
body: None, body: None,
is_proxy: false,
} }
} }
@@ -66,6 +68,13 @@ impl<B> Request<B> {
/// Set the body of the request. /// Set the body of the request.
#[inline] #[inline]
pub fn set_body<T: Into<B>>(&mut self, body: T) { self.body = Some(body.into()); } pub fn set_body<T: Into<B>>(&mut self, body: T) { self.body = Some(body.into()); }
/// Set that the URI should use the absolute form.
///
/// This is only needed when talking to HTTP/1 proxies to URLs not
/// protected by TLS.
#[inline]
pub fn set_proxy(&mut self, is_proxy: bool) { self.is_proxy = is_proxy; }
} }
impl<B> fmt::Debug for Request<B> { impl<B> fmt::Debug for Request<B> {
@@ -80,7 +89,11 @@ impl<B> fmt::Debug for Request<B> {
} }
pub fn split<B>(req: Request<B>) -> (RequestHead, Option<B>) { pub fn split<B>(req: Request<B>) -> (RequestHead, Option<B>) {
let uri = Uri::from_str(&req.url[::url::Position::BeforePath..::url::Position::AfterQuery]).expect("url is uri"); let uri = if req.is_proxy {
Uri::from(req.url)
} else {
Uri::from_str(&req.url[::url::Position::BeforePath..::url::Position::AfterQuery]).expect("url is not uri")
};
let head = RequestHead { let head = RequestHead {
subject: ::http::RequestLine(req.method, uri), subject: ::http::RequestLine(req.method, uri),
headers: req.headers, headers: req.headers,

View File

@@ -37,6 +37,7 @@ macro_rules! test {
url: $client_url:expr, url: $client_url:expr,
headers: [ $($request_headers:expr,)* ], headers: [ $($request_headers:expr,)* ],
body: $request_body:expr, body: $request_body:expr,
proxy: $request_proxy:expr,
response: response:
status: $client_status:ident, status: $client_status:ident,
@@ -61,6 +62,8 @@ macro_rules! test {
let body: &'static str = body; let body: &'static str = body;
req.set_body(body); req.set_body(body);
} }
req.set_proxy($request_proxy);
let res = client.request(req); let res = client.request(req);
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
@@ -109,6 +112,7 @@ test! {
url: "http://{addr}/", url: "http://{addr}/",
headers: [], headers: [],
body: None, body: None,
proxy: false,
response: response:
status: Ok, status: Ok,
headers: [ headers: [
@@ -130,6 +134,7 @@ test! {
url: "http://{addr}/foo?key=val#dont_send_me", url: "http://{addr}/foo?key=val#dont_send_me",
headers: [], headers: [],
body: None, body: None,
proxy: false,
response: response:
status: Ok, status: Ok,
headers: [ headers: [
@@ -159,6 +164,7 @@ test! {
ContentLength(7), ContentLength(7),
], ],
body: Some("foo bar"), body: Some("foo bar"),
proxy: false,
response: response:
status: Ok, status: Ok,
headers: [], headers: [],
@@ -188,6 +194,31 @@ test! {
TransferEncoding::chunked(), TransferEncoding::chunked(),
], ],
body: Some("foo bar baz"), body: Some("foo bar baz"),
proxy: false,
response:
status: Ok,
headers: [],
body: None,
}
test! {
name: client_http_proxy,
server:
expected: "\
GET http://{addr}/proxy HTTP/1.1\r\n\
Host: {addr}\r\n\
\r\n\
",
reply: REPLY_OK,
client:
request:
method: Get,
url: "http://{addr}/proxy",
headers: [],
body: None,
proxy: true,
response: response:
status: Ok, status: Ok,
headers: [], headers: [],