use std::time::Duration; use anyhow::Result; use reqwest::{Client, StatusCode, Url}; /// HTTP Connectivity module for checking HTTP/HTTPS connections pub struct HttpConnector { client: Client, } impl HttpConnector { /// Create a new HTTP connector with the default configuration pub fn new() -> Result { let client = Client::builder().timeout(Duration::from_secs(30)).build()?; Ok(Self { client }) } /// Create a new HTTP connector with a custom timeout pub fn with_timeout(timeout: Duration) -> Result { let client = Client::builder().timeout(timeout).build()?; Ok(Self { client }) } /// Check if a URL is reachable pub async fn check_url>(&self, url: U) -> Result { let url_str = url.as_ref(); let url = Url::parse(url_str)?; let result = self.client.head(url).send().await; Ok(result.is_ok()) } /// Check a URL and return the status code if reachable pub async fn check_status>(&self, url: U) -> Result> { let url_str = url.as_ref(); let url = Url::parse(url_str)?; let result = self.client.head(url).send().await; match result { Ok(response) => Ok(Some(response.status())), Err(_) => Ok(None), } } /// Get the content of a URL pub async fn get_content>(&self, url: U) -> Result { let url_str = url.as_ref(); let url = Url::parse(url_str)?; let response = self.client.get(url).send().await?; if !response.status().is_success() { return Err(anyhow::anyhow!( "HTTP request failed with status: {}", response.status() )); } let content = response.text().await?; Ok(content) } /// Verify that a URL responds with a specific status code pub async fn verify_status>( &self, url: U, expected_status: StatusCode, ) -> Result { match self.check_status(url).await? { Some(status) => Ok(status == expected_status), None => Ok(false), } } } impl Default for HttpConnector { fn default() -> Self { Self::new().expect("Failed to create default HttpConnector") } }