fix(client): fix panic when CONNECT request doesn't have a port
This commit is contained in:
@@ -245,28 +245,10 @@ where C: Connect + Sync + 'static,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let uri = req.uri().clone();
|
let domain = match extract_domain(req.uri_mut(), is_http_connect) {
|
||||||
let domain = match (uri.scheme_part(), uri.authority_part()) {
|
Ok(s) => s,
|
||||||
(Some(scheme), Some(auth)) => {
|
Err(err) => {
|
||||||
format!("{}://{}", scheme, auth)
|
return ResponseFuture::new(Box::new(future::err(err)));
|
||||||
}
|
|
||||||
(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())))
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -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) {
|
fn set_scheme(uri: &mut Uri, scheme: Scheme) {
|
||||||
debug_assert!(uri.scheme_part().is_none(), "set_scheme expects no existing scheme");
|
debug_assert!(uri.scheme_part().is_none(), "set_scheme expects no existing scheme");
|
||||||
let old = mem::replace(uri, Uri::default());
|
let old = mem::replace(uri, Uri::default());
|
||||||
@@ -1089,4 +1098,11 @@ mod unit_tests {
|
|||||||
authority_form(&mut uri);
|
authority_form(&mut uri);
|
||||||
assert_eq!(uri.to_string(), "hyper.rs");
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user