| 190 | } |
| 191 | |
| 192 | fn parse(url: Url) -> Result<Self, ProxyError> { |
| 193 | use url::Position; |
| 194 | |
| 195 | // Resolve URL to a host and port |
| 196 | let to_addr = || { |
| 197 | let addrs = url.socket_addrs(|| match url.scheme() { |
| 198 | "socks5" => Some(1080), |
| 199 | _ => None, |
| 200 | })?; |
| 201 | addrs |
| 202 | .into_iter() |
| 203 | .next() |
| 204 | .ok_or_else(|| ProxyError::UrlParseScheme(url::ParseError::EmptyHost)) |
| 205 | }; |
| 206 | |
| 207 | let mut scheme: Self = match url.scheme() { |
| 208 | "http" => Self::http(&url[Position::BeforeHost..Position::AfterPort])?, |
| 209 | "https" => Self::https(&url[Position::BeforeHost..Position::AfterPort])?, |
| 210 | "socks5" => Self::socks5(to_addr()?)?, |
| 211 | e => return Err(ProxyError::UrlBadScheme(e.to_string())), |
| 212 | }; |
| 213 | |
| 214 | if let Some(pwd) = url.password() { |
| 215 | let username = url.username(); |
| 216 | scheme.set_basic_auth(username, pwd); |
| 217 | } |
| 218 | |
| 219 | Ok(scheme) |
| 220 | } |
| 221 | pub async fn socket_addrs(&self) -> Result<SocketAddr, ProxyError> { |
| 222 | info!("Resolving socket address"); |
| 223 | match self { |