Merge pull request #157 from bhendo/master

Complete CONNECT requests for HTTPS through proxies
This commit is contained in:
Sean McArthur
2017-07-03 19:22:21 -07:00
committed by GitHub
2 changed files with 29 additions and 18 deletions

View File

@@ -335,7 +335,9 @@ impl Client {
}); });
if proxy::is_proxied(&self.inner.proxies, &uri) { if proxy::is_proxied(&self.inner.proxies, &uri) {
req.set_proxy(true); if uri.scheme() == Some("http") {
req.set_proxy(true);
}
} }
let in_flight = self.inner.hyper.request(req); let in_flight = self.inner.hyper.request(req);
@@ -451,7 +453,9 @@ impl Future for Pending {
req.set_body(body.clone()); req.set_body(body.clone());
} }
if proxy::is_proxied(&self.client.proxies, &uri) { if proxy::is_proxied(&self.client.proxies, &uri) {
req.set_proxy(true); if uri.scheme() == Some("http") {
req.set_proxy(true);
}
} }
self.in_flight = self.client.hyper.request(req); self.in_flight = self.client.hyper.request(req);
continue; continue;

View File

@@ -49,10 +49,14 @@ impl Service for Connector {
for prox in self.proxies.iter() { for prox in self.proxies.iter() {
if let Some(puri) = proxy::proxies(prox, &uri) { if let Some(puri) = proxy::proxies(prox, &uri) {
if uri.scheme() == Some("https") { if uri.scheme() == Some("https") {
let host = uri.authority().unwrap().to_owned(); let host = uri.host().unwrap().to_owned();
let port = match uri.port(){
Some(port) => port.to_string(),
None => 443.to_string()
}.to_owned();
let tls = self.tls.clone(); let tls = self.tls.clone();
return Box::new(self.https.call(puri).and_then(move |conn| { return Box::new(self.https.call(puri).and_then(move |conn| {
tunnel(conn, host.clone()) tunnel(conn, host.clone(), port.clone())
.and_then(move |tunneled| { .and_then(move |tunneled| {
tls.connect_async(&host, tunneled) tls.connect_async(&host, tunneled)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e)) .map_err(|e| io::Error::new(io::ErrorKind::Other, e))
@@ -137,12 +141,12 @@ impl AsyncWrite for Conn {
} }
} }
fn tunnel<T>(conn: T, host: String) -> Tunnel<T> { fn tunnel<T>(conn: T, host: String, port: String) -> Tunnel<T> {
let buf = format!("\ let buf = format!("\
CONNECT {0} HTTP/1.1\r\n\ CONNECT {0}:{1} HTTP/1.1\r\n\
Host: {0}\r\n\ Host: {0}:{1}\r\n\
\r\n\ \r\n\
", host).into_bytes(); ", host, port).into_bytes();
Tunnel { Tunnel {
buf: buf.into_buf(), buf: buf.into_buf(),
@@ -183,7 +187,7 @@ where T: AsyncRead + AsyncWrite {
if n == 0 { if n == 0 {
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected eof while tunneling")); return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected eof while tunneling"));
} else if read.len() > 12 { } else if read.len() > 12 {
if read.starts_with(b"HTTP/1.1 200") { if read.starts_with(b"HTTP/1.1 200") || read.starts_with(b"HTTP/1.0 200"){
if read.ends_with(b"\r\n\r\n") { if read.ends_with(b"\r\n\r\n") {
return Ok(Async::Ready(self.conn.take().unwrap())); return Ok(Async::Ready(self.conn.take().unwrap()));
} }
@@ -219,10 +223,10 @@ mod tests {
let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap(); let addr = listener.local_addr().unwrap();
let connect_expected = format!("\ let connect_expected = format!("\
CONNECT {0} HTTP/1.1\r\n\ CONNECT {0}:{1} HTTP/1.1\r\n\
Host: {0}\r\n\ Host: {0}:{1}\r\n\
\r\n\ \r\n\
", addr).into_bytes(); ", addr.ip(), addr.port()).into_bytes();
thread::spawn(move || { thread::spawn(move || {
let (mut sock, _) = listener.accept().unwrap(); let (mut sock, _) = listener.accept().unwrap();
@@ -242,9 +246,10 @@ mod tests {
let mut core = Core::new().unwrap(); let mut core = Core::new().unwrap();
let work = TcpStream::connect(&addr, &core.handle()); let work = TcpStream::connect(&addr, &core.handle());
let host = addr.to_string(); let host = addr.ip().to_string();
let port = addr.port().to_string();
let work = work.and_then(|tcp| { let work = work.and_then(|tcp| {
tunnel(tcp, host) tunnel(tcp, host, port)
}); });
core.run(work).unwrap(); core.run(work).unwrap();
@@ -256,9 +261,10 @@ mod tests {
let mut core = Core::new().unwrap(); let mut core = Core::new().unwrap();
let work = TcpStream::connect(&addr, &core.handle()); let work = TcpStream::connect(&addr, &core.handle());
let host = addr.to_string(); let host = addr.ip().to_string();
let port = addr.port().to_string();
let work = work.and_then(|tcp| { let work = work.and_then(|tcp| {
tunnel(tcp, host) tunnel(tcp, host, port)
}); });
core.run(work).unwrap_err(); core.run(work).unwrap_err();
@@ -270,9 +276,10 @@ mod tests {
let mut core = Core::new().unwrap(); let mut core = Core::new().unwrap();
let work = TcpStream::connect(&addr, &core.handle()); let work = TcpStream::connect(&addr, &core.handle());
let host = addr.to_string(); let host = addr.ip().to_string();
let port = addr.port().to_string();
let work = work.and_then(|tcp| { let work = work.and_then(|tcp| {
tunnel(tcp, host) tunnel(tcp, host, port)
}); });
core.run(work).unwrap_err(); core.run(work).unwrap_err();