diff --git a/src/config.rs b/src/config.rs index c504dde..3deed2a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,117 +5,18 @@ use std::{ use color_eyre::eyre::{OptionExt as _, WrapErr as _}; -use crate::{ - parsers::parse_ipv4, - proxy::ProxyType, - raw_config::RawConfig, - utils::{is_docker, pretty_error}, -}; +use crate::{proxy::ProxyType, raw_config::RawConfig, utils::is_docker}; pub const APP_DIRECTORY_NAME: &str = "proxy_scraper_checker"; pub const USER_AGENT: &str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) \ AppleWebKit/537.36 (KHTML, like Gecko) \ Chrome/135.0.0.0 Safari/537.36"; -#[derive(Clone)] -pub enum CheckWebsiteType { - Unknown, - PlainIp, - HttpbinIp, -} - #[derive(serde::Deserialize)] pub struct HttpbinResponse { pub origin: String, } -impl CheckWebsiteType { - pub async fn guess( - check_website: &str, - http_client: reqwest::Client, - ) -> Self { - if check_website.is_empty() { - return Self::Unknown; - } - - let response = match http_client.get(check_website).send().await { - Ok(resp) => resp, - Err(err) => { - log::error!( - "Failed to open check_website without proxy, it will be \ - impossible to determine anonymity and geolocation of \ - proxies: {err}", - ); - return Self::Unknown; - } - }; - - let response = match response.error_for_status() { - Ok(response) => response, - Err(err) => { - if let Some(status) = err.status() { - log::error!( - "check_website returned error HTTP status code: \ - {status}" - ); - } else { - log::error!( - "check_website returned error HTTP status code" - ); - } - return Self::Unknown; - } - }; - - let body = match response.text().await { - Ok(text) => text, - Err(err) => { - log::error!("Failed to decode check_website response: {err}"); - return Self::Unknown; - } - }; - - if let Ok(httpbin) = serde_json::from_str::(&body) { - match parse_ipv4(&httpbin.origin) { - Ok(Some(_)) => { - return Self::HttpbinIp; - } - Ok(None) => { - log::error!("Failed to parse ipv4 from httpbin response"); - } - Err(e) => { - log::error!( - "Failed to parse ipv4 from httpbin response: {}", - pretty_error(&e) - ); - } - } - } else { - match parse_ipv4(&body) { - Ok(Some(_)) => { - return Self::PlainIp; - } - Ok(None) => {} - Err(e) => { - log::error!( - "Failed to parse ipv4 from response: {}", - pretty_error(&e) - ); - } - } - } - - Self::Unknown - } - - pub const fn supports_geolocation(&self) -> bool { - match self { - Self::Unknown => false, - Self::PlainIp | Self::HttpbinIp => true, - } - } -} - #[expect(clippy::struct_excessive_bools)] pub struct Config { pub timeout: tokio::time::Duration, @@ -123,7 +24,6 @@ pub struct Config { pub proxies_per_source_limit: usize, pub max_concurrent_checks: usize, pub check_website: String, - pub check_website_type: CheckWebsiteType, pub sort_by_speed: bool, pub enable_geolocation: bool, pub debug: bool, @@ -157,23 +57,17 @@ async fn get_output_path( impl Config { pub async fn from_raw_config( raw_config: RawConfig, - http_client: reqwest::Client, ) -> color_eyre::Result { - let (check_website_type, output_path) = tokio::try_join!( - async { - Ok(CheckWebsiteType::guess( - &raw_config.check_website, - http_client, - ) - .await) - }, - get_output_path(&raw_config) - )?; + let output_path = get_output_path(&raw_config).await?; let max_concurrent_checks = match rlimit::increase_nofile_limit(u64::MAX) { Ok(lim) => { + #[cfg(target_pointer_width = "32")] + let lim = cast::usize(lim).unwrap_or(usize::MAX); + #[cfg(not(target_pointer_width = "32"))] let lim = cast::usize(lim); + if raw_config.max_concurrent_checks > lim { log::warn!( "max_concurrent_checks config value is too high \ @@ -196,10 +90,8 @@ impl Config { proxies_per_source_limit: raw_config.proxies_per_source_limit, max_concurrent_checks, check_website: raw_config.check_website, - check_website_type: check_website_type.clone(), sort_by_speed: raw_config.sort_by_speed, - enable_geolocation: raw_config.enable_geolocation - && check_website_type.supports_geolocation(), + enable_geolocation: raw_config.enable_geolocation, debug: raw_config.debug, output_path, output_json: raw_config.output.json, diff --git a/src/main.rs b/src/main.rs index cdcee56..6d7adc8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,16 +68,13 @@ async fn main() -> color_eyre::Result<()> { let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); let ui_task = tokio::task::spawn(ui_impl.run(tx.clone(), rx)); - let http_client = create_reqwest_client() - .wrap_err("failed to create reqwest HTTP client")?; - let raw_config_path = raw_config::get_config_path(); let raw_config = raw_config::read_config(&raw_config_path) .await .wrap_err_with(move || format!("failed to read {raw_config_path}"))?; let config = Arc::new( - config::Config::from_raw_config(raw_config, http_client.clone()) + config::Config::from_raw_config(raw_config) .await .wrap_err("failed to create Config from RawConfig")?, ); @@ -86,6 +83,9 @@ async fn main() -> color_eyre::Result<()> { ui::UIImpl::set_log_level(log::LevelFilter::Debug); } + let http_client = create_reqwest_client() + .wrap_err("failed to create reqwest HTTP client")?; + let maybe_geodb_task = config.enable_geolocation.then(|| { let http_client = http_client.clone(); #[cfg(feature = "tui")] diff --git a/src/proxy.rs b/src/proxy.rs index 5d62dc7..bc947ce 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -1,9 +1,9 @@ use std::{fmt, fmt::Write as _, sync::Arc}; -use color_eyre::eyre::{OptionExt as _, WrapErr as _, eyre}; +use color_eyre::eyre::{WrapErr as _, eyre}; use crate::{ - config::{CheckWebsiteType, Config, HttpbinResponse, USER_AGENT}, + config::{Config, HttpbinResponse, USER_AGENT}, parsers::parse_ipv4, }; @@ -109,35 +109,20 @@ impl Proxy { .wrap_err("Got error HTTP status code when checking proxy")?; drop(client); self.timeout = Some(start.elapsed()); - self.exit_ip = match config.check_website_type { - CheckWebsiteType::HttpbinIp => { - let httpbin = response - .json::() - .await - .wrap_err("failed to parse response as HttpBin")?; - Some( - parse_ipv4(&httpbin.origin) - .wrap_err("failed to parse ipv4 from httpbin response")? - .ok_or_eyre( - "failed to parse ipv4 from httpbin response", - )?, - ) + self.exit_ip = response.text().await.map_or(None, move |text| { + if let Ok(httpbin) = serde_json::from_str::(&text) + { + match parse_ipv4(&httpbin.origin) { + Ok(Some(ipv4)) => Some(ipv4), + Ok(None) | Err(_) => None, + } + } else { + match parse_ipv4(&text) { + Ok(Some(ipv4)) => Some(ipv4), + Ok(None) | Err(_) => None, + } } - CheckWebsiteType::PlainIp => { - let text = response - .text() - .await - .wrap_err("failed to decode response text")?; - Some( - parse_ipv4(&text) - .wrap_err("failed to parse ipv4 from response text")? - .ok_or_eyre( - "failed to parse ipv4 from response text", - )?, - ) - } - CheckWebsiteType::Unknown => None, - }; + }); Ok(()) }