use std::time::Duration;
use futures::future::BoxFuture;
use thiserror::Error;
use crate::error::BoxError;
#[derive(Debug, Clone)]
pub struct HttpRequest {
pub url: String,
pub timeout: Option<Duration>,
pub follow_redirects: bool,
pub max_redirects: u32,
pub max_response_bytes: u64,
}
#[derive(Debug, Clone)]
pub struct HttpResponse {
pub status: u16,
pub content_type: Option<String>,
pub body: Vec<u8>,
pub bytes_received: u64,
pub truncated: bool,
pub redirects: u32,
pub final_url: String,
}
#[non_exhaustive]
#[derive(Debug, Error)]
pub enum HttpClientError {
#[error("invalid URL: {0}")]
InvalidUrl(String),
#[error("http request timed out")]
Timeout,
#[error("too many redirects ({0})")]
TooManyRedirects(u32),
#[error("http transport error: {0}")]
Transport(#[source] BoxError),
}
pub trait HttpClient: Send + Sync {
fn fetch(&self, req: HttpRequest) -> BoxFuture<'_, Result<HttpResponse, HttpClientError>>;
}
pub struct NoopHttpClient;
impl HttpClient for NoopHttpClient {
fn fetch(&self, _req: HttpRequest) -> BoxFuture<'_, Result<HttpResponse, HttpClientError>> {
Box::pin(async move {
Err(HttpClientError::Transport(BoxError::new(
std::io::Error::other("NoopHttpClient: HTTP fetch not configured"),
)))
})
}
}