diff --git a/Cargo.toml b/Cargo.toml index 9ca0adc66..a3aa59866 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,15 +27,16 @@ flate2 = { version = "^1.0.7", default-features = false, features = ["rust_backe log = "0.4" mime = "0.3.7" mime_guess = "2.0" +percent-encoding = "2.1" serde = "1.0" serde_json = "1.0" -serde_urlencoded = "0.5" +serde_urlencoded = "0.6.1" tokio = { version = "0.1.7", default-features = false, features = ["rt-full", "tcp"] } tokio-executor = "0.1.4" # a minimum version so trust-dns-resolver compiles tokio-io = "0.1" tokio-threadpool = "0.1.8" # a minimum version so tokio compiles tokio-timer = "0.2.6" # a minimum version so trust-dns-resolver compiles -url = "1.2" +url = "2.1" uuid = { version = "0.7", features = ["v4"] } # Optional deps... @@ -49,7 +50,7 @@ socks = { version = "0.3.2", optional = true } tokio-rustls = { version = "0.10", optional = true } trust-dns-resolver = { version = "0.11", optional = true } webpki-roots = { version = "0.17", optional = true } -cookie_store = "0.7.0" +cookie_store = "0.9.0" cookie = "0.12.0" time = "0.1.42" diff --git a/src/async_impl/multipart.rs b/src/async_impl/multipart.rs index dfb06a15d..c2eb8c225 100644 --- a/src/async_impl/multipart.rs +++ b/src/async_impl/multipart.rs @@ -4,7 +4,7 @@ use std::fmt; use http::HeaderMap; use mime_guess::Mime; -use url::percent_encoding::{self, EncodeSet, PATH_SEGMENT_ENCODE_SET}; +use percent_encoding::{self, AsciiSet, NON_ALPHANUMERIC}; use uuid::Uuid; use futures::Stream; @@ -386,33 +386,33 @@ impl PartMetadata { } } -#[derive(Debug, Clone)] -pub(crate) struct AttrCharEncodeSet; - -impl EncodeSet for AttrCharEncodeSet { - fn contains(&self, ch: u8) -> bool { - match ch as char { - '!' => false, - '#' => false, - '$' => false, - '&' => false, - '+' => false, - '-' => false, - '.' => false, - '^' => false, - '_' => false, - '`' => false, - '|' => false, - '~' => false, - _ => { - let is_alpha_numeric = ch >= 0x41 && ch <= 0x5a - || ch >= 0x61 && ch <= 0x7a - || ch >= 0x30 && ch <= 0x39; - !is_alpha_numeric - } - } - } -} +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ') + .add(b'"') + .add(b'<') + .add(b'>') + .add(b'`'); + +/// https://url.spec.whatwg.org/#path-percent-encode-set +const PATH_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'#').add(b'?').add(b'{').add(b'}'); + +const PATH_SEGMENT_ENCODE_SET: &AsciiSet = &PATH_ENCODE_SET.add(b'/').add(b'%'); + +/// https://tools.ietf.org/html/rfc8187#section-3.2.1 +const ATTR_CHAR_ENCODE_SET: &AsciiSet = &NON_ALPHANUMERIC + .remove(b'!') + .remove(b'#') + .remove(b'$') + .remove(b'&') + .remove(b'+') + .remove(b'-') + .remove(b'.') + .remove(b'^') + .remove(b'_') + .remove(b'`') + .remove(b'|') + .remove(b'~'); pub(crate) enum PercentEncoding { PathSegment, @@ -463,7 +463,7 @@ impl PercentEncoding { percent_encoding::utf8_percent_encode(value, PATH_SEGMENT_ENCODE_SET).to_string() } PercentEncoding::AttrChar => { - percent_encoding::utf8_percent_encode(value, AttrCharEncodeSet).to_string() + percent_encoding::utf8_percent_encode(value, ATTR_CHAR_ENCODE_SET).to_string() } PercentEncoding::NoOp => value.to_string(), }; diff --git a/src/body.rs b/src/body.rs index bea52e50d..dc17289bc 100644 --- a/src/body.rs +++ b/src/body.rs @@ -4,7 +4,7 @@ use std::io::{self, Cursor, Read}; use bytes::Bytes; use futures::{try_ready, Future}; -use hyper::{self}; +use hyper; use crate::async_impl; diff --git a/src/proxy.rs b/src/proxy.rs index d2457a61e..7ee3661cb 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -1,16 +1,16 @@ use std::fmt; #[cfg(feature = "socks")] -use std::net::{SocketAddr, ToSocketAddrs}; +use std::net::SocketAddr; use std::sync::Arc; use crate::{IntoUrl, Url}; use http::{header::HeaderValue, Uri}; use hyper::client::connect::Destination; +use percent_encoding::percent_decode; use std::collections::HashMap; use std::env; #[cfg(target_os = "windows")] use std::error::Error; -use url::percent_encoding::percent_decode; #[cfg(target_os = "windows")] use winreg::enums::HKEY_CURRENT_USER; #[cfg(target_os = "windows")] @@ -326,12 +326,14 @@ impl ProxyScheme { // Resolve URL to a host and port #[cfg(feature = "socks")] let to_addr = || { - let host_and_port = try_!(url.with_default_port(|url| match url.scheme() { - "socks5" | "socks5h" => Ok(1080), - _ => Err(()), + let addrs = try_!(url.socket_addrs(|| match url.scheme() { + "socks5" | "socks5h" => Some(1080), + _ => None, })); - let mut addr = try_!(host_and_port.to_socket_addrs()); - addr.next().ok_or_else(crate::error::unknown_proxy_scheme) + addrs + .into_iter() + .next() + .ok_or_else(crate::error::unknown_proxy_scheme) }; let mut scheme = match url.scheme() {