Skip to content

Commit e871411

Browse files
committed
feat(client): add Request.set_proxy for HTTP proxy requests
Closes #1056
1 parent 88eaaa0 commit e871411

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

src/client/request.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub struct Request<B = Body> {
1616
version: HttpVersion,
1717
headers: Headers,
1818
body: Option<B>,
19+
is_proxy: bool,
1920
}
2021

2122
impl<B> Request<B> {
@@ -28,6 +29,7 @@ impl<B> Request<B> {
2829
version: HttpVersion::default(),
2930
headers: Headers::new(),
3031
body: None,
32+
is_proxy: false,
3133
}
3234
}
3335

@@ -66,6 +68,13 @@ impl<B> Request<B> {
6668
/// Set the body of the request.
6769
#[inline]
6870
pub fn set_body<T: Into<B>>(&mut self, body: T) { self.body = Some(body.into()); }
71+
72+
/// Set that the URI should use the absolute form.
73+
///
74+
/// This is only needed when talking to HTTP/1 proxies to URLs not
75+
/// protected by TLS.
76+
#[inline]
77+
pub fn set_proxy(&mut self, is_proxy: bool) { self.is_proxy = is_proxy; }
6978
}
7079

7180
impl<B> fmt::Debug for Request<B> {
@@ -80,7 +89,11 @@ impl<B> fmt::Debug for Request<B> {
8089
}
8190

8291
pub fn split<B>(req: Request<B>) -> (RequestHead, Option<B>) {
83-
let uri = Uri::from_str(&req.url[::url::Position::BeforePath..::url::Position::AfterQuery]).expect("url is uri");
92+
let uri = if req.is_proxy {
93+
Uri::from(req.url)
94+
} else {
95+
Uri::from_str(&req.url[::url::Position::BeforePath..::url::Position::AfterQuery]).expect("url is not uri")
96+
};
8497
let head = RequestHead {
8598
subject: ::http::RequestLine(req.method, uri),
8699
headers: req.headers,

tests/client.rs

+31
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ macro_rules! test {
3737
url: $client_url:expr,
3838
headers: [ $($request_headers:expr,)* ],
3939
body: $request_body:expr,
40+
proxy: $request_proxy:expr,
4041

4142
response:
4243
status: $client_status:ident,
@@ -61,6 +62,8 @@ macro_rules! test {
6162
let body: &'static str = body;
6263
req.set_body(body);
6364
}
65+
req.set_proxy($request_proxy);
66+
6467
let res = client.request(req);
6568

6669
let (tx, rx) = oneshot::channel();
@@ -109,6 +112,7 @@ test! {
109112
url: "http://{addr}/",
110113
headers: [],
111114
body: None,
115+
proxy: false,
112116
response:
113117
status: Ok,
114118
headers: [
@@ -130,6 +134,7 @@ test! {
130134
url: "http://{addr}/foo?key=val#dont_send_me",
131135
headers: [],
132136
body: None,
137+
proxy: false,
133138
response:
134139
status: Ok,
135140
headers: [
@@ -159,6 +164,7 @@ test! {
159164
ContentLength(7),
160165
],
161166
body: Some("foo bar"),
167+
proxy: false,
162168
response:
163169
status: Ok,
164170
headers: [],
@@ -188,6 +194,31 @@ test! {
188194
TransferEncoding::chunked(),
189195
],
190196
body: Some("foo bar baz"),
197+
proxy: false,
198+
response:
199+
status: Ok,
200+
headers: [],
201+
body: None,
202+
}
203+
204+
test! {
205+
name: client_http_proxy,
206+
207+
server:
208+
expected: "\
209+
GET http://{addr}/proxy HTTP/1.1\r\n\
210+
Host: {addr}\r\n\
211+
\r\n\
212+
",
213+
reply: REPLY_OK,
214+
215+
client:
216+
request:
217+
method: Get,
218+
url: "http://{addr}/proxy",
219+
headers: [],
220+
body: None,
221+
proxy: true,
191222
response:
192223
status: Ok,
193224
headers: [],

0 commit comments

Comments
 (0)