http-request 21.7.8

http-request is a lightweight, efficient library for building, sending, and handling HTTP/HTTPS requests in Rust applications. It provides a simple and intuitive API, allowing developers to easily interact with web services, whether they use the "HTTP" or "HTTPS" protocol. The library supports various HTTP methods, custom headers, request bodies, timeout, automatic handling of redirects (including detecting redirect loops), and enhanced response body decoding (both automatic and manual), enabling fast and secure communication. Whether working with secure "HTTPS" connections or standard "HTTP" requests, the library is optimized for performance, minimal resource usage, and easy integration into Rust projects.
Documentation
use super::*;

/// Proxy protocol family.
///
/// Distinguishes the wire format used to reach the proxy server:
/// plain `HTTP CONNECT` for HTTP proxies, TLS-wrapped `HTTP CONNECT` for
/// HTTPS proxies, and SOCKS5 handshake for SOCKS5 proxies.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ProxyType {
    /// HTTP proxy (plain TCP, CONNECT method).
    Http,
    /// HTTPS proxy (TLS-wrapped CONNECT method).
    Https,
    /// SOCKS5 proxy.
    Socks5,
}

/// Proxy configuration for an outgoing HTTP / WebSocket request.
///
/// `Proxy` is a value type with no `Arc<RwLock>` wrapping — exactly like
/// `hyperlane-core`'s plain fields. Construct one with the convenience
/// constructors below, then pass to `RequestBuilder::proxy(...)` or assign
/// directly to `RequestConfig::proxy`.
///
/// # Examples
///
/// ```ignore
/// use http_request::Proxy;
///
/// let p = Proxy::https("proxy.example.com", 7890);
/// let auth = Proxy::socks5("127.0.0.1", 1080).auth("user", "pass");
/// ```
#[derive(Clone, Data, Debug, Eq, PartialEq)]
pub struct Proxy {
    /// Proxy protocol family.
    pub proxy_type: ProxyType,
    /// Proxy server hostname or IP.
    pub host: String,
    /// Proxy server port.
    pub port: u16,
    /// Optional username for proxy auth.
    pub username: Option<String>,
    /// Optional password for proxy auth.
    pub password: Option<String>,
}

impl Proxy {
    /// Plain HTTP proxy.
    pub fn http<H: AsRef<str>>(host: H, port: u16) -> Self {
        Self::new(ProxyType::Http, host, port)
    }

    /// HTTPS proxy (TLS-wrapped).
    pub fn https<H: AsRef<str>>(host: H, port: u16) -> Self {
        Self::new(ProxyType::Https, host, port)
    }

    /// SOCKS5 proxy.
    pub fn socks5<H: AsRef<str>>(host: H, port: u16) -> Self {
        Self::new(ProxyType::Socks5, host, port)
    }

    /// Attach username / password to this proxy.
    pub fn auth<U: AsRef<str>, P: AsRef<str>>(mut self, username: U, password: P) -> Self {
        self.set_username(Some(username.as_ref().to_owned()));
        self.set_password(Some(password.as_ref().to_owned()));
        self
    }

    fn new<H: AsRef<str>>(proxy_type: ProxyType, host: H, port: u16) -> Self {
        Self {
            proxy_type,
            host: host.as_ref().to_owned(),
            port,
            username: None,
            password: None,
        }
    }
}

/// Async tunnel stream wrapping another async stream, with a buffer of
/// pre-read bytes that are returned before delegating to the inner stream.
#[derive(Data)]
pub struct ProxyTunnelStream {
    #[get(pub(crate))]
    #[get_mut(pub(crate))]
    #[set(pub(crate))]
    pub(super) inner: BoxAsyncReadWrite,
    #[get(pub(crate))]
    #[get_mut(pub(crate))]
    #[set(pub(crate))]
    pub(super) pre_read_data: Vec<u8>,
}

/// Sync tunnel stream wrapping another sync stream, with a buffer of
/// pre-read bytes that are returned before delegating to the inner stream.
#[derive(Data)]
pub struct SyncProxyTunnelStream {
    #[get(pub(crate))]
    #[get_mut(pub(crate))]
    #[set(pub(crate))]
    pub(super) inner: BoxReadWrite,
    #[get(pub(crate))]
    #[get_mut(pub(crate))]
    #[set(pub(crate))]
    pub(super) pre_read_data: Vec<u8>,
}