Remove username and password when parsing proxies (#686)
This commit is contained in:
115
src/proxy.rs
115
src/proxy.rs
@@ -60,7 +60,11 @@ pub struct Proxy {
|
||||
pub enum ProxyScheme {
|
||||
Http {
|
||||
auth: Option<HeaderValue>,
|
||||
uri: hyper::Uri,
|
||||
host: http::uri::Authority,
|
||||
},
|
||||
Https {
|
||||
auth: Option<HeaderValue>,
|
||||
host: http::uri::Authority,
|
||||
},
|
||||
#[cfg(feature = "socks")]
|
||||
Socks5 {
|
||||
@@ -226,6 +230,7 @@ impl Proxy {
|
||||
| Intercept::Http(ProxyScheme::Http { ref auth, .. }) => auth.clone(),
|
||||
Intercept::Custom(ref custom) => custom.call(uri).and_then(|scheme| match scheme {
|
||||
ProxyScheme::Http { auth, .. } => auth,
|
||||
ProxyScheme::Https { auth, .. } => auth,
|
||||
#[cfg(feature = "socks")]
|
||||
_ => None,
|
||||
}),
|
||||
@@ -278,10 +283,18 @@ impl ProxyScheme {
|
||||
// To start conservative, keep builders private for now.
|
||||
|
||||
/// Proxy traffic via the specified URL over HTTP
|
||||
fn http<T: IntoUrl>(url: T) -> crate::Result<Self> {
|
||||
fn http(host: &str) -> crate::Result<Self> {
|
||||
Ok(ProxyScheme::Http {
|
||||
auth: None,
|
||||
uri: crate::into_url::expect_uri(&url.into_url()?),
|
||||
host: host.parse().map_err(crate::error::builder)?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Proxy traffic via the specified URL over HTTPS
|
||||
fn https(host: &str) -> crate::Result<Self> {
|
||||
Ok(ProxyScheme::Https {
|
||||
auth: None,
|
||||
host: host.parse().map_err(crate::error::builder)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -330,7 +343,11 @@ impl ProxyScheme {
|
||||
ProxyScheme::Http { ref mut auth, .. } => {
|
||||
let header = encode_basic_auth(&username.into(), &password.into());
|
||||
*auth = Some(header);
|
||||
}
|
||||
},
|
||||
ProxyScheme::Https { ref mut auth, .. } => {
|
||||
let header = encode_basic_auth(&username.into(), &password.into());
|
||||
*auth = Some(header);
|
||||
},
|
||||
#[cfg(feature = "socks")]
|
||||
ProxyScheme::Socks5 { ref mut auth, .. } => {
|
||||
*auth = Some((username.into(), password.into()));
|
||||
@@ -338,11 +355,32 @@ impl ProxyScheme {
|
||||
}
|
||||
}
|
||||
|
||||
fn if_no_auth(mut self, update: &Option<HeaderValue>) -> Self {
|
||||
match self {
|
||||
ProxyScheme::Http { ref mut auth, .. } => {
|
||||
if auth.is_none() {
|
||||
*auth = update.clone();
|
||||
}
|
||||
},
|
||||
ProxyScheme::Https { ref mut auth, .. } => {
|
||||
if auth.is_none() {
|
||||
*auth = update.clone();
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "socks")]
|
||||
ProxyScheme::Socks5 { .. } => {}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Convert a URL into a proxy scheme
|
||||
///
|
||||
/// Supported schemes: HTTP, HTTPS, (SOCKS5, SOCKS5H if `socks` feature is enabled).
|
||||
// Private for now...
|
||||
fn parse(url: Url) -> crate::Result<Self> {
|
||||
use url::Position;
|
||||
|
||||
// Resolve URL to a host and port
|
||||
#[cfg(feature = "socks")]
|
||||
let to_addr = || {
|
||||
@@ -357,7 +395,8 @@ impl ProxyScheme {
|
||||
};
|
||||
|
||||
let mut scheme = match url.scheme() {
|
||||
"http" | "https" => Self::http(url.clone())?,
|
||||
"http" => Self::http(&url[Position::BeforeHost..Position::AfterPort])?,
|
||||
"https" => Self::https(&url[Position::BeforeHost..Position::AfterPort])?,
|
||||
#[cfg(feature = "socks")]
|
||||
"socks5" => Self::socks5(to_addr()?)?,
|
||||
#[cfg(feature = "socks")]
|
||||
@@ -375,13 +414,22 @@ impl ProxyScheme {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn http_uri(&self) -> &http::Uri {
|
||||
fn scheme(&self) -> &str {
|
||||
match self {
|
||||
ProxyScheme::Http { ref uri, .. } => {
|
||||
uri
|
||||
},
|
||||
ProxyScheme::Http { .. } => "http",
|
||||
ProxyScheme::Https { .. } => "https",
|
||||
#[cfg(feature = "socks")]
|
||||
_ => panic!("socks not expected"),
|
||||
ProxyScheme::Socks5 => "socks5",
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn host(&self) -> &str {
|
||||
match self {
|
||||
ProxyScheme::Http { host, .. } => host.as_str(),
|
||||
ProxyScheme::Https { host, .. } => host.as_str(),
|
||||
#[cfg(feature = "socks")]
|
||||
ProxyScheme::Socks5 => panic!("socks5"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -433,20 +481,7 @@ impl Custom {
|
||||
|
||||
(self.func)(&url)
|
||||
.and_then(|result| result.ok())
|
||||
.map(|scheme| match scheme {
|
||||
ProxyScheme::Http { auth, uri } => {
|
||||
if auth.is_some() {
|
||||
ProxyScheme::Http { auth, uri }
|
||||
} else {
|
||||
ProxyScheme::Http {
|
||||
auth: self.auth.clone(),
|
||||
uri,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "socks")]
|
||||
socks => socks,
|
||||
})
|
||||
.map(|scheme| scheme.if_no_auth(&self.auth))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,11 +694,18 @@ mod tests {
|
||||
}
|
||||
|
||||
fn intercepted_uri(p: &Proxy, s: &str) -> Uri {
|
||||
match p.intercept(&url(s)).unwrap() {
|
||||
ProxyScheme::Http { uri, .. } => uri,
|
||||
let (scheme, host) = match p.intercept(&url(s)).unwrap() {
|
||||
ProxyScheme::Http { host, .. } => ("http", host),
|
||||
ProxyScheme::Https { host, .. } => ("https", host),
|
||||
#[cfg(feature = "socks")]
|
||||
_ => panic!("intercepted as socks"),
|
||||
}
|
||||
};
|
||||
http::Uri::builder()
|
||||
.scheme(scheme)
|
||||
.authority(host)
|
||||
.path_and_query("/")
|
||||
.build()
|
||||
.expect("intercepted_uri")
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -727,6 +769,19 @@ mod tests {
|
||||
assert!(p.intercept(&url(other)).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_proxy_scheme_parse() {
|
||||
let ps = "http://foo:bar@localhost:1239".into_proxy_scheme().unwrap();
|
||||
|
||||
match ps {
|
||||
ProxyScheme::Http { auth, host } => {
|
||||
assert_eq!(auth.unwrap(), encode_basic_auth("foo", "bar"));
|
||||
assert_eq!(host, "localhost:1239");
|
||||
},
|
||||
other => panic!("unexpected: {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_sys_proxies_parsing() {
|
||||
// save system setting first.
|
||||
@@ -744,7 +799,9 @@ mod tests {
|
||||
env::set_var("http_proxy", "http://127.0.0.1/");
|
||||
let proxies = get_sys_proxies();
|
||||
|
||||
assert_eq!(proxies["http"].http_uri(), "http://127.0.0.1/");
|
||||
let p = &proxies["http"];
|
||||
assert_eq!(p.scheme(), "http");
|
||||
assert_eq!(p.host(), "127.0.0.1");
|
||||
|
||||
// reset user setting when guards drop
|
||||
}
|
||||
@@ -759,7 +816,7 @@ mod tests {
|
||||
env::set_var("HTTP_PROXY", "http://evil/");
|
||||
|
||||
// not in CGI yet
|
||||
assert_eq!(get_sys_proxies()["http"].http_uri(), "http://evil/");
|
||||
assert_eq!(get_sys_proxies()["http"].host(), "evil");
|
||||
|
||||
// set like we're in CGI
|
||||
env::set_var("REQUEST_METHOD", "GET");
|
||||
|
||||
Reference in New Issue
Block a user