net-cat 0.3.0

Minimal hand-rolled HTTP/1.1 client over std::net::TcpStream. v0.3.0 adds chunked-transfer decoding (`Transfer-Encoding: chunked` responses now yield the correct decoded body) and a redirect follower in `fetch` (RFC 7231 §6.4: 301/302/303 downgrade non-GET/HEAD to GET and drop the body; 307/308 preserve method + body; cross-origin hops strip `Cookie` and `Authorization`; capped at `MAX_REDIRECTS = 10` hops). Optional `tls` feature still wires rustls + webpki-roots for `https://` URLs. No external HTTP crate. Sixth sub-crate of a Servo-replacement webview runtime targeting Tauri.
//! HTTP request.

use crate::headers::Headers;
use crate::method::Method;
use crate::url::Url;

/// An HTTP request.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Request {
    method: Method,
    url: Url,
    headers: Headers,
    body: Vec<u8>,
}

impl Request {
    /// Build a request with empty headers and no body.
    #[must_use]
    pub fn new(method: Method, url: Url) -> Self {
        Self {
            method,
            url,
            headers: Headers::new(),
            body: Vec::new(),
        }
    }

    /// The method.
    #[must_use]
    pub fn method(&self) -> Method {
        self.method
    }

    /// The URL.
    #[must_use]
    pub fn url(&self) -> &Url {
        &self.url
    }

    /// The headers.
    #[must_use]
    pub fn headers(&self) -> &Headers {
        &self.headers
    }

    /// The body bytes.
    #[must_use]
    pub fn body(&self) -> &[u8] {
        &self.body
    }

    /// Return a copy with `name: value` appended to the headers.
    #[must_use]
    pub fn with_header(self, name: impl Into<String>, value: impl Into<String>) -> Self {
        let headers = self.headers.with(name, value);
        Self { headers, ..self }
    }

    /// Return a copy with `body` replacing the current body.
    #[must_use]
    pub fn with_body(self, body: Vec<u8>) -> Self {
        Self { body, ..self }
    }

    /// Return a copy targeting `url` instead of the current URL.
    /// Used by `fetch`'s redirect follower.
    #[must_use]
    pub fn with_url(self, url: Url) -> Self {
        Self { url, ..self }
    }

    /// Return a copy whose method is `method`.  Used by `fetch`'s
    /// redirect follower to convert 301/302/303 responses to `GET`.
    #[must_use]
    pub fn with_method(self, method: Method) -> Self {
        Self { method, ..self }
    }

    /// Return a copy whose headers are replaced wholesale.  Used by
    /// `fetch`'s redirect follower to drop sensitive headers on
    /// cross-origin hops.
    #[must_use]
    pub fn with_headers(self, headers: Headers) -> Self {
        Self { headers, ..self }
    }
}