attohttpc

repository·master·Indexed 43 days ago

https://github.com/sbstp/attohttpc

A small, lightweight, and synchronous HTTP/1.1 client for Rust designed for simplicity and small binary sizes. It avoids the asynchronous stack and provides modular functionality via feature flags for JSON serialization, TLS (native-tls or rustls), compression, and multipart forms. Version 0.31.0.

Tokens
9K
Snippets
34
Records
46
Agent score
52%

What's inside attohttpc

  1. Overview of attohttpc

    master
    attohttpc is a lightweight, simple, and modular HTTP client for Rust. It is designed for projects where HTTP is not the primary purpose or where performance is not the absolute critical factor, as it avoids the complexity of the asynchronous stack to remain as small as possible. It focuses on HTTP/1.1 and leverages established ecosystem crates like http, url, and encoding_rs.
  2. Supported request body kinds

    master

    The BodyKind enum describes how the request body is transmitted. This information is used to determine if the body has a known length or requires chunked encoding.

    • Empty: No body content.
    • KnownLength(u64): A body with a specific, pre-determined size.
    • Chunked: A body transferred using chunked encoding (common for streaming data).
  3. Use `Session` to manage persistent request settings

    master

    A Session is a container for settings that are applied to every request created from it. This allows you to define common headers, timeouts, proxy settings, and TLS configurations once and reuse them across multiple requests.

    Session can be cloned cheaply and sent to other threads because it uses std::sync::Arc internally.

    To use a session, create a new one with Session::new() and then use its HTTP method helpers (like .get(), .post(), etc.) to generate RequestBuilder instances that inherit the session's configuration.

    use attohttpc::Session;
    use std::time::Duration;
    
    let mut session = Session::new();
    
    // Configure the session
    session.header("Authorization", "Bearer my_token");
    session.connect_timeout(Duration::from_secs(5));
    
    // Create requests using the session's settings
    let response = session.get("https://api.example.com/data")
        .send()?
        .text()?;
  4. Implement the Body trait for custom request bodies

    master

    The Body trait is the core abstraction for request payloads in attohttpc. Any type implementing Body can be used as a request body. The trait is designed to be rewindable, meaning the write method can be called multiple times (e.g., during HTTP redirects).

    Key methods:

    • kind(): Returns a BodyKind indicating if the length is known or if it is chunked.
    • write<W: Write>(&mut self, writer: W): Writes the body content into the provided writer.
    • content_type(): Returns an optional String representing the MIME type of the body.
  5. Use `Multipart` as an HTTP request body

    master

    The Multipart struct is the result of calling MultipartBuilder::build(). It implements the Body trait, meaning it can be passed directly into attohttpc request methods.

    When used as a body:

    • The Content-Type header is automatically set to multipart/form-data including the required boundary parameter.
    • The body is streamed using Chunked encoding.
    // Assuming 'client' is an attohttpc client
    let body = MultipartBuilder::new()
        .with_text("field", "value")
        .build()?;
    
    let response = client.post("https://example.com/upload")
        .body(body)
        .send()?;
  6. Configure attohttpc features via feature flags

    master

    attohttpc is modular. You can enable or disable specific capabilities using Cargo feature flags to keep your binary size small.

    Compression

    • compress (default): Decompresses response bodies using miniz_oxide.
    • compress-zlib: Uses zlib instead of miniz_oxide.
    • compress-zlib-ng: Uses zlib-ng instead of miniz_oxide.

    TLS (Transport Layer Security)

    • tls-native (default): Uses the native-tls crate.
    • tls-native-vendored: Activates the vendored feature of native-tls.
    • tls-rustls-webpki-roots: Uses rustls with Web PKI roots.
    • tls-rustls-native-roots: Uses rustls with root certificates from the rustls-native-certs crate.

    Data Formats & Encodings

    • json: Enables serde serialization and deserialization.
    • charsets: Supports decoding text encodings beyond UTF-8.
    • form: Supports URL-encoded forms (excludes multipart).
    • multipart-form: Supports multipart forms (excludes URL encoding).
  7. Configure attohttpc features in Cargo.toml

    master

    attohttpc uses feature flags to keep the crate small. You can enable specific functionality by adding them to your Cargo.toml file.

    Example:

    attohttpc = { version = "...", features = ["json", "form", "multipart-form"] }
    attohttpc = { version = "...", features = ["json", "form", ...] }
  8. Quick start with attohttpc

    master

    attohttpc is a lightweight, synchronous HTTP client for Rust. It is designed for projects where performance is not the absolute priority or where HTTP is not the main purpose of the application. It avoids the asynchronous stack to remain small and efficient.

    To perform a POST request with a JSON body, headers, and query parameters, use the following pattern:

    # #[cfg(feature = "json")]
    # use serde_json::json;
    # #[cfg(feature = "json")]
    # fn main() -> attohttpc::Result {
    let obj = json!({
        "hello": "world",
    });
    
    let resp = attohttpc::post("https://my-api.org/do/something")
        .header("X-My-Header", "foo")   // set a header for the request
        .param("qux", "baz")            // set a query parameter
        .json(&obj)?                    // set the request body (json feature required)
        .send()?;                       // send the request
    
    // Check if the status is a 2XX code.
    if resp.is_success() {
        // Consume the response body as text and print it.
        println!("{}", resp.text()?);
    }
    # Ok(())
    # }
    # #[cfg(not(feature = "json"))]
    # fn main() {}
    let obj = json!({
        "hello": "world",
    });
    
    let resp = attohttpc::post("https://my-api.org/do/something")
        .header("X-My-Header", "foo")
        .param("qux", "baz")
        .json(&obj)?
        .send()?;
    
    if resp.is_success() {
        println!("{}", resp.text()?);
    }
  9. Perform a JSON POST request with attohttpc

    master

    You can perform a POST request with a JSON body and deserialize the response using the .json() method. This requires the json feature flag to be enabled.

    let resp = attohttpc::post("https://my-api.com/do/something")
        .json(&request)?
        .send()?;
    
    if resp.is_success() {
        let response = resp.json()?;
        // ...
    }
    let resp = attohttpc::post("https://my-api.com/do/something").json(&request)?.send()?;
    if resp.is_success() {
        let response = resp.json()?;
        // ...
    }
  10. Capabilities of attohttpc

    master

    The current feature set includes:

    • Query parameters, Request headers, and Bodies.
    • TLS management: adding trusted certificates and disabling verification (supported for both native-tls and rustls).
    • Automatic redirection.
    • Streaming response bodies.
    • Multiple text encodings.
    • Automatic compression/decompression (gzip or deflate).
    • Transfer-Encoding: chunked support.
    • serde/json support.
    • HTTP Proxies: Supports proxying via configuration and the HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables.
    • Happy Eyeballs implementation.
    • Partial support for Authentication.
  11. Load proxy settings from environment variables

    master

    The ProxySettings::from_env() method initializes proxy settings following standard curl/Unix conventions. It looks for the following environment variables (case-insensitive):

    • ALL_PROXY: A fallback proxy for all schemes.
    • HTTP_PROXY: Proxy for http requests. Takes precedence over ALL_PROXY for HTTP.
    • HTTPS_PROXY: Proxy for https requests. Takes precedence over ALL_PROXY for HTTPS.
    • NO_PROXY: A comma-separated list of hostnames or domains that should bypass the proxy. If set to *, all proxies are disabled.

    Note: HTTP_PROXY or HTTPS_PROXY will override the values set by ALL_PROXY for their respective schemes.

    use attohttpc::request::proxy::ProxySettings;
    
    // Loads settings from ALL_PROXY, HTTP_PROXY, HTTPS_PROXY, and NO_PROXY
    let settings = ProxySettings::from_env();
  12. Configure request settings and timeouts

    master

    Adjust request behavior and connection settings:

    • max_redirections(n): Sets the maximum number of redirections (default: 5).
    • follow_redirects(bool): Enables/disables following 3xx redirects (default: true).
    • connect_timeout(duration): Sets the connection timeout (default: 30s).
    • read_timeout(duration): Sets the read timeout (default: 30s).
    • timeout(duration): Sets a timeout for the entire request after connection is established.
    • max_headers(n): Sets the maximum number of headers accepted in responses (default: 100).
    • proxy_settings(settings): Configures proxy settings.
    • allow_compression(bool): (Requires flate2 feature) Signals that the request accepts compression.
    • danger_accept_invalid_certs(bool): (Danger) Accepts any TLS certificate (valid or not).
    • danger_accept_invalid_hostnames(bool): (Danger) Accepts TLS certificates that do not match the hostname.
    use std::time::Duration;
    
    builder
        .connect_timeout(Duration::from_secs(5))
        .read_timeout(Duration::from_secs(10))
        .follow_redirects(true)
        .max_redirections(3);