Skip to content

Commit

Permalink
fix(client): fix panic when CONNECT request doesn't have a port
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmonstar committed Feb 11, 2019
1 parent 3e9782c commit d16b2c3
Showing 1 changed file with 38 additions and 22 deletions.
60 changes: 38 additions & 22 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,28 +245,10 @@ where C: Connect + Sync + 'static,
}
};

let uri = req.uri().clone();
let domain = match (uri.scheme_part(), uri.authority_part()) {
(Some(scheme), Some(auth)) => {
format!("{}://{}", scheme, auth)
}
(None, Some(auth)) if is_http_connect => {
let port = auth.port_part().unwrap();
let scheme = match port.as_str() {
"443" => {
set_scheme(req.uri_mut(), Scheme::HTTPS);
"https"
},
_ => {
set_scheme(req.uri_mut(), Scheme::HTTP);
"http"
},
};
format!("{}://{}", scheme, auth)
},
_ => {
debug!("Client requires absolute-form URIs, received: {:?}", uri);
return ResponseFuture::new(Box::new(future::err(::Error::new_user_absolute_uri_required())))
let domain = match extract_domain(req.uri_mut(), is_http_connect) {
Ok(s) => s,
Err(err) => {
return ResponseFuture::new(Box::new(future::err(err)));
}
};

Expand Down Expand Up @@ -808,6 +790,33 @@ fn authority_form(uri: &mut Uri) {
};
}

fn extract_domain(uri: &mut Uri, is_http_connect: bool) -> ::Result<String> {
let uri_clone = uri.clone();
match (uri_clone.scheme_part(), uri_clone.authority_part()) {
(Some(scheme), Some(auth)) => {
Ok(format!("{}://{}", scheme, auth))
}
(None, Some(auth)) if is_http_connect => {
let port = auth.port_part();
let scheme = match port.as_ref().map(|p| p.as_str()) {
Some("443") => {
set_scheme(uri, Scheme::HTTPS);
"https"
}
_ => {
set_scheme(uri, Scheme::HTTP);
"http"
},
};
Ok(format!("{}://{}", scheme, auth))
},
_ => {
debug!("Client requires absolute-form URIs, received: {:?}", uri);
Err(::Error::new_user_absolute_uri_required())
}
}
}

fn set_scheme(uri: &mut Uri, scheme: Scheme) {
debug_assert!(uri.scheme_part().is_none(), "set_scheme expects no existing scheme");
let old = mem::replace(uri, Uri::default());
Expand Down Expand Up @@ -1089,4 +1098,11 @@ mod unit_tests {
authority_form(&mut uri);
assert_eq!(uri.to_string(), "hyper.rs");
}

#[test]
fn test_extract_domain_connect_no_port() {
let mut uri = "hyper.rs".parse().unwrap();
let domain = extract_domain(&mut uri, true).expect("extract domain");
assert_eq!(domain, "http://hyper.rs");
}
}

0 comments on commit d16b2c3

Please sign in to comment.