reqwest

repository·master·Indexed 9 days ago

https://github.com/seanmonstar/reqwest

An ergonomic, batteries-included HTTP client for Rust, version 0.13.4. It supports both asynchronous and blocking modes with built-in support for JSON, multipart, and various TLS backends (rustls by default, with optional native-tls). Key features include connection pooling via a reusable Client, customizable redirect policies, proxy support, cookie storage, and WebAssembly (WASM) compatibility.

Tokens
19.7K
Snippets
69
Records
100
Agent score
95%

What's inside reqwest

  1. Overview of reqwest capabilities

    master

    reqwest is an ergonomic, batteries-included HTTP client for Rust. It supports both asynchronous and blocking clients and provides built-in support for various body types and protocols.

    Key features include:

    • Body Types: Plain text, JSON, urlencoded, and multipart.
    • Redirection: Customizable redirect policies.
    • Proxies: Support for HTTP proxies.
    • TLS/HTTPS: Uses rustls by default, with optional support for system-native TLS.
    • State Management: Includes a Cookie Store.
    • WASM: Supports WebAssembly environments.
  2. Configure TLS backends

    master

    Reqwest handles HTTPS using different TLS implementations depending on the enabled features:

    • Default: Uses rustls.
    • native-tls: Uses the operating system's TLS framework (e.g., Windows and macOS native frameworks, or OpenSSL on Linux). Note that on Linux, OpenSSL must be available on the system for the build to succeed.
    • native-tls-vendored: Compiles a copy of OpenSSL to be used with the client, which can help avoid system-level dependency issues.
  3. Run the Reqwest WASM example locally

    master

    To run the WASM example provided in this repository, you must first install the dependencies using npm and then use the provided serve script. This example demonstrates how to use reqwest within a WebAssembly environment, similar to the wasm-bindgen fetch example.

    Prerequisites

    Ensure you have npm installed on your system.

    Steps to Run

    1. Install dependencies:
      npm install
    2. Build and serve the example:
      npm run serve
    3. Open your browser and navigate to http://localhost:8080 to view the running example.
    npm install
    npm run serve
  4. Set up reqwest for asynchronous JSON requests

    master

    To use reqwest asynchronously with JSON support, add it to your Cargo.toml along with an async runtime like tokio. You must enable the json feature in reqwest to use the .json() method on responses.

    [dependencies]
    reqwest = { version = "0.13", features = ["json"] }
    tokio = { version = "1", features = ["full"] }
  5. How Client and Request headers interact

    master

    When using a Client with default headers, the Client merges its configuration into each request before execution.

    Precedence Rule: If a header is defined in both the Client (via default_headers or user_agent) and the specific RequestBuilder (via .header()), the value provided in the RequestBuilder overwrites the client's default value. The client's default headers are only inserted if the key is currently vacant in the request's header map.

    // If client has default header: "X-Custom: default-value"
    // And you do this:
    let req = client.get("https://example.com")
        .header("X-Custom", "override-value")
        .build()?;
    
    // The resulting request will have: "X-Custom: override-value"
  6. Internal Request Lifecycle: Pending and PendingRequest

    master

    The Pending type is a wrapper around the asynchronous execution of an HTTP request. It implements Future and resolves to a Result<Response, crate::Error>.

    Internally, it manages a PendingRequest which tracks:

    • The HTTP Method and Url.
    • Request headers.
    • The in_flight response future (supporting both standard and HTTP/3 via ResponseFuture).
    • Timeout state, including total_timeout and read_timeout.

    When polled, Pending handles the transition from an active request to either a successful Response or a crate::Error. If a request is redirected, the PendingRequest logic updates the internal URL before returning the final response.

  7. Configure Proxies in reqwest

    master

    System proxies are enabled by default via environment variables:

    • HTTP_PROXY or http_proxy for HTTP connections.
    • HTTPS_PROXY or https_proxy for HTTPS connections.
    • ALL_PROXY or all_proxy for both.

    To override system proxies, add a Proxy to your ClientBuilder using reqwest::Proxy::http("...") or disable them entirely with .no_proxy(). If using SOCKS5 proxies, the socks feature must be enabled.

  8. How Proxy interception and ordering works

    master

    When a reqwest::Client is configured with multiple proxies, it evaluates them in the order they were added via the .proxy() method on the ClientBuilder.

    Important Note on Ordering: If you add a proxy with broad interception rules (like Proxy::all) before a proxy with specific rules, the broad proxy may intercept the request first, preventing the more specific proxy from ever being reached. Always add more specific proxies before general ones if you want specific routing to take precedence.

  9. Use reqwest in WASM environments

    master

    When targeting wasm32, reqwest automatically switches to a WASM-compatible implementation. The async API usage remains largely the same, but certain features are disabled or limited:

    • Disabled features: tls, cookie, blocking, and certain ClientBuilder methods like timeout() or connector_layer().
    • TLS/Cookies: These are provided via the browser environment, meaning they have limited configuration compared to the native implementation.
  10. Configure HTTP redirect policies

    master

    By default, a reqwest::Client automatically handles HTTP redirects with a maximum chain of 10 hops. You can customize this behavior using redirect::Policy when building a client via ClientBuilder::redirect().

    Available policy types:

    • Policy::default(): Follows up to 10 redirects.
    • Policy::limited(max: usize): Follows up to max redirects before returning an error.
    • Policy::none(): Disables all redirect following. The 3xx response will be returned as the Ok result.
    • Policy::custom(closure): Allows for fully manual control over redirect logic.
    let client = reqwest::Client::builder()
        .redirect(reqwest::redirect::Policy::limited(5))
        .build()?;
  11. Configure retry policies with `Builder`

    master

    Use the reqwest::retry::Builder to define how the Client should handle retries. A retry policy consists of a scope (which requests are eligible), a classifier (which specific results trigger a retry), a retry budget (to prevent retry storms), and a per-request limit.

    Key Concepts

    • Scope: Policies are scoped. A policy only applies to requests that fall within its defined scope (e.g., a specific host). This prevents a single retry budget from being exhausted by unrelated requests.
    • Classifier: Determines if a specific request/response pair is Retryable or a Success. Warning: Only retry requests that are idempotent or safe to execute multiple times.
    • Retry Budget: Controls the total amount of extra load retries can add. By default, policies include a budget that permits 20% extra requests. Disabling this is not recommended as it can lead to retry storms.
    • Max Retries per Request: Limits how many times a single logical request is retried, regardless of the overall budget.
    // Example of creating a builder with a custom classifier
    let builder = reqwest::retry::Builder::for_host("api.example.com")
        .classify_fn(|req_rep| {
            match (req_rep.method(), req_rep.status()) {
                (&http::Method::GET, Some(http::StatusCode::SERVICE_UNAVAILABLE)) => {
                    req_rep.retryable()
                },
                _ => req_rep.success()
            }
        });
  12. Enable unstable HTTP/3 support

    master

    The http3 feature is currently unstable and experimental. To use it, you must enable the feature in your Cargo.toml and pass the reqwest_unstable flag to the compiler via environment variables or .cargo/config.

    RUSTFLAGS="--cfg reqwest_unstable" cargo build