Showing preview only (954K chars total). Download the full file or copy to clipboard to get everything.
Repository: seanmonstar/reqwest
Branch: master
Commit: c5e50f004de3
Files: 93
Total size: 918.0 KB
Directory structure:
gitextract_aj92qe_u/
├── .github/
│ ├── FUNDING.yml
│ ├── dependabot.yml
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── examples/
│ ├── blocking.rs
│ ├── connect_via_lower_priority_tokio_runtime.rs
│ ├── form.rs
│ ├── h3_simple.rs
│ ├── json_dynamic.rs
│ ├── json_typed.rs
│ ├── simple.rs
│ ├── tor_socks.rs
│ └── wasm_github_fetch/
│ ├── .gitignore
│ ├── Cargo.toml
│ ├── README.md
│ ├── index.js
│ ├── osv-scanner.toml
│ ├── package.json
│ ├── src/
│ │ └── lib.rs
│ └── webpack.config.js
├── src/
│ ├── async_impl/
│ │ ├── body.rs
│ │ ├── client.rs
│ │ ├── h3_client/
│ │ │ ├── connect.rs
│ │ │ ├── dns.rs
│ │ │ ├── mod.rs
│ │ │ └── pool.rs
│ │ ├── mod.rs
│ │ ├── multipart.rs
│ │ ├── request.rs
│ │ ├── response.rs
│ │ └── upgrade.rs
│ ├── blocking/
│ │ ├── body.rs
│ │ ├── client.rs
│ │ ├── mod.rs
│ │ ├── multipart.rs
│ │ ├── request.rs
│ │ ├── response.rs
│ │ └── wait.rs
│ ├── config.rs
│ ├── connect.rs
│ ├── cookie.rs
│ ├── dns/
│ │ ├── gai.rs
│ │ ├── hickory.rs
│ │ ├── mod.rs
│ │ └── resolve.rs
│ ├── error.rs
│ ├── into_url.rs
│ ├── lib.rs
│ ├── proxy.rs
│ ├── redirect.rs
│ ├── response.rs
│ ├── retry.rs
│ ├── tls.rs
│ ├── util.rs
│ └── wasm/
│ ├── body.rs
│ ├── client.rs
│ ├── mod.rs
│ ├── multipart.rs
│ ├── request.rs
│ └── response.rs
└── tests/
├── badssl.rs
├── blocking.rs
├── brotli.rs
├── ci.rs
├── client.rs
├── connector_layers.rs
├── cookie.rs
├── deflate.rs
├── gzip.rs
├── http3.rs
├── multipart.rs
├── not_tcp.rs
├── proxy.rs
├── redirect.rs
├── retry.rs
├── support/
│ ├── crl.pem
│ ├── delay_layer.rs
│ ├── delay_server.rs
│ ├── error.rs
│ ├── mod.rs
│ ├── not_tcp.rs
│ ├── server.cert
│ ├── server.key
│ └── server.rs
├── timeouts.rs
├── upgrade.rs
├── wasm_simple.rs
└── zstd.rs
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
github: [seanmonstar]
================================================
FILE: .github/dependabot.yml
================================================
version: 2
# Only enable cargo, turn off npm from wasm example
updates:
- package-ecosystem: "github-actions"
# Workflow files stored in the
# default location of `.github/workflows`
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "daily"
# todo: if only this worked, see https://github.com/dependabot/dependabot-core/issues/4009
# only tell us if there's a new 'breaking' change we could upgrade to
# versioning-strategy: increase-if-necessary
# disable regular version updates, security updates are unaffected
open-pull-requests-limit: 0
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
pull_request:
push:
branches:
- master
env:
REQWEST_TEST_BODY_FULL: 1
RUST_BACKTRACE: 1
CARGO_INCREMENTAL: 0
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
jobs:
ci-pass:
name: CI is green
runs-on: ubuntu-latest
needs:
- style
- test
- features
- unstable
- nightly
- msrv_default
- msrv_oldest
- android
- wasm
- docs
steps:
- run: exit 0
style:
name: Check Style
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: cargo fmt -- --check
run: cargo fmt -- --check
- name: temporary workaround - fmt all files under src
# Workaround for rust-lang/cargo#7732
run: cargo fmt -- --check $(find . -name '*.rs' -print)
test:
name: ${{ matrix.name }}
needs: [style]
runs-on: ${{ matrix.os || 'ubuntu-latest' }}
env:
AWS_LC_SYS_PREBUILT_NASM: ${{ matrix.aws_lc_sys_prebuilt_nasm || 0 }}
# The build matrix does not yet support 'allow failures' at job level.
# See `jobs.nightly` for the active nightly job definition.
strategy:
matrix:
name:
- linux / stable
- linux / stable-aarch64-gnu
- linux / beta
# - linux / nightly
- macOS / stable
- windows / stable-x86_64-msvc
- windows / stable-i686-msvc
- windows / stable-aarch64-msvc
- windows / stable-x86_64-gnu
- windows / stable-i686-gnu
- "feat.: default-tls disabled"
- "feat.: rustls"
- "feat.: rustls-no-provider"
- "feat.: native-tls"
- "feat.: default-tls and native-tls"
- "feat.: rustls and rustls-no-provider"
- "feat.: cookies"
- "feat.: blocking"
- "feat.: blocking only"
- "feat.: gzip"
- "feat.: brotli"
- "feat.: deflate"
- "feat.: query"
- "feat.: form"
- "feat.: json"
- "feat.: multipart"
- "feat.: stream"
- "feat.: socks/default-tls"
- "feat.: socks/native-tls"
- "feat.: hickory-dns"
include:
- name: linux / stable
- name: linux / stable-aarch64-gnu
os: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
- name: linux / beta
rust: beta
# - name: linux / nightly
# rust: nightly
- name: macOS / stable
os: macOS-latest
- name: windows / stable-x86_64-msvc
os: windows-latest
target: x86_64-pc-windows-msvc
features: "--features blocking,gzip,brotli,zstd,deflate,query,form,json,multipart,stream"
aws_lc_sys_prebuilt_nasm: 1
- name: windows / stable-i686-msvc
os: windows-latest
target: i686-pc-windows-msvc
features: "--features blocking,gzip,brotli,zstd,deflate,query,form,json,multipart,stream"
aws_lc_sys_prebuilt_nasm: 1
- name: windows / stable-aarch64-msvc
os: windows-11-arm
target: aarch64-pc-windows-msvc
features: "--features blocking,gzip,brotli,zstd,deflate,query,form,json,multipart,stream"
aws_lc_sys_prebuilt_nasm: 1
- name: windows / stable-x86_64-gnu
os: windows-latest
rust: stable-x86_64-pc-windows-gnu
target: x86_64-pc-windows-gnu
features: "--features blocking,gzip,brotli,zstd,deflate,query,form,json,multipart,stream"
package_name: mingw-w64-x86_64-gcc
mingw64_path: "C:\\msys64\\mingw64\\bin"
aws_lc_sys_prebuilt_nasm: 1
- name: windows / stable-i686-gnu
os: windows-latest
rust: stable-i686-pc-windows-gnu
target: i686-pc-windows-gnu
features: "--no-default-features --features blocking,gzip,brotli,zstd,deflate,query,form,json,multipart,stream,native-tls,http2"
package_name: mingw-w64-i686-gcc
mingw64_path: "C:\\msys64\\mingw32\\bin"
- name: "feat.: default-tls disabled"
features: "--no-default-features"
- name: "feat.: rustls"
features: "--no-default-features --features rustls"
- name: "feat.: rustls-no-provider"
features: "--no-default-features --features rustls-no-provider"
- name: "feat.: native-tls"
features: "--features native-tls"
- name: "feat.: rustls and rustls-no-provider"
features: "--features rustls,rustls-no-provider"
- name: "feat.: default-tls and native-tls"
features: "--features native-tls"
- name: "feat.: cookies"
features: "--features cookies"
- name: "feat.: blocking"
features: "--features blocking"
- name: "feat.: blocking only"
features: "--no-default-features --features blocking"
- name: "feat.: gzip"
features: "--features gzip,stream"
- name: "feat.: brotli"
features: "--features brotli,stream"
- name: "feat.: zstd"
features: "--features zstd,stream"
- name: "feat.: deflate"
features: "--features deflate,stream"
- name: "feat.: query"
features: "--features query"
- name: "feat.: form"
features: "--features form"
- name: "feat.: json"
features: "--features json"
- name: "feat.: multipart"
features: "--features multipart"
- name: "feat.: stream"
features: "--features stream"
- name: "feat.: socks/default-tls"
features: "--features socks"
- name: "feat.: socks/native-tls"
features: "--features socks,native-tls"
- name: "feat.: hickory-dns"
features: "--features hickory-dns"
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust || 'stable' }}
targets: ${{ matrix.target }}
- name: Add mingw-w64 to path for i686-gnu
run: |
echo "${{ matrix.mingw64_path }}" >> $GITHUB_PATH
echo "C:\msys64\usr\bin" >> $GITHUB_PATH
if: matrix.mingw64_path
shell: bash
- name: Install x86_64 Clang & NASM
if: ${{ matrix.target == 'x86_64-pc-windows-gnu' }}
run: pacman.exe -Sy --noconfirm mingw-w64-x86_64-clang mingw-w64-x86_64-nasm
shell: bash
- name: Add libclang to the environment for windows x86_64-gnu
run: echo "LIBCLANG_PATH=C:\msys64\mingw64\bin" >> $env:GITHUB_ENV
if: ${{ matrix.target == 'x86_64-pc-windows-gnu' }}
shell: bash
- name: Update gcc
if: matrix.package_name
run: pacman.exe -Sy --noconfirm ${{ matrix.package_name }}
- name: Create Cargo.lock
run: cargo update
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@v2
with:
tool: cargo-nextest
- name: Run tests
run: |
set -euxo pipefail
cargo nextest run --locked --workspace ${{ matrix.features }} ${{ matrix.test-features }}
cargo test --locked --workspace --doc ${{ matrix.features }} ${{ matrix.test-features }}
shell: bash
features:
name: features
needs: [style]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-hack
uses: taiki-e/install-action@cargo-hack
- uses: Swatinem/rust-cache@v2
- name: check --feature-powerset
run: cargo hack --no-dev-deps check --feature-powerset --depth 2 --skip http3,__tls,__rustls,__rustls-aws-lc-rs,native-tls-vendored,trust-dns
env:
RUSTFLAGS: "-D dead_code -D unused_imports"
unstable:
name: "unstable features"
needs: [style]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: 'stable'
- name: Check
run: cargo test --features http3,stream
env:
RUSTFLAGS: --cfg reqwest_unstable
RUSTDOCFLAGS: --cfg reqwest_unstable
docs:
name: Docs
needs: [test]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Check documentation
env:
RUSTDOCFLAGS: --cfg reqwest_unstable -D warnings
run: cargo doc --no-deps --document-private-items --all-features
# Separate build job for nightly because of the missing feature for allowed failures at
# job level. See `jobs.build.strategy.matrix`.
nightly:
name: linux / nightly
needs: [style]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install rust
uses: dtolnay/rust-toolchain@nightly
- name: Check minimal versions
env:
RUSTFLAGS: --cfg reqwest_unstable
# See https://github.com/rust-lang/rust/issues/113152
# We don't force a newer openssl, but a newer one is required for
# this CI runner, because of the version of Ubuntu.
run: |
cargo clean
cargo update -Z minimal-versions
cargo update -p proc-macro2 --precise 1.0.87
cargo update -p aws-lc-rs --precise 1.13.1
cargo update -p aws-lc-sys --precise 0.29.0
cargo update -p openssl-sys
cargo update -p openssl
cargo check
cargo check --all-features
msrv_default:
name: MSRV Default
needs: [style]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Resolve MSRV aware dependencies
run: cargo update
env:
CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS: fallback
# required by rustls-platform-verifier
- name: Install rust (1.71.0)
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.71.0
- uses: Swatinem/rust-cache@v2
- name: Check
run: cargo check
msrv_oldest:
name: MSRV Oldest
needs: [style]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Resolve MSRV aware dependencies
run: cargo update
env:
CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS: fallback
- name: Get MSRV package metadata
id: metadata
run: cargo metadata --no-deps --format-version 1 | jq -r '"msrv=" + .packages[0].rust_version' >> $GITHUB_OUTPUT
- name: Install rust (${{ steps.metadata.outputs.msrv }})
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ steps.metadata.outputs.msrv }}
- uses: Swatinem/rust-cache@v2
- name: Check
run: cargo check --no-default-features --features="http2,charset,native-tls"
android:
name: Android
needs: [style]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install rust
uses: dtolnay/rust-toolchain@stable
with:
target: aarch64-linux-android
- name: Install cargo-ndk
run: cargo install cargo-ndk
- name: Build
run: cargo ndk --target aarch64-linux-android build
wasm:
name: WASM
needs: [style]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Check
run: cargo check --target wasm32-unknown-unknown
- name: Check cookies
run: cargo check --target wasm32-unknown-unknown --features cookies
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Wasm-pack test firefox
run: wasm-pack test --headless --firefox
- name: Wasm-pack test chrome
run: wasm-pack test --headless --chrome
================================================
FILE: .gitignore
================================================
target
Cargo.lock
*.swp
.idea
================================================
FILE: CHANGELOG.md
================================================
## v0.13.2
- Fix HTTP/2 and native-tls ALPN feature combinations.
- Fix HTTP/3 to send h3 ALPN.
- (wasm) fix `RequestBuilder::json()` from override previously set content-type.
## v0.13.1
- Fixes compiling with rustls on Android targets.
# v0.13.0
- **Breaking changes**:
- `rustls` is now the default TLS backend, instead of `native-tls`.
- `rustls` crypto provider defaults to aws-lc instead of _ring_. (`rustls-no-provider` exists if you want a different crypto provider)
- `rustls-tls` has been renamed to `rustls`.
- rustls roots features removed, `rustls-platform-verifier` is used by default.
- To use different roots, call `tls_certs_only(your_roots)`.
- `native-tls` now includes ALPN. To disable, use `native-tls-no-alpn`.
- `query` and `form` are now crate features, disabled by default.
- Long-deprecated methods and crate features have been removed (such as `trust-dns`, which was renamed `hickory-dns` a while ago).
- Many TLS-related methods renamed to improve autocompletion and discovery, but previous name left in place with a "soft" deprecation. (just documented, no warnings)
- For example, prefer `tls_backend_rustls()` over `use_rustls_tls()`.
## v0.12.28
- Fix compiling on Windows if TLS and SOCKS features are not enabled.
## v0.12.27
- Add `ClientBuilder::windows_named_pipe(name)` option that will force all requests over that Windows Named Piper.
## v0.12.26
- Fix sending `Accept-Encoding` header only with values configured with reqwest, regardless of underlying tower-http config.
## v0.12.25
- Add `Error::is_upgrade()` to determine if the error was from an HTTP upgrade.
- Fix sending `Proxy-Authorization` if only username is configured.
- Fix sending `Proxy-Authorization` to HTTPS proxies when the target is HTTP.
- Refactor internal decompression handling to use tower-http.
## v0.12.24
- Refactor cookie handling to an internal middleware.
- Refactor internal random generator.
- Refactor base64 encoding to reduce a copy.
- Documentation updates.
## v0.12.23
- Add `ClientBuilder::unix_socket(path)` option that will force all requests over that Unix Domain Socket.
- Add `ClientBuilder::retry(policy)` and `reqwest::retry::Builder` to configure automatic retries.
- Add `ClientBuilder::dns_resolver2()` with more ergonomic argument bounds, allowing more resolver implementations.
- Add `http3_*` options to `blocking::ClientBuilder`.
- Fix default TCP timeout values to enabled and faster.
- Fix SOCKS proxies to default to port 1080
- (wasm) Add cache methods to `RequestBuilder`.
## v0.12.22
- Fix socks proxies when resolving IPv6 destinations.
## v0.12.21
- Fix socks proxy to use `socks4a://` instead of `socks4h://`.
- Fix `Error::is_timeout()` to check for hyper and IO timeouts too.
- Fix request `Error` to again include URLs when possible.
- Fix socks connect error to include more context.
- (wasm) implement `Default` for `Body`.
## v0.12.20
- Add `ClientBuilder::tcp_user_timeout(Duration)` option to set `TCP_USER_TIMEOUT`.
- Fix proxy headers only using the first matched proxy.
- (wasm) Fix re-adding `Error::is_status()`.
## v0.12.19
- Fix redirect that changes the method to GET should remove payload headers.
- Fix redirect to only check the next scheme if the policy action is to follow.
- (wasm) Fix compilation error if `cookies` feature is enabled (by the way, it's a noop feature in wasm).
## v0.12.18
- Fix compilation when `socks` enabled without TLS.
## v0.12.17
- Fix compilation on macOS.
## v0.12.16
- Add `ClientBuilder::http3_congestion_bbr()` to enable BBR congestion control.
- Add `ClientBuilder::http3_send_grease()` to configure whether to send use QUIC grease.
- Add `ClientBuilder::http3_max_field_section_size()` to configure the maximum response headers.
- Add `ClientBuilder::tcp_keepalive_interval()` to configure TCP probe interval.
- Add `ClientBuilder::tcp_keepalive_retries()` to configure TCP probe count.
- Add `Proxy::headers()` to add extra headers that should be sent to a proxy.
- Fix `redirect::Policy::limit()` which had an off-by-1 error, allowing 1 more redirect than specified.
- Fix HTTP/3 to support streaming request bodies.
- (wasm) Fix null bodies when calling `Response::bytes_stream()`.
## v0.12.15
- Fix Windows to support both `ProxyOverride` and `NO_PROXY`.
- Fix http3 to support streaming response bodies.
- Fix http3 dependency from public API misuse.
## v0.12.14
- Fix missing `fetch_mode_no_cors()`, marking as deprecated when not on WASM.
## v0.12.13
- Add `Form::into_reader()` for blocking `multipart` forms.
- Add `Form::into_stream()` for async `multipart` forms.
- Add support for SOCKS4a proxies.
- Fix decoding responses with multiple zstd frames.
- Fix `RequestBuilder::form()` from overwriting a previously set `Content-Type` header, like the other builder methods.
- Fix cloning of request timeout in `blocking::Request`.
- Fix http3 synchronization of connection creation, reducing unneccesary extra connections.
- Fix Windows system proxy to use `ProxyOverride` as a `NO_PROXY` value.
- Fix blocking read to correctly reserve and zero read buffer.
- (wasm) Add support for request timeouts.
- (wasm) Fix `Error::is_timeout()` to return true when from a request timeout.
## v0.12.12
- (wasm) Fix compilation by not compiler `tokio/time` on WASM.
## v0.12.11
- Fix decompression returning an error when HTTP/2 ends with an empty data frame.
## v0.12.10
- Add `ClientBuilder::connector_layer()` to allow customizing the connector stack.
- Add `ClientBuilder::http2_max_header_list_size()` option.
- Fix propagating body size hint (`content-length`) information when wrapping bodies.
- Fix decompression of chunked bodies so the connections can be reused more often.
## v0.12.9
- Add `tls::CertificateRevocationLists` support.
- Add crate features to enable webpki roots without selecting a rustls provider.
- Fix `connection_verbose()` to output read logs.
- Fix `multipart::Part::file()` to automatically include content-length.
- Fix proxy to internally no longer cache system proxy settings.
## v0.12.8
- Add support for SOCKS4 proxies.
- Add `multipart::Form::file()` method for adding files easily.
- Add `Body::wrap()` to wrap any `http_body::Body` type.
- Fix the pool configuration to use a timer to remove expired connections.
## v0.12.7
- Revert adding `impl Service<http::Request<_>>` for `Client`.
## v0.12.6
- Add support for `danger_accept_invalid_hostnames` for `rustls`.
- Add `impl Service<http::Request<Body>>` for `Client` and `&'_ Client`.
- Add support for `!Sync` bodies in `Body::wrap_stream()`.
- Enable happy eyeballs when `hickory-dns` is used.
- Fix `Proxy` so that `HTTP(S)_PROXY` values take precedence over `ALL_PROXY`.
- Fix `blocking::RequestBuilder::header()` from unsetting `sensitive` on passed header values.
## v0.12.5
- Add `blocking::ClientBuilder::dns_resolver()` method to change DNS resolver in blocking client.
- Add `http3` feature back, still requiring `reqwest_unstable`.
- Add `rustls-tls-no-provider` Cargo feature to use rustls without a crypto provider.
- Fix `Accept-Encoding` header combinations.
- Fix http3 resolving IPv6 addresses.
- Internal: upgrade to rustls 0.23.
## v0.12.4
- Add `zstd` support, enabled with `zstd` Cargo feature.
- Add `ClientBuilder::read_timeout(Duration)`, which applies the duration for each read operation. The timeout resets after a successful read.
## v0.12.3
- Add `FromStr` for `dns::Name`.
- Add `ClientBuilder::built_in_webpki_certs(bool)` to enable them separately.
- Add `ClientBuilder::built_in_native_certs(bool)` to enable them separately.
- Fix sending `content-length: 0` for GET requests.
- Fix response body `content_length()` to return value when timeout is configured.
- Fix `ClientBuilder::resolve()` to use lowercase domain names.
## v0.12.2
- Fix missing ALPN when connecting to socks5 proxy with rustls.
- Fix TLS version limits with rustls.
- Fix not detected ALPN h2 from server with native-tls.
## v0.12.1
- Fix `ClientBuilder::interface()` when no TLS is enabled.
- Fix `TlsInfo::peer_certificate()` being truncated with rustls.
- Fix panic if `http2` feature disabled but TLS negotiated h2 in ALPN.
- Fix `Display` for `Error` to not include its source error.
# v0.12.0
- Upgrade to `hyper`, `http`, and `http-body` v1.
- Add better support for converting to and from `http::Request` and `http::Response`.
- Add `http2` optional cargo feature, default on.
- Add `charset` optional cargo feature, default on.
- Add `macos-system-configuration` cargo feature, default on.
- Change all optional dependencies to no longer be exposed as implicit features.
- Add `ClientBuilder::interface(str)` to specify the local interface to bind to.
- Experimental: disables the `http3` feature temporarily.
## v0.11.27
- Add `hickory-dns` feature, deprecating `trust-dns`.
- (wasm) Fix `Form::text()` to not set octet-stream for plain text fields.
## v0.11.26
- Revert `system-configuration` upgrade, which broke MSRV on macOS.
## v0.11.25
- Fix `Certificate::from_pem_bundle()` parsing.
- Fix Apple linker errors from detecting system proxies.
## v0.11.24
- Add `Certificate::from_pem_bundle()` to add a bundle.
- Add `http3_prior_knowledge()` to blocking client builder.
- Remove `Sync` bounds requirement for `Body::wrap_stream()`.
- Fix HTTP/2 to retry `REFUSED_STREAM` requests.
- Fix instances of converting `Url` to `Uri` that could panic.
## v0.11.23
- Add `Proxy::custom_http_auth(val)` for setting the raw `Proxy-Authorization` header when connecting to proxies.
- Fix redirect to reject locations that are not `http://` or `https://`.
- Fix setting `nodelay` when TLS is enabled but URL is HTTP.
- (wasm) Add `ClientBuilder::user_agent(val)`.
- (wasm) add `multipart::Form::headers(headers)`.
## v0.11.22
- Fix compilation on Windows when `trust-dns` is enabled.
## v0.11.21
- Add automatically detecting macOS proxy settings.
- Add `ClientBuilder::tls_info(bool)`, which will put `tls::TlsInfo` into the response extensions.
- Fix trust-dns resolver from possible hangs.
- Fix connect timeout to be split among multiple IP addresses.
## v0.11.20
- Fix `deflate` decompression back to using zlib, as outlined in the spec.
## v0.11.19
- Add `ClientBuilder::http1_ignore_invalid_headers_in_responses()` option.
- Add `ClientBuilder::http1_allow_spaces_after_header_name_in_responses()` option.
- Add support for `ALL_PROXY` environment variable.
- Add support for `use_preconfigured_tls` when combined with HTTP/3.
- Fix `deflate` decompression from using the zlib decoder.
- Fix `Response::{text, text_with_charset}()` to strip BOM characters.
- Fix a panic when HTTP/3 is used if UDP isn't able to connect.
- Fix some dependencies for HTTP/3.
- Increase MSRV to 1.63.
## v0.11.18
- Fix `RequestBuilder::json()` method from overriding a previously set `content-type` header. An existing value will be left in place.
- Upgrade internal dependencies for rustls and compression.
## v0.11.17
- Upgrade internal dependencies of Experimental HTTP/3 to use quinn v0.9
- (wasm) Fix blob url support
## v0.11.16
- Chore: set MSRV in `Cargo.toml`.
- Docs: fix build on docs.rs
## v0.11.15
- Add `RequestBuilder` methods to split and reconstruct from its parts.
- Add experimental HTTP/3 support.
- Fix `connection_verbose` to log `write_vectored` calls.
- (wasm) Make requests actually cancel if the future is dropped.
## v0.11.14
- Adds `Proxy::no_proxy(url)` that works like the NO_PROXY environment variable.
- Adds `multipart::Part::headers(headers)` method to add custom headers.
- (wasm) Add `Response::bytes_stream()`.
- Perf: several internal optimizations reducing copies and memory allocations.
## v0.11.13
- Add `ClientBuilder::dns_resolver()` option for custom DNS resolvers.
- Add `ClientBuilder::tls_sni(bool)` option to enable or disable TLS Server Name Indication.
- Add `Identity::from_pkcs8_pem()` constructor when using `native-tls`.
- Fix `redirect::Policy::limited(0)` from following any redirects.
## v0.11.12
- Add `ClientBuilder::resolve_to_addrs()` which allows a slice of IP addresses to be specified for a single host.
- Add `Response::upgrade()` to await whether the server agrees to an HTTP upgrade.
## v0.11.11
- Add HTTP/2 keep-alive configuration methods on `ClientBuilder`.
- Add `ClientBuilder::http1_allow_obsolete_multiline_headers_in_responses()`.
- Add `impl Service<Request>` for `Client` and `&'_ Client`.
- (wasm) Add `RequestBuilder::basic_auth()`.
- Fix `RequestBuilder::header` to not override `sensitive` if user explicitly set on a `HeaderValue`.
- Fix rustls parsing of elliptic curve private keys.
- Fix Proxy URL parsing of some invalid targets.
## v0.11.10
- Add `Error::url()` to access the URL of an error.
- Add `Response::extensions()` to access the `http::Extensions` of a response.
- Fix `rustls-native-certs` to log an error instead of panicking when loading an invalid system certificate.
- Fix passing Basic Authorization header to proxies.
## v0.11.9
- Add `ClientBuilder::http09_responses(bool)` option to allow receiving HTTP/0.9 responses.
- Fix HTTP/2 to retry requests interrupted by an HTTP/2 graceful shutdown.
- Fix proxy loading from environment variables to ignore empty values.
## v0.11.8
- Update internal webpki-roots dependency.
## v0.11.7
- Add `blocking::ClientBuilder::resolve()` option, matching the async builder.
- Implement `From<tokio::fs::File>` for `Body`.
- Fix `blocking` request-scoped timeout applying to bodies as well.
- (wasm) Fix request bodies using multipart vs formdata.
- Update internal `rustls` to 0.20.
## v0.11.6
- (wasm) Fix request bodies more.
## v0.11.5
- Add `ClientBuilder::http1_only()` method.
- Add `tls::Version` type, and `ClientBuilder::min_tls_version()` and `ClientBuilder::max_tls_version()` methods.
- Implement `TryFrom<Request>` for `http::Request`.
- Implement `Clone` for `Identity`.
- Fix `NO_PROXY`environment variable parsing to more closely match curl's. Comma-separated entries are now trimmed for whitespace, and `*` is allowed to match everything.
- Fix redirection to respect `https_only` option.
- (wasm) Add `Body::as_bytes()` method.
- (wasm) Fix sometimes wrong conversation of bytes into a `JsValue`.
- (wasm) Avoid dependency on serde-serialize feature.
## v0.11.4
- Add `ClientBuilder::resolve()` option to override DNS resolution for specific domains.
- Add `native-tls-alpn` Cargo feature to use ALPN with the native-tls backend.
- Add `ClientBuilder::deflate()` option and `deflate` Cargo feature to support decoding response bodies using deflate.
- Add `RequestBuilder::version()` to allow setting the HTTP version of a request.
- Fix allowing "invalid" certificates with the `rustls-tls` backend, when the server uses TLS v1.2 or v1.3.
- (wasm) Add `try_clone` to `Request` and `RequestBuilder`
## v0.11.3
- Add `impl From<hyper::Body> for reqwest::Body`.
- (wasm) Add credentials mode methods to `RequestBuilder`.
## v0.11.2
- Add `CookieStore` trait to customize the type that stores and retrieves cookies for a session.
- Add `cookie::Jar` as a default `CookieStore`, easing creating some session cookies before creating the `Client`.
- Add `ClientBuilder::http2_adaptive_window()` option to configure an adaptive HTTP2 flow control behavior.
- Add `ClientBuilder::http2_max_frame_size()` option to adjust the maximum HTTP2 frame size that can be received.
- Implement `IntoUrl` for `String`, making it more convenient to create requests with `format!`.
## v0.11.1
- Add `ClientBuilder::tls_built_in_root_certs()` option to disable built-in root certificates.
- Fix `rustls-tls` glue to more often support ALPN to upgrade to HTTP/2.
- Fix proxy parsing to assume `http://` if no scheme is found.
- Fix connection pool idle reaping by enabling hyper's `runtime` feature.
- (wasm) Add `Request::new()` constructor.
# v0.11.0
- Change `multipart` to be an optional cargo feature.
- Remove deprecated methods.
- Update to Tokio v1.0.
- Update to Bytes v1.0.
- Update to hyper v0.14.
## v0.10.10
- Add `tcp_keepalive` option to `blocking::ClientBuilder`.
- Add `multipart::Part::stream_with_length` constructor, to create a streaming part with a known length.
- Add `ClientBuilder::https_only` option, to allow requiring URLs to be `https`.
- Change default `tcp_keepalive` value to be disabled.
## v0.10.9
- Add `rustls-tls-native-roots`, `rustls-tls-webpki-roots`, and `rustls-tls-manual-roots` Cargo features, to configure which certificate roots to use with rustls.
- Add `ClientBuilder::tcp_keepalive()` method to enable TCP keepalive.
- Add `ClientBuilder::http1_writev()` method to force enable or disable vectored writes.
- Add `Error::is_connect()` method to identify if the error is related to connection-establishment.
- Add `blocking::ClientBuilder::brotli()` method.
- Windows: Update default protocol to HTTP for HTTPS system proxies, when a protocol is not specified.
- (wasm) Add support for Cloudflare workers runtime.
- (wasm) Add `ClientBuilder::default_headers()` method.
- (wasm) Add `RequestBuilder::build()` method.
## v0.10.8
- Add `must_use` to `RequestBuilder` and `ClientBuilder`.
- Fix Windows system proxy detection of Fiddler proxies.
- (wasm) Add `headers` method to `RequestBuilder`.
- (wasm) Add `execute` method to `Client`.
- (wasm) Add `TryFrom<http::Request>` for `Request`.
- (wasm) Fix checking for global `window` to work in non-browser environments.
- (wasm) Fix sending of an empty body when not required.
## v0.10.7
- Add `NO_PROXY` environment variable support.
- Add more `Error::{is_request, is_body, is_decode}` getters.
- Add conversion of `reqwest::ClientBuilder` to `reqwest::blocking::ClientBuilder`.
- Add `headers_mut()` to `reqwest::blocking::Response`.
- (wasm) Add `form()`, `query()`, `multipart` and `bearer_auth()` to `RequestBuilder`.
## v0.10.6
- Changed handling of URLs that don't have `http:` or `https:` schemes, returning an error instead.
- Fixed a potential hyper-rustls feature conflict.
## v0.10.5
- Add `ClientBuilder::pool_idle_timeout` option.
- Add `ClientBuilder::pool_max_idle_per_host` option, deprecate `max_idle_per_host`.
- Add `Response::content_length` for WASM target.
- Enable TCP_NODELAY by default.
- Implement `TryFrom<http::Request>` for `blocking::Request`.
- Implement `TryFrom<http::Request>` for `Request`.
- Removes `From<http::Request>` for `Request`.
- This is technically a breaking change, but was a mistake. It was not valid to convert from an `http::Request` to a `reqwest::Request` in an infallible fashion. It would panic if the conversion was not possible. Instead, the implementation has been changed to `TryFrom` to indicate it could fail.
## v0.10.4
- Add `trust-dns` optional feature to change DNS resolver.
- Add `bytes()` method to `reqwest::blocking::Response`.
- Add `buffer()` method to `reqwest::blocking::Body`.
- Implement `From<http::Request>` for `reqwest::Request`.
## v0.10.3
- Upgrade internal `rustls` version.
## v0.10.2
- Add Brotli support, enabled with the optional `brotli` feature.
- Add `Client::use_preconfigured_tls(tls_connector)` allowing manual configuration of TLS options.
- Implement `Default` for blocking `Client`, `ClientBuilder`, and `multipart::Form`.
- (wasm) Add `Response::error_for_status()` method.
- (wasm) Add `Response::json()` method.
- (wasm) Implement `Default` for `Client` and `ClientBuilder`.
## v0.10.1
- Add `socks` optional feature to support SOCKS5 proxies.
- Add `RequestBuilder::timeout()` to configure a timeout for a single request, instead of using the client's timeout.
- Add `ClientBuilder::connection_verbose()` option to enable verbose IO logs.
- (wasm) Add `RequestBuilder::fetch_mode_no_cors()` option.
- (wasm) Add `Response::url()` getter method.
# v0.10.0
- Add `std::future::Future` support.
- Add `wasm32-unknown-unknown` support (with fewer features).
- Add ability to pass async `Response` as the `body` of another `Request`.
- Add `Body::as_bytes()` method.
- Add `Response::bytes_stream()` method to get body as an `impl Stream`.
- Add `Request::try_clone()` method.
- Change default `Client` API to async. The previous blocking client API is available at `reqwest::blocking`.
- Change to no longer send a default `User-Agent` header. Add one via `ClientBuilder::user_agent()`.
- Change to enable system/environment proxy detection by default.
- Change `default-tls` feature to only include `ClientBuilder` options that both `native-tls` and `rustls` support.
- Change default feature set to reduce unnecessary dependencies. Most features are disabled by default:
- `blocking`: The `reqwest::blocking` (synchronous) client API.
- `cookies`: Cookie store support.
- `gzip`: Automatic response body decompression.
- `json`: Request and response JSON body methods.
- `stream`: `futures::Stream` support.
- Change `Error` internal design, removing several `Error::is_*` inspector methods.
- Change Redirect API:
- Renamed types to be part of the `redirect` module (for example, `reqwest::RedirectPolicy` is now `reqwest::redirect::Policy`).
- Removed `loop_detected` and `too_many_redirect` methods from `redirect::Attempt`, replaced with a generic `error` method.
- The default policy no longer specifically looks for redirect loops (but they should be caught by the maximum limit).
- Fix checking `HTTP_PROXY` environment variable if it the environment is from a CGI script.
- Fix removal of username/password of parsed proxy URL.
- Update `url` to v2.0.
- Update `hyper` to v0.13.
- Update `http` to v0.2.
## v0.9.19
- Add `ClientBuilder::use_sys_proxy()` to enable automatic detect of HTTP proxies configured on the system.
- Add `ClientBuilder::no_proxy()` to disable system proxies. This is the default for 0.9, but will change to detecting system proxies by default in 0.10.
- Add support for streaming request bodies in the async client.
- Add `async::Response::text()` that returns a `Future` of the full body decoded to a `String`.
- Add `Clone` for `Certificate`.
## v0.9.18
- Fix `Cookie` headers to no longer send as percent-encoded (instead, exactly as sent by the server).
## v0.9.17
- Fix `Cookie` headers to not include attributes from the `Set-Cookie` (like `HttpOnly`, `Secure`, etc.)
## v0.9.16
- Add `Response::text_with_charset()` to allow setting the default charset to decode.
- Add `Error::source()` implementation.
- Add `async::ClientBuilder::timeout()` option, will timeout the connect, request, and response body futures.
- Fix gzip + chunked transfer encoding issue preventing connection reuse.
- Fix `RequestBuilder::query()` to not add just `"?"` if the encoded query is empty.
- Fix including new cookie headers when response is a redirect.
## v0.9.15
- Fix sending of "appended" request headers.
## v0.9.14
- Add optional support for SOCKS5 proxies, by enabling the `socks5` cargo feature.
- Add Cookie Store support to `Client`, automatically handling cookies for a session.
- Add `ClientBuilder::cookie_store(enable: bool)` method to enable a cookie store that persists across requests.
- Add `Response::cookies()` accessor that allows iterating over response cookies.
- Fix `Proxy` to check the URL for a username and password.
## v0.9.13
### Fixes
- Fix panic on some invalid `Location` headers during redirects (error is logged and redirect response is returned instead).
- Fix instance when server notices streaming request body is complete before reqwest does.
## v0.9.12
### Features
- Add `ClientBuilder::tcp_nodelay()` to allow disabling Nagle's algorithm.
- Add `ClientBuilder::max_idle_per_host()` to allow reducing the number of idle pooled connections.
- Add `RequestBuilder::bearer_auth()` method to async builder.
### Fixes
- Fix capitalization error in async `RequestBuilder::basic_auth()`.
- Fix ALPN causing issues when using a Proxy.
## v0.9.11
### Features
- Add `multipart::Form::percent_encode_noop()` to allow for servers which don't support percent encoding of parameters.
- Add `ClientBuilder::http1_title_case_headers()` to force request headers to use Title-Case.
- Add `ClientBuilder::connect_timeout()` to allow setting only a connect timeout.
## v0.9.10
### Features
- Add `ClientBuilder::local_address()` to bind to a local IP address.
- Add `Response::error_for_status_ref()` to return an `Error` while borrowing a `Response`.
### Fixes
- Fix `Identity::from_pem` with `rustls-tls` backend when using RSA private keys.
## v0.9.9
### Features
- Add `ClientBuilder::h2_prior_knowledge()` option to force HTTP2.
- Add `Response::content_length()` to get the content-length of a response.
- Enable ALPN h2 with the rustls-tls backend.
## v0.9.8
### Fixes
- Revert default DNS resolver to `getaddrinfo` in a threadpool. There is now a `trust-dns` optional feature to enable the Trust-DNS resolver.
- Detect `Certificate` and `Identity` errors at construction time.
## v0.9.7
### Fixes
- Fix DNS resolver on Android (reverted back to `getaddrinfo`).
- Fix sending unicode `filename`s in `multipart/form-data` requests.
## v0.9.6
### Features
- Add `Proxy::basic_auth` method to support proxy authorization.
- Add `rustls-tls` optional feature to use rustls instead of native-tls.
- Add `try_clone` method to `Request` and `RequestBuilder`.
- Add `reqwest::async::multipart` support, similar to the synchronous API.
- Adds `default-tls-vendored` optional feature to vendor OpenSSL.
### Fixes
- Fix panic from top-level `reqwest::get` if client builder fails to build.
- Removed timeout waiting for `reqwest::Client` runtime to startup.
- Fix `RequestBuilder::headers` to properly append extra headers of the same name.
### Performance
- Replaced DNS threadpool using `getaddrinfo` with a non-blocking DNS resolver.
## v0.9.5
### Features
- Adds `Response::remote_addr()` method to check the address of the connection used.
- Adds `default-tls` crate feature, enabled by default, which allows users to *disable* TLS.
## v0.9.4
### Features
- Adds `percent_encoding_path_segment` and `percent_encoding_attr_char` configuration to `multipart::Form`.
### Fixes
- Reverts `multipart::Form` default percent encoding format to `path-segment`.
## v0.9.3
### Features
- Adds `multipart::Part::bytes()` to create a part of raw bytes.
- Adds constructors for `Response` to help with testing.
### Fixes
- Properly percent-encoding more illegal characters in multipart filenames.
- Ensure timed out requests cancel the associated async task.
## v0.9.2
### Fixes
- Fix panic when `Location` header has UTF-8 characters.
## v0.9.1
### Fixes
- Fix large request bodies failing because of improper handling of backpressure.
- Remove body-related headers when redirect changes a `POST` into a `GET`.
- Reduce memory size of `Response` and `Error` significantly.
# v0.9.0
### Features
- Upgrade to `tokio` 0.1.
- Upgrade to `hyper` 0.12.
- Upgrade to `native-tls` 0.2.
- Add `ClientBuilder::danger_accept_invalid_certs(bool)` to disable
certificate verification.
- Add `RequestBuilder::bearer_auth(token)` to ease sending bearer tokens.
- Add `headers()` and `headers_mut()` to `multipart::Part` to allow sending
extra headers for a specific part.
- Moved `request::unstable::async` to `reqwest::async`.
### Fixes
- Fix panicking when passing a `Url` with a `file://` scheme. Instead, an
`Error` is returned.
### Breaking Changes
- Changed `ClientBuilder::danger_disable_hostname_verification()`
to `ClientBuilder::danger_accept_invalid_hostnames(bool)`.
- Changed `ClientBuilder` to be a by-value builder instead of by-ref.
For single chains of method calls, this shouldn't affect you. For code that
conditionally uses the builder, this kind of change is needed:
```rust
// Old
let mut builder = ClientBuilder::new();
if some_val {
builder.gzip(false);
}
let client = builder.build()?;
// New
let mut builder = ClientBuilder::new();
if some_val {
builder = builder.gzip(false);
}
let client = builder.build()?;
```
- Changed `RequestBuilder` to be a by-value builder of by-ref.
See the previous note about `ClientBuilder` for affected code and
how to change it.
- Removed the `unstable` cargo-feature, and moved `reqwest::unstable::async`
to `reqwest::async`.
- Changed `multipart::Part::mime()` to `mime_str()`.
```rust
// Old
let part = multipart::Part::file(path)?
.mime(mime::TEXT_PLAIN);
// New
let part = multipart::Part::file(path)?
.mime_str("text/plain")?;
```
- The upgrade to `hyper` 0.12 means a temporary removal of the typed headers.
The `RequestBuilder` has simple methods to set headers using strings, which
can work in most places.
```rust
// Old
client
.get("https://hyper.rs")
.header(UserAgent::new("hallo"))
.send()?;
// New
client
.get("https://hyper.rs")
.header("user-agent", "hallo")
.send()?;
```
To ease the transition, there is a `hyper-011` cargo-feature that can be
enabled.
```toml
[dependencies]
reqwest = { version = "0.9", features = ["hyper-011"] }
```
And then usage:
```rust
client
.get("https://hyper.rs")
.header_011(reqwest::hyper_011::header::UserAgent::new("hallo"))
.send()?;
```
## v0.8.8
- Fix docs.rs/reqwest build.
## v0.8.7
### Fixes
- Send an extra CRLF at the end of multipart requests, since some servers expect it.
- Removed internal dependency on `tokio-proto`, which removed unsafe `small-vec`
dependency.
## v0.8.6
### Features
- Add `RedirectAttempt::status` to check status code that triggered redirect.
- Add `RedirectPolicy::redirect` method publicly, to allow composing policies.
## v0.8.5
### Features
- Try to auto-detect encoding in `Response::text()`.
- Add `Certificate::from_pem` to load PEM encoded client certificates.
- Allow unsized types in `query`, `form`, and `json`.
- Add `unstable::async::RequestBuilder::query`, mirroring the stable builder method.
## v0.8.4
### Features
- Add `RequestBuilder::query` to easily adjust query parameters of requests.
## v0.8.3
### Features
- Upgrades internal log crate usage to v0.4
## v0.8.2
### Fixes
- Enable hyper's `no_proto` config, fixing several bugs in hyper.
## v0.8.1
### Features
- Add `ClientBuilder::default_headers` to set headers used for every request.
- Add `async::ClientBuilder::dns_threads` to set number of threads use for DNS.
- Add `Response::text` as shortcut to read the full body into a `String`.
- Add `Response::copy_to` as shortcut for `std::io::copy`.
# v0.8.0
### Features
- Client TLS Certificates (#43)
- GZIP decoding has been added to the **async** Client (#161)
- `ClientBuilder` and `RequestBuilder` hold their errors till consumed (#189)
- `async::Response::body()` now returns a reference to the body instead of consuming the `Response`
- A default timeout for `reqwest::Client` is used set to 30 seconds (#181)
### Breaking Changes
- `Client::new` no longer returns a `Result`.
To handle any panics that come from `Client::new`, the builder can be used instead.
- `ClientBuilder` and `RequestBuilder` hold their errors till consumed (#189).
This means a bunch of `?` will be going away, but means using the builders will be far easier now. Any error encountered inside the builders will now be returned when the builder is consumed.
To get errors back immediately, the `Request` type can be used directly, by building pieces separately and calling setters.
- `async::Response::body()` now returns a reference to the body instead of consuming the `Response`.
- A default timeout for `reqwest::Client` is used set to 30 seconds (#181)
For uses where the timeout is too short, it can be changed on the `ClientBuilder`, using the `timeout` method. Passing `None` will disable the timeout, reverting to the pre-0.8 behavior.
## v0.7.3
### Features
- `Proxy::custom(fn)` to allow dynamically picking a proxy URL
### Fixes
- fix occasional panic when program exits while `Client` or `Response` are dropping.
## v0.7.2
### Fixes
- fix a panic when redirecting and a `Authorization<Basic>` header was added (https://github.com/seanmonstar/reqwest/commit/cf246d072badd9b31b487e7a0b00490e4cc9584f)
- fix redirects so that a GET will follow 307/308 responses (https://github.com/seanmonstar/reqwest/commit/2d11a4bd7167e1bf3a35b62f5aeb36d5d294e56e)
## v0.7.1
### Fixes
- fix remove accidental `println`s in the sending of a body
- some documentation improvements
# v0.7.0
### Features
- Proxy support (#30)
- Self-signed TLS certificates (#97)
- Disabling TLS hostname validation (#89)
- A `Request` type that can be used instead of the `RequestBuilder` (#85)
- Add `Response::error_for_status()` to easily convert 400 and 500 status responses into an `Error` (#98)
- Upgrade hyper to 0.11
- Synchronous `Client` remains.
- Timeouts now affect DNS and socket connection.
- Pool much better at evicting sockets when they die.
- An `unstable` Cargo feature to enable `reqwest::unstable::async`.
- A huge docs improvement!
### Fixes
- Publicly exports `RedirectAction` and `RedirectAttempt`
- `Error::get_ref` returns `Error + Send + Sync`
### Breaking Changes
- hyper has been upgraded to 0.11, so `header`, `StatusCode`, and `Method` have breaking changes.
- `mime` has been upgraded to 0.3, with a very different API.
- All configuration methods have been removed from the `Client`, and moved to the `ClientBuilder`.
- The `HttpVersion` type was completely removed.
- `Error::cause()` now returns `Error::get_ref().cause()`.
- All methods on `Client` that start a `RequestBuilder` now return a `Result` immediately, instead of delaying the URL parse error for later.
- The `RequestBuilder` methods all take `&mut self`, instead of moving the builder, and return `&mut Self`. (This shouldn't actually affect most people who are building a request in a single chain.)
- `Response::status()` returns a `StatusCode` instead of `&StatusCode`.
## v0.6.2
### Features
- adds `Client::referer(bool)` option to disable setting the `Referer` header during redirects (https://github.com/seanmonstar/reqwest/commit/bafcd7ae6fc232856dd6ddb8bf5b20dbbbfe0bc9)
### Fixes
- fixes filtering sensitive headers during redirects (https://github.com/seanmonstar/reqwest/issues/10)
- fixes sending of the Referer to an HTTP site when coming from HTTPS, and removes username and fragment explicitly (https://github.com/seanmonstar/reqwest/commit/d8696045b4c6bc4d9e33789cff6a9e1fa75462d7)
- documentation updates
## v0.6.1
### Features
- adds `Error::get_ref` to get the underlying error that may have occurred. Includes a `'static` bounds, which allows for downcasting (as opposed to `Error::cause`).
# v0.6.0
### Features
- Upgraded to serde `1.0`
- Added a `url` [method](https://docs.rs/reqwest/0.6.0/reqwest/struct.Error.html#method.url) to `Error`, which returns a possible associated `Url` that occurred with this error.
- Added `req.basic_auth(user, optional_pass)` [method](https://docs.rs/reqwest/0.6.0/reqwest/struct.RequestBuilder.html#method.basic_auth) to ease using `Basic` authentication.
### Breaking Changes
- The publicly exposed peer dependency serde was upgraded. It is now `serde@1.0`. Mismatched version will give a compiler error that a serde trait is not implemented.
- `Error` is no longer an `enum`, but an opaque struct. Details about it can be checked with `std::error::Error::cause()`, and methods on `reqwest::Error` include `is_http()`, `is_serialization()`, and `is_redirect()`.
- `RedirectPolicy::custom` receives different arguments, and returns different values. See the [docs](https://docs.rs/reqwest/0.6.0/reqwest/struct.RedirectPolicy.html#method.custom) for an example.
## v0.5.2
### Fixes
- fix panic with Gzip decoder on an empty body (https://github.com/seanmonstar/reqwest/issues/82)
## v0.5.1
### Features
- add `Clone` implementation for `Client`
# v0.5.0
### Features
- Automatic GZIP decoding: By default, `Client` will try to decode any responses that appear to be gzip encoded (based on headers). This can be disabled via `client.gzip(false)` (https://github.com/seanmonstar/reqwest/commit/ab5e477a123319efd4b17f3666b41b44ec244bee)
- Specify a timeout for requests using `client.timeout(duration)`. (https://github.com/seanmonstar/reqwest/commit/ec049fefbae7355f6e4ddbbc7ebedcadb30e1e04)
- Request bodies with a known length can be constructed with `Body::sized()` (https://github.com/seanmonstar/reqwest/commit/82f1877d4b6cba2fac432670ec306160aee5c501)
- Add `Client.put`, `Client.patch`, and `Client.delete` convenience methods (https://github.com/seanmonstar/reqwest/commit/c37b8aa0338ac4142763d206c6df79856915056d, https://github.com/seanmonstar/reqwest/commit/4d6582d22b23c27927e481a9c8a83ad08cfd1a2a, https://github.com/seanmonstar/reqwest/commit/a3983f3122b2d1495ea36bb5a8fd019a7605ae56)
- Add `reqwest::mime` (https://github.com/seanmonstar/reqwest/commit/0615c6d65e03ba9cb5364169c9e74f4f2a91554b)
### Breaking Changes
The only breaking change is a behavioral one, all programs should still compile without modification. The automatic GZIP decoding could interfere in cases where a user was expecting the GZIP bytes, either to save to a file or decode themselves. To restore this functionality, set `client.gzip(false)`.
# v0.4.0
- updated to serde 0.9
# v0.3.0
- updated to hyper 0.10
# v0.2.0
### Features
- add `Response.json()` method (https://github.com/seanmonstar/reqwest/commit/2d10ecc99e2aaed66616294baaf65380b446e1c6)
- add `RedirectPolicy` (https://github.com/seanmonstar/reqwest/commit/e92b3e862a1a94c0b4173a7d49a315bc121da31e)
- set an `Accept: */*` header by default if no `Accept` header is set (https://github.com/seanmonstar/reqwest/commit/559ae8011a2c098f4fe1821ec1d3444a46f4bf5e)
- add support for 307 and 308 redirects (https://github.com/seanmonstar/reqwest/commit/a54447c1d9c75dab639333265f51a91a43e99c2e)
- implement `Sync` for `Client`, and `Send` for `RequestBuilder` and `Response` (https://github.com/seanmonstar/reqwest/commit/d18a53b3fcc81c4a60875755c8e95d777a343319)
- implement `Send` for `Error` (https://github.com/seanmonstar/reqwest/commit/20b161096e67d22c962e69b2656ae9741ac73c25)
- implement `std::fmt::Debug` for all public types (https://github.com/seanmonstar/reqwest/commit/d624b0ef29020c6085ec94651a990f58ccd684e2)
### Breaking Changes
- `Error::Serialize` now has a `Box<StdError + Send + Sync>` instead of `Box<StdError>`
- `RequestBuilder` no longer has an associated lifetime (was `RequestBuilder<'a>`)
# v0.1.0
Initial release: http://seanmonstar.com/post/153221119046/introducing-reqwest
================================================
FILE: Cargo.toml
================================================
[package]
name = "reqwest"
version = "0.13.2"
description = "higher level HTTP client library"
keywords = ["http", "request", "client"]
categories = ["web-programming::http-client", "wasm"]
repository = "https://github.com/seanmonstar/reqwest"
documentation = "https://docs.rs/reqwest"
authors = ["Sean McArthur <sean@seanmonstar.com>"]
readme = "README.md"
license = "MIT OR Apache-2.0"
edition = "2021"
rust-version = "1.64.0"
autotests = true
include = [
"README.md",
"Cargo.toml",
"LICENSE-APACHE",
"LICENSE-MIT",
"src/**/*.rs"
]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs", "--cfg", "reqwest_unstable"]
targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"]
[package.metadata.playground]
features = [
"blocking",
"cookies",
"query",
"form",
"json",
"multipart",
]
[features]
default = ["default-tls", "charset", "http2", "system-proxy"]
default-tls = ["rustls"]
http2 = ["dep:h2", "hyper/http2", "hyper-util/http2", "hyper-rustls?/http2"]
rustls = ["__rustls-aws-lc-rs", "dep:rustls-platform-verifier", "__rustls"]
rustls-no-provider = ["dep:rustls-platform-verifier", "__rustls"]
native-tls = ["__native-tls", "__native-tls-alpn"]
native-tls-no-alpn = ["__native-tls"]
native-tls-vendored = ["__native-tls", "native-tls-crate?/vendored", "__native-tls-alpn"]
native-tls-vendored-no-alpn = ["__native-tls", "native-tls-crate?/vendored"]
blocking = ["dep:futures-channel", "futures-channel?/sink", "dep:futures-util", "futures-util?/io", "futures-util?/sink", "tokio/sync"]
charset = ["dep:encoding_rs", "dep:mime"]
cookies = ["dep:cookie_crate", "dep:cookie_store"]
gzip = ["tower-http/decompression-gzip"]
brotli = ["tower-http/decompression-br"]
zstd = ["tower-http/decompression-zstd"]
deflate = ["tower-http/decompression-deflate"]
query = ["dep:serde", "dep:serde_urlencoded"]
form = ["dep:serde", "dep:serde_urlencoded"]
json = ["dep:serde", "dep:serde_json"]
multipart = ["dep:mime_guess", "dep:futures-util"]
hickory-dns = ["dep:hickory-resolver", "dep:once_cell"]
stream = ["tokio/fs", "dep:futures-util", "dep:tokio-util", "dep:wasm-streams"]
socks = []
# Use the system's proxy configuration.
system-proxy = ["hyper-util/client-proxy-system"]
# Experimental HTTP/3 client.
http3 = ["rustls", "dep:h3", "dep:h3-quinn", "dep:quinn", "tokio/macros"]
# Internal (PRIVATE!) features used to aid testing.
# Don't rely on these whatsoever. They may disappear at any time.
# Enables common types used for TLS. Useless on its own.
__tls = ["dep:rustls-pki-types", "tokio/io-util"]
# Enables common rustls code.
__rustls = ["dep:hyper-rustls", "dep:tokio-rustls", "dep:rustls", "__tls"]
__rustls-aws-lc-rs = ["hyper-rustls?/aws-lc-rs", "tokio-rustls?/aws-lc-rs", "rustls?/aws-lc-rs", "quinn?/rustls-aws-lc-rs"]
# Enables common native-tls code.
__native-tls = ["dep:hyper-tls", "dep:native-tls-crate", "__tls", "dep:tokio-native-tls"]
__native-tls-alpn = ["native-tls-crate?/alpn", "hyper-tls?/alpn"]
[dependencies]
base64 = "0.22"
http = "1.1"
url = "2.4"
bytes = "1.2"
futures-core = { version = "0.3.28", default-features = false }
futures-util = { version = "0.3.28", default-features = false, optional = true }
sync_wrapper = { version = "1.0", features = ["futures"] }
# Optional deps...
serde = { version = "1.0", optional = true }
## query/form
serde_urlencoded = { version = "0.7.1", optional = true }
## json
serde_json = { version = "1.0", optional = true }
## multipart
mime_guess = { version = "2.0", default-features = false, optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
encoding_rs = { version = "0.8", optional = true }
http-body = "1"
http-body-util = "0.1.2"
hyper = { version = "1.1", features = ["http1", "client"] }
hyper-util = { version = "0.1.12", features = ["http1", "client", "client-legacy", "client-proxy", "tokio"] }
h2 = { version = "0.4", optional = true }
log = "0.4.17"
percent-encoding = "2.3"
tokio = { version = "1.0", default-features = false, features = ["net", "time"] }
tower = { version = "0.5.2", default-features = false, features = ["retry", "timeout", "util"] }
tower-service = "0.3"
tower-http = { version = "0.6.8", default-features = false, features = ["follow-redirect"] }
pin-project-lite = "0.2.11"
# Optional deps...
rustls-pki-types = { version = "1.9.0", features = ["std"], optional = true }
mime = { version = "0.3.16", optional = true }
# native-tls
hyper-tls = { version = "0.6", optional = true }
native-tls-crate = { version = "0.2.10", optional = true, package = "native-tls" }
tokio-native-tls = { version = "0.3.0", optional = true }
# default rustls
hyper-rustls = { version = "0.27.0", default-features = false, optional = true, features = ["http1", "tls12"] }
rustls = { version = "0.23.4", optional = true, default-features = false, features = ["std", "tls12"] }
tokio-rustls = { version = "0.26", optional = true, default-features = false, features = ["tls12"] }
rustls-platform-verifier = { version = "0.6", optional = true }
## cookies
cookie_crate = { version = "0.18.0", package = "cookie", optional = true }
cookie_store = { version = "0.22.0", optional = true }
## stream
tokio-util = { version = "0.7.9", default-features = false, features = ["io"], optional = true }
## hickory-dns
hickory-resolver = { version = "0.25", optional = true, features = ["tokio"] }
once_cell = { version = "1.18", optional = true }
# HTTP/3 experimental support
h3 = { version = "0.0.8", optional = true }
h3-quinn = { version = "0.0.10", optional = true }
quinn = { version = "0.11.1", default-features = false, features = ["runtime-tokio"], optional = true }
futures-channel = { version = "0.3", optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
env_logger = "0.10"
hyper = { version = "1.1.0", default-features = false, features = ["http1", "http2", "client", "server"] }
hyper-util = { version = "0.1.12", features = ["http1", "http2", "client", "client-legacy", "server-auto", "server-graceful", "tokio"] }
serde = { version = "1.0", features = ["derive"] }
flate2 = "1.0.13"
brotli_crate = { package = "brotli", version = "8" }
zstd_crate = { package = "zstd", version = "0.13" }
doc-comment = "0.3"
tokio = { version = "1.0", default-features = false, features = ["macros", "rt-multi-thread"] }
futures-util = { version = "0.3.28", default-features = false, features = ["std", "alloc"] }
# wasm
[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = "0.3.77"
wasm-bindgen = "0.2.89"
wasm-bindgen-futures = "0.4.18"
wasm-streams = { version = "0.5", optional = true }
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3.28"
features = [
"AbortController",
"AbortSignal",
"Headers",
"Request",
"RequestInit",
"RequestMode",
"Response",
"Window",
"FormData",
"Blob",
"BlobPropertyBag",
"ServiceWorkerGlobalScope",
"RequestCredentials",
"File",
"ReadableStream",
"RequestCache"
]
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen = { version = "0.2.89", features = ["serde-serialize"] }
wasm-bindgen-test = "0.3"
[dev-dependencies]
tower = { version = "0.5.2", default-features = false, features = ["limit"] }
num_cpus = "1.0"
libc = "0"
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(reqwest_unstable)'] }
[[example]]
name = "blocking"
path = "examples/blocking.rs"
required-features = ["blocking"]
[[example]]
name = "json_dynamic"
path = "examples/json_dynamic.rs"
required-features = ["json"]
[[example]]
name = "json_typed"
path = "examples/json_typed.rs"
required-features = ["json"]
[[example]]
name = "tor_socks"
path = "examples/tor_socks.rs"
required-features = ["socks"]
[[example]]
name = "form"
path = "examples/form.rs"
required-features = ["form"]
[[example]]
name = "simple"
path = "examples/simple.rs"
[[example]]
name = "h3_simple"
path = "examples/h3_simple.rs"
required-features = ["http3", "rustls"]
[[example]]
name = "connect_via_lower_priority_tokio_runtime"
path = "examples/connect_via_lower_priority_tokio_runtime.rs"
[[test]]
name = "blocking"
path = "tests/blocking.rs"
required-features = ["blocking"]
[[test]]
name = "cookie"
path = "tests/cookie.rs"
required-features = ["cookies"]
[[test]]
name = "gzip"
path = "tests/gzip.rs"
required-features = ["gzip", "stream"]
[[test]]
name = "brotli"
path = "tests/brotli.rs"
required-features = ["brotli", "stream"]
[[test]]
name = "zstd"
path = "tests/zstd.rs"
required-features = ["zstd", "stream"]
[[test]]
name = "deflate"
path = "tests/deflate.rs"
required-features = ["deflate", "stream"]
[[test]]
name = "multipart"
path = "tests/multipart.rs"
required-features = ["multipart"]
================================================
FILE: LICENSE-APACHE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016 Sean McArthur
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: LICENSE-MIT
================================================
Copyright (c) 2016-2026 Sean McArthur
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
# reqwest
[](https://crates.io/crates/reqwest)
[](https://docs.rs/reqwest)
[](./LICENSE-APACHE)
[](https://github.com/seanmonstar/reqwest/actions/workflows/ci.yml)
An ergonomic, batteries-included HTTP Client for Rust.
- Async and blocking `Client`s
- Plain bodies, JSON, urlencoded, multipart
- Customizable redirect policy
- HTTP Proxies
- HTTPS via rustls (or optionally, system-native TLS)
- Cookie Store
- WASM
## Example
This asynchronous example uses [Tokio](https://tokio.rs) and enables some
optional features, so your `Cargo.toml` could look like this:
```toml
[dependencies]
reqwest = { version = "0.13", features = ["json"] }
tokio = { version = "1", features = ["full"] }
```
And then the code:
```rust,no_run
use std::collections::HashMap;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::get("https://httpbin.org/ip")
.await?
.json::<HashMap<String, String>>()
.await?;
println!("{resp:#?}");
Ok(())
}
```
## Commercial Support
For private advice, support, reviews, access to the maintainer, and the like, reach out for [commercial support][sponsor].
## Requirements
By default, Reqwest uses [rustls](https://github.com/rustls/rustls), but when the `native-tls` feature is enabled
it will use the operating system TLS framework if available, meaning Windows and macOS.
On Linux, it will use the available OpenSSL (see https://docs.rs/openssl for supported versions and more details)
or fail to build if not found. Alternatively you can enable the `native-tls-vendored` feature to compile a copy of OpenSSL.
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.
## Sponsors
Support this project by becoming a [sponsor][].
[sponsor]: https://seanmonstar.com/sponsor
================================================
FILE: examples/blocking.rs
================================================
//! `cargo run --example blocking --features=blocking`
#![deny(warnings)]
fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
// Some simple CLI args requirements...
let url = match std::env::args().nth(1) {
Some(url) => url,
None => {
println!("No CLI URL provided, using default.");
"https://hyper.rs".into()
}
};
eprintln!("Fetching {url:?}...");
// reqwest::blocking::get() is a convenience function.
//
// In most cases, you should create/build a reqwest::Client and reuse
// it for all requests.
let mut res = reqwest::blocking::get(url)?;
eprintln!("Response: {:?} {}", res.version(), res.status());
eprintln!("Headers: {:#?}\n", res.headers());
// copy the response body directly to stdout
res.copy_to(&mut std::io::stdout())?;
Ok(())
}
================================================
FILE: examples/connect_via_lower_priority_tokio_runtime.rs
================================================
#![deny(warnings)]
// This example demonstrates how to delegate the connect calls, which contain TLS handshakes,
// to a secondary tokio runtime of lower OS thread priority using a custom tower layer.
// This helps to ensure that long-running futures during handshake crypto operations don't block other I/O futures.
//
// This does introduce overhead of additional threads, channels, extra vtables, etc,
// so it is best suited to services with large numbers of incoming connections or that
// are otherwise very sensitive to any blocking futures. Or, you might want fewer threads
// and/or to use the current_thread runtime.
//
// This is using the `tokio` runtime and certain other dependencies:
//
// `tokio = { version = "1", features = ["full"] }`
// `num_cpus = "1.0"`
// `libc = "0"`
// `pin-project-lite = "0.2"`
// `tower = { version = "0.5", default-features = false}`
#[cfg(not(target_arch = "wasm32"))]
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
background_threadpool::init_background_runtime();
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
let client = reqwest::Client::builder()
.connector_layer(background_threadpool::BackgroundProcessorLayer::new())
.build()
.expect("should be able to build reqwest client");
let url = if let Some(url) = std::env::args().nth(1) {
url
} else {
println!("No CLI URL provided, using default.");
"https://hyper.rs".into()
};
eprintln!("Fetching {url:?}...");
let res = client.get(url).send().await?;
eprintln!("Response: {:?} {}", res.version(), res.status());
eprintln!("Headers: {:#?}\n", res.headers());
let body = res.text().await?;
println!("{body}");
Ok(())
}
// separating out for convenience to avoid a million #[cfg(not(target_arch = "wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
mod background_threadpool {
use std::{
future::Future,
pin::Pin,
sync::OnceLock,
task::{Context, Poll},
};
use futures_util::TryFutureExt;
use pin_project_lite::pin_project;
use tokio::{runtime::Handle, select, sync::mpsc::error::TrySendError};
use tower::{BoxError, Layer, Service};
static CPU_HEAVY_THREAD_POOL: OnceLock<
tokio::sync::mpsc::Sender<Pin<Box<dyn Future<Output = ()> + Send + 'static>>>,
> = OnceLock::new();
pub(crate) fn init_background_runtime() {
std::thread::Builder::new()
.name("cpu-heavy-background-threadpool".to_string())
.spawn(move || {
let rt = tokio::runtime::Builder::new_multi_thread()
.thread_name("cpu-heavy-background-pool-thread")
.worker_threads(num_cpus::get() as usize)
// ref: https://github.com/tokio-rs/tokio/issues/4941
// consider uncommenting if seeing heavy task contention
// .disable_lifo_slot()
.on_thread_start(move || {
#[cfg(target_os = "linux")]
unsafe {
// Increase thread pool thread niceness, so they are lower priority
// than the foreground executor and don't interfere with I/O tasks
{
*libc::__errno_location() = 0;
if libc::nice(10) == -1 && *libc::__errno_location() != 0 {
let error = std::io::Error::last_os_error();
log::error!("failed to set threadpool niceness: {}", error);
}
}
}
})
.enable_all()
.build()
.unwrap_or_else(|e| panic!("cpu heavy runtime failed_to_initialize: {}", e));
rt.block_on(async {
log::debug!("starting background cpu-heavy work");
process_cpu_work().await;
});
})
.unwrap_or_else(|e| panic!("cpu heavy thread failed_to_initialize: {}", e));
}
#[cfg(not(target_arch = "wasm32"))]
async fn process_cpu_work() {
// we only use this channel for routing work, it should move pretty quick, it can be small
let (tx, mut rx) = tokio::sync::mpsc::channel(10);
// share the handle to the background channel globally
CPU_HEAVY_THREAD_POOL.set(tx).unwrap();
while let Some(work) = rx.recv().await {
tokio::task::spawn(work);
}
}
// retrieve the sender to the background channel, and send the future over to it for execution
fn send_to_background_runtime(future: impl Future<Output = ()> + Send + 'static) {
let tx = CPU_HEAVY_THREAD_POOL.get().expect(
"start up the secondary tokio runtime before sending to `CPU_HEAVY_THREAD_POOL`",
);
match tx.try_send(Box::pin(future)) {
Ok(_) => (),
Err(TrySendError::Closed(_)) => {
panic!("background cpu heavy runtime channel is closed")
}
Err(TrySendError::Full(msg)) => {
log::warn!(
"background cpu heavy runtime channel is full, task spawning loop delayed"
);
let tx = tx.clone();
Handle::current().spawn(async move {
tx.send(msg)
.await
.expect("background cpu heavy runtime channel is closed")
});
}
}
}
// This tower layer injects futures with a oneshot channel, and then sends them to the background runtime for processing.
// We don't use the Buffer service because that is intended to process sequentially on a single task, whereas we want to
// spawn a new task per call.
#[derive(Copy, Clone)]
pub struct BackgroundProcessorLayer {}
impl BackgroundProcessorLayer {
pub fn new() -> Self {
Self {}
}
}
impl<S> Layer<S> for BackgroundProcessorLayer {
type Service = BackgroundProcessor<S>;
fn layer(&self, service: S) -> Self::Service {
BackgroundProcessor::new(service)
}
}
impl std::fmt::Debug for BackgroundProcessorLayer {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("BackgroundProcessorLayer").finish()
}
}
// This tower service injects futures with a oneshot channel, and then sends them to the background runtime for processing.
#[derive(Debug, Clone)]
pub struct BackgroundProcessor<S> {
inner: S,
}
impl<S> BackgroundProcessor<S> {
pub fn new(inner: S) -> Self {
BackgroundProcessor { inner }
}
}
impl<S, Request> Service<Request> for BackgroundProcessor<S>
where
S: Service<Request>,
S::Response: Send + 'static,
S::Error: Into<BoxError> + Send,
S::Future: Send + 'static,
{
type Response = S::Response;
type Error = BoxError;
type Future = BackgroundResponseFuture<S::Response>;
fn poll_ready(
&mut self,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Result<(), Self::Error>> {
match self.inner.poll_ready(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(r) => Poll::Ready(r.map_err(Into::into)),
}
}
fn call(&mut self, req: Request) -> Self::Future {
let response = self.inner.call(req);
// wrap our inner service's future with a future that writes to this oneshot channel
let (mut tx, rx) = tokio::sync::oneshot::channel();
let future = async move {
select!(
_ = tx.closed() => {
// receiver already dropped, don't need to do anything
}
result = response.map_err(|err| Into::<BoxError>::into(err)) => {
// if this fails, the receiver already dropped, so we don't need to do anything
let _ = tx.send(result);
}
)
};
// send the wrapped future to the background
send_to_background_runtime(future);
BackgroundResponseFuture::new(rx)
}
}
// `BackgroundProcessor` response future
pin_project! {
#[derive(Debug)]
pub struct BackgroundResponseFuture<S> {
#[pin]
rx: tokio::sync::oneshot::Receiver<Result<S, BoxError>>,
}
}
impl<S> BackgroundResponseFuture<S> {
pub(crate) fn new(rx: tokio::sync::oneshot::Receiver<Result<S, BoxError>>) -> Self {
BackgroundResponseFuture { rx }
}
}
impl<S> Future for BackgroundResponseFuture<S>
where
S: Send + 'static,
{
type Output = Result<S, BoxError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
// now poll on the receiver end of the oneshot to get the result
match this.rx.poll(cx) {
Poll::Ready(v) => match v {
Ok(v) => Poll::Ready(v.map_err(Into::into)),
Err(err) => Poll::Ready(Err(Box::new(err) as BoxError)),
},
Poll::Pending => Poll::Pending,
}
}
}
}
// The [cfg(not(target_arch = "wasm32"))] above prevent building the tokio::main function
// for wasm32 target, because tokio isn't compatible with wasm32.
// If you aren't building for wasm32, you don't need that line.
// The two lines below avoid the "'main' function not found" error when building for wasm32 target.
#[cfg(any(target_arch = "wasm32"))]
fn main() {}
================================================
FILE: examples/form.rs
================================================
// Short example of a POST request with form data.
//
// This is using the `tokio` runtime. You'll need the following dependency:
//
// `tokio = { version = "1", features = ["full"] }`
#[cfg(not(target_arch = "wasm32"))]
#[tokio::main]
async fn main() {
let response = reqwest::Client::new()
.post("http://www.baidu.com")
.form(&[("one", "1")])
.send()
.await
.expect("send");
println!("Response status {}", response.status());
}
// The [cfg(not(target_arch = "wasm32"))] above prevent building the tokio::main function
// for wasm32 target, because tokio isn't compatible with wasm32.
// If you aren't building for wasm32, you don't need that line.
// The two lines below avoid the "'main' function not found" error when building for wasm32 target.
#[cfg(target_arch = "wasm32")]
fn main() {}
================================================
FILE: examples/h3_simple.rs
================================================
#![deny(warnings)]
// This is using the `tokio` runtime. You'll need the following dependency:
//
// `tokio = { version = "1", features = ["full"] }`
#[cfg(feature = "http3")]
#[cfg(not(target_arch = "wasm32"))]
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = reqwest::Client::builder().http3_prior_knowledge().build()?;
// Some simple CLI args requirements...
let url = match std::env::args().nth(1) {
Some(url) => url,
None => {
println!("No CLI URL provided, using default.");
"https://hyper.rs".into()
}
};
eprintln!("Fetching {url:?}...");
let res = client
.get(url)
.version(http::Version::HTTP_3)
.send()
.await?;
eprintln!("Response: {:?} {}", res.version(), res.status());
eprintln!("Headers: {:#?}\n", res.headers());
let body = res.text().await?;
println!("{body}");
Ok(())
}
// The [cfg(not(target_arch = "wasm32"))] above prevent building the tokio::main function
// for wasm32 target, because tokio isn't compatible with wasm32.
// If you aren't building for wasm32, you don't need that line.
// The two lines below avoid the "'main' function not found" error when building for wasm32 target.
#[cfg(any(target_arch = "wasm32", not(feature = "http3")))]
fn main() {}
================================================
FILE: examples/json_dynamic.rs
================================================
//! This example illustrates the way to send and receive arbitrary JSON.
//!
//! This is useful for some ad-hoc experiments and situations when you don't
//! really care about the structure of the JSON and just need to display it or
//! process it at runtime.
// This is using the `tokio` runtime. You'll need the following dependency:
//
// `tokio = { version = "1", features = ["full"] }`
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let echo_json: serde_json::Value = reqwest::Client::new()
.post("https://jsonplaceholder.typicode.com/posts")
.json(&serde_json::json!({
"title": "Reqwest.rs",
"body": "https://docs.rs/reqwest",
"userId": 1
}))
.send()
.await?
.json()
.await?;
println!("{echo_json:#?}");
// Object(
// {
// "body": String(
// "https://docs.rs/reqwest"
// ),
// "id": Number(
// 101
// ),
// "title": String(
// "Reqwest.rs"
// ),
// "userId": Number(
// 1
// )
// }
// )
Ok(())
}
================================================
FILE: examples/json_typed.rs
================================================
//! This example illustrates the way to send and receive statically typed JSON.
//!
//! In contrast to the arbitrary JSON example, this brings up the full power of
//! Rust compile-time type system guaranties though it requires a little bit
//! more code.
// These require the `serde` dependency.
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Post {
id: Option<i32>,
title: String,
body: String,
#[serde(rename = "userId")]
user_id: i32,
}
// This is using the `tokio` runtime. You'll need the following dependency:
//
// `tokio = { version = "1", features = ["full"] }`
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let new_post = Post {
id: None,
title: "Reqwest.rs".into(),
body: "https://docs.rs/reqwest".into(),
user_id: 1,
};
let new_post: Post = reqwest::Client::new()
.post("https://jsonplaceholder.typicode.com/posts")
.json(&new_post)
.send()
.await?
.json()
.await?;
println!("{new_post:#?}");
// Post {
// id: Some(
// 101
// ),
// title: "Reqwest.rs",
// body: "https://docs.rs/reqwest",
// user_id: 1
// }
Ok(())
}
================================================
FILE: examples/simple.rs
================================================
#![deny(warnings)]
// This is using the `tokio` runtime. You'll need the following dependency:
//
// `tokio = { version = "1", features = ["full"] }`
#[cfg(not(target_arch = "wasm32"))]
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
// Some simple CLI args requirements...
let url = if let Some(url) = std::env::args().nth(1) {
url
} else {
println!("No CLI URL provided, using default.");
"https://hyper.rs".into()
};
eprintln!("Fetching {url:?}...");
// reqwest::get() is a convenience function.
//
// In most cases, you should create/build a reqwest::Client and reuse
// it for all requests.
let res = reqwest::get(url).await?;
eprintln!("Response: {:?} {}", res.version(), res.status());
eprintln!("Headers: {:#?}\n", res.headers());
let body = res.text().await?;
println!("{body}");
Ok(())
}
// The [cfg(not(target_arch = "wasm32"))] above prevent building the tokio::main function
// for wasm32 target, because tokio isn't compatible with wasm32.
// If you aren't building for wasm32, you don't need that line.
// The two lines below avoid the "'main' function not found" error when building for wasm32 target.
#[cfg(target_arch = "wasm32")]
fn main() {}
================================================
FILE: examples/tor_socks.rs
================================================
#![deny(warnings)]
// This is using the `tokio` runtime. You'll need the following dependency:
//
// `tokio = { version = "1", features = ["full"] }`
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
// Make sure you are running tor and this is your socks port
let proxy = reqwest::Proxy::all("socks5h://127.0.0.1:9050").expect("tor proxy should be there");
let client = reqwest::Client::builder()
.proxy(proxy)
.build()
.expect("should be able to build reqwest client");
let res = client.get("https://check.torproject.org").send().await?;
println!("Status: {}", res.status());
let text = res.text().await?;
let is_tor = text.contains("Congratulations. This browser is configured to use Tor.");
println!("Is Tor: {is_tor}");
assert!(is_tor);
Ok(())
}
================================================
FILE: examples/wasm_github_fetch/.gitignore
================================================
node_modules
pkg
target
Cargo.lock
*.swp
================================================
FILE: examples/wasm_github_fetch/Cargo.toml
================================================
[package]
name = "wasm"
version = "0.1.0"
authors = ["John Gallagher <john.willis.gallagher@gmail.com>"]
edition = "2021"
# Config mostly pulled from: https://github.com/rustwasm/wasm-bindgen/blob/master/examples/fetch/Cargo.toml
[lib]
crate-type = ["cdylib"]
[dependencies]
reqwest = {path = "../../"}
serde = { version = "1.0.101", features = ["derive"] }
serde_derive = "^1.0.59"
wasm-bindgen-futures = "0.4.1"
serde_json = "1.0.41"
wasm-bindgen = { version = "0.2.51", features = ["serde-serialize"] }
================================================
FILE: examples/wasm_github_fetch/README.md
================================================
## Example usage of Reqwest from WASM
Install wasm-pack with
npm install
Then you can build the example locally with:
npm run serve
and then visiting http://localhost:8080 in a browser should run the example!
This example is loosely based off of [this example](https://github.com/rustwasm/wasm-bindgen/blob/master/examples/fetch/src/lib.rs), an example usage of `fetch` from `wasm-bindgen`.
================================================
FILE: examples/wasm_github_fetch/index.js
================================================
const rust = import('./pkg');
rust
.then(m => {
return m.run().then((data) => {
console.log(data);
console.log("The latest commit to the wasm-bindgen %s branch is:", data.name);
console.log("%s, authored by %s <%s>", data.commit.sha, data.commit.commit.author.name, data.commit.commit.author.email);
})
})
.catch(console.error);
================================================
FILE: examples/wasm_github_fetch/osv-scanner.toml
================================================
[[PackageOverrides]]
ecosystem = "npm"
ignore = true
================================================
FILE: examples/wasm_github_fetch/package.json
================================================
{
"scripts": {
"build": "webpack",
"serve": "webpack-dev-server"
},
"devDependencies": {
"@wasm-tool/wasm-pack-plugin": "1.0.1",
"text-encoding": "^0.7.0",
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.29.4",
"webpack-cli": "^3.1.1",
"webpack-dev-server": "^3.1.0"
}
}
================================================
FILE: examples/wasm_github_fetch/src/lib.rs
================================================
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
// NOTE: This test is a clone of https://github.com/rustwasm/wasm-bindgen/blob/master/examples/fetch/src/lib.rs
// but uses Reqwest instead of the web_sys fetch api directly
/// A struct to hold some data from the GitHub Branch API.
///
/// Note how we don't have to define every member -- serde will ignore extra
/// data when deserializing
#[derive(Debug, Serialize, Deserialize)]
pub struct Branch {
pub name: String,
pub commit: Commit,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Commit {
pub sha: String,
pub commit: CommitDetails,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CommitDetails {
pub author: Signature,
pub committer: Signature,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Signature {
pub name: String,
pub email: String,
}
#[wasm_bindgen]
pub async fn run() -> Result<JsValue, JsValue> {
let res = reqwest::Client::new()
.get("https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master")
.header("Accept", "application/vnd.github.v3+json")
.send()
.await?;
let text = res.text().await?;
let branch_info: Branch = serde_json::from_str(&text).unwrap();
Ok(JsValue::from_serde(&branch_info).unwrap())
}
================================================
FILE: examples/wasm_github_fetch/webpack.config.js
================================================
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin");
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
},
plugins: [
new HtmlWebpackPlugin(),
new WasmPackPlugin({
crateDirectory: path.resolve(__dirname, ".")
}),
// Have this example work in Edge which doesn't ship `TextEncoder` or
// `TextDecoder` at this time.
new webpack.ProvidePlugin({
TextDecoder: ['text-encoding', 'TextDecoder'],
TextEncoder: ['text-encoding', 'TextEncoder']
})
],
mode: 'development'
};
================================================
FILE: src/async_impl/body.rs
================================================
use std::fmt;
use std::future::Future;
use std::pin::Pin;
use std::task::{ready, Context, Poll};
use std::time::Duration;
use bytes::Bytes;
use http_body::Body as HttpBody;
use http_body_util::combinators::BoxBody;
use pin_project_lite::pin_project;
#[cfg(feature = "stream")]
use tokio::fs::File;
use tokio::time::Sleep;
#[cfg(feature = "stream")]
use tokio_util::io::ReaderStream;
/// An asynchronous request body.
pub struct Body {
inner: Inner,
}
enum Inner {
Reusable(Bytes),
Streaming(BoxBody<Bytes, Box<dyn std::error::Error + Send + Sync>>),
}
pin_project! {
/// A body with a total timeout.
///
/// The timeout does not reset upon each chunk, but rather requires the whole
/// body be streamed before the deadline is reached.
pub(crate) struct TotalTimeoutBody<B> {
#[pin]
inner: B,
timeout: Pin<Box<Sleep>>,
}
}
pin_project! {
pub(crate) struct ReadTimeoutBody<B> {
#[pin]
inner: B,
#[pin]
sleep: Option<Sleep>,
timeout: Duration,
}
}
impl Body {
/// Returns a reference to the internal data of the `Body`.
///
/// `None` is returned, if the underlying data is a stream.
pub fn as_bytes(&self) -> Option<&[u8]> {
match &self.inner {
Inner::Reusable(bytes) => Some(bytes.as_ref()),
Inner::Streaming(..) => None,
}
}
/// Wrap a futures `Stream` in a box inside `Body`.
///
/// # Example
///
/// ```
/// # use reqwest::Body;
/// # use futures_util;
/// # fn main() {
/// let chunks: Vec<Result<_, ::std::io::Error>> = vec![
/// Ok("hello"),
/// Ok(" "),
/// Ok("world"),
/// ];
///
/// let stream = futures_util::stream::iter(chunks);
///
/// let body = Body::wrap_stream(stream);
/// # }
/// ```
///
/// # Optional
///
/// This requires the `stream` feature to be enabled.
#[cfg(feature = "stream")]
#[cfg_attr(docsrs, doc(cfg(feature = "stream")))]
pub fn wrap_stream<S>(stream: S) -> Body
where
S: futures_core::stream::TryStream + Send + 'static,
S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
Bytes: From<S::Ok>,
{
Body::stream(stream)
}
#[cfg(any(feature = "stream", feature = "multipart", feature = "blocking"))]
pub(crate) fn stream<S>(stream: S) -> Body
where
S: futures_core::stream::TryStream + Send + 'static,
S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
Bytes: From<S::Ok>,
{
use futures_util::TryStreamExt;
use http_body::Frame;
use http_body_util::StreamBody;
let body = http_body_util::BodyExt::boxed(StreamBody::new(sync_wrapper::SyncStream::new(
stream
.map_ok(|d| Frame::data(Bytes::from(d)))
.map_err(Into::into),
)));
Body {
inner: Inner::Streaming(body),
}
}
pub(crate) fn empty() -> Body {
Body::reusable(Bytes::new())
}
pub(crate) fn reusable(chunk: Bytes) -> Body {
Body {
inner: Inner::Reusable(chunk),
}
}
/// Wrap a [`HttpBody`] in a box inside `Body`.
///
/// # Example
///
/// ```
/// # use reqwest::Body;
/// # use futures_util;
/// # fn main() {
/// let content = "hello,world!".to_string();
///
/// let body = Body::wrap(content);
/// # }
/// ```
pub fn wrap<B>(inner: B) -> Body
where
B: HttpBody + Send + Sync + 'static,
B::Data: Into<Bytes>,
B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
{
use http_body_util::BodyExt;
let boxed = IntoBytesBody { inner }.map_err(Into::into).boxed();
Body {
inner: Inner::Streaming(boxed),
}
}
pub(crate) fn try_clone(&self) -> Option<Body> {
match self.inner {
Inner::Reusable(ref chunk) => Some(Body::reusable(chunk.clone())),
Inner::Streaming { .. } => None,
}
}
#[cfg(feature = "multipart")]
pub(crate) fn content_length(&self) -> Option<u64> {
match self.inner {
Inner::Reusable(ref bytes) => Some(bytes.len() as u64),
Inner::Streaming(ref body) => body.size_hint().exact(),
}
}
}
impl Default for Body {
#[inline]
fn default() -> Body {
Body::empty()
}
}
/*
impl From<hyper::Body> for Body {
#[inline]
fn from(body: hyper::Body) -> Body {
Self {
inner: Inner::Streaming {
body: Box::pin(WrapHyper(body)),
},
}
}
}
*/
impl From<Bytes> for Body {
#[inline]
fn from(bytes: Bytes) -> Body {
Body::reusable(bytes)
}
}
impl From<Vec<u8>> for Body {
#[inline]
fn from(vec: Vec<u8>) -> Body {
Body::reusable(vec.into())
}
}
impl From<&'static [u8]> for Body {
#[inline]
fn from(s: &'static [u8]) -> Body {
Body::reusable(Bytes::from_static(s))
}
}
impl From<String> for Body {
#[inline]
fn from(s: String) -> Body {
Body::reusable(s.into())
}
}
impl From<&'static str> for Body {
#[inline]
fn from(s: &'static str) -> Body {
s.as_bytes().into()
}
}
#[cfg(feature = "stream")]
#[cfg_attr(docsrs, doc(cfg(feature = "stream")))]
impl From<File> for Body {
#[inline]
fn from(file: File) -> Body {
Body::wrap_stream(ReaderStream::new(file))
}
}
impl fmt::Debug for Body {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Body").finish()
}
}
impl HttpBody for Body {
type Data = Bytes;
type Error = crate::Error;
fn poll_frame(
mut self: Pin<&mut Self>,
cx: &mut Context,
) -> Poll<Option<Result<hyper::body::Frame<Self::Data>, Self::Error>>> {
match self.inner {
Inner::Reusable(ref mut bytes) => {
let out = bytes.split_off(0);
if out.is_empty() {
Poll::Ready(None)
} else {
Poll::Ready(Some(Ok(hyper::body::Frame::data(out))))
}
}
Inner::Streaming(ref mut body) => Poll::Ready(
ready!(Pin::new(body).poll_frame(cx))
.map(|opt_chunk| opt_chunk.map_err(crate::error::body)),
),
}
}
fn size_hint(&self) -> http_body::SizeHint {
match self.inner {
Inner::Reusable(ref bytes) => http_body::SizeHint::with_exact(bytes.len() as u64),
Inner::Streaming(ref body) => body.size_hint(),
}
}
fn is_end_stream(&self) -> bool {
match self.inner {
Inner::Reusable(ref bytes) => bytes.is_empty(),
Inner::Streaming(ref body) => body.is_end_stream(),
}
}
}
// ===== impl TotalTimeoutBody =====
pub(crate) fn total_timeout<B>(body: B, timeout: Pin<Box<Sleep>>) -> TotalTimeoutBody<B> {
TotalTimeoutBody {
inner: body,
timeout,
}
}
pub(crate) fn with_read_timeout<B>(body: B, timeout: Duration) -> ReadTimeoutBody<B> {
ReadTimeoutBody {
inner: body,
sleep: None,
timeout,
}
}
impl<B> hyper::body::Body for TotalTimeoutBody<B>
where
B: hyper::body::Body,
B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
{
type Data = B::Data;
type Error = crate::Error;
fn poll_frame(
self: Pin<&mut Self>,
cx: &mut Context,
) -> Poll<Option<Result<hyper::body::Frame<Self::Data>, Self::Error>>> {
let this = self.project();
if let Poll::Ready(()) = this.timeout.as_mut().poll(cx) {
return Poll::Ready(Some(Err(crate::error::body(crate::error::TimedOut))));
}
Poll::Ready(
ready!(this.inner.poll_frame(cx))
.map(|opt_chunk| opt_chunk.map_err(crate::error::body)),
)
}
#[inline]
fn size_hint(&self) -> http_body::SizeHint {
self.inner.size_hint()
}
#[inline]
fn is_end_stream(&self) -> bool {
self.inner.is_end_stream()
}
}
impl<B> hyper::body::Body for ReadTimeoutBody<B>
where
B: hyper::body::Body,
B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
{
type Data = B::Data;
type Error = crate::Error;
fn poll_frame(
self: Pin<&mut Self>,
cx: &mut Context,
) -> Poll<Option<Result<hyper::body::Frame<Self::Data>, Self::Error>>> {
let mut this = self.project();
// Start the `Sleep` if not active.
let sleep_pinned = if let Some(some) = this.sleep.as_mut().as_pin_mut() {
some
} else {
this.sleep.set(Some(tokio::time::sleep(*this.timeout)));
this.sleep.as_mut().as_pin_mut().unwrap()
};
// Error if the timeout has expired.
if let Poll::Ready(()) = sleep_pinned.poll(cx) {
return Poll::Ready(Some(Err(crate::error::body(crate::error::TimedOut))));
}
let item = ready!(this.inner.poll_frame(cx))
.map(|opt_chunk| opt_chunk.map_err(crate::error::body));
// a ready frame means timeout is reset
this.sleep.set(None);
Poll::Ready(item)
}
#[inline]
fn size_hint(&self) -> http_body::SizeHint {
self.inner.size_hint()
}
#[inline]
fn is_end_stream(&self) -> bool {
self.inner.is_end_stream()
}
}
pub(crate) type ResponseBody =
http_body_util::combinators::BoxBody<Bytes, Box<dyn std::error::Error + Send + Sync>>;
pub(crate) fn boxed<B>(body: B) -> ResponseBody
where
B: hyper::body::Body<Data = Bytes> + Send + Sync + 'static,
B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
{
use http_body_util::BodyExt;
body.map_err(box_err).boxed()
}
pub(crate) fn response<B>(
body: B,
deadline: Option<Pin<Box<Sleep>>>,
read_timeout: Option<Duration>,
) -> ResponseBody
where
B: hyper::body::Body<Data = Bytes> + Send + Sync + 'static,
B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
{
use http_body_util::BodyExt;
match (deadline, read_timeout) {
(Some(total), Some(read)) => {
let body = with_read_timeout(body, read).map_err(box_err);
total_timeout(body, total).map_err(box_err).boxed()
}
(Some(total), None) => total_timeout(body, total).map_err(box_err).boxed(),
(None, Some(read)) => with_read_timeout(body, read).map_err(box_err).boxed(),
(None, None) => body.map_err(box_err).boxed(),
}
}
fn box_err<E>(err: E) -> Box<dyn std::error::Error + Send + Sync>
where
E: Into<Box<dyn std::error::Error + Send + Sync>>,
{
err.into()
}
// ===== impl IntoBytesBody =====
pin_project! {
struct IntoBytesBody<B> {
#[pin]
inner: B,
}
}
// We can't use `map_frame()` because that loses the hint data (for good reason).
// But we aren't transforming the data.
impl<B> hyper::body::Body for IntoBytesBody<B>
where
B: hyper::body::Body,
B::Data: Into<Bytes>,
{
type Data = Bytes;
type Error = B::Error;
fn poll_frame(
self: Pin<&mut Self>,
cx: &mut Context,
) -> Poll<Option<Result<hyper::body::Frame<Self::Data>, Self::Error>>> {
match ready!(self.project().inner.poll_frame(cx)) {
Some(Ok(f)) => Poll::Ready(Some(Ok(f.map_data(Into::into)))),
Some(Err(e)) => Poll::Ready(Some(Err(e))),
None => Poll::Ready(None),
}
}
#[inline]
fn size_hint(&self) -> http_body::SizeHint {
self.inner.size_hint()
}
#[inline]
fn is_end_stream(&self) -> bool {
self.inner.is_end_stream()
}
}
#[cfg(test)]
mod tests {
use http_body::Body as _;
use super::Body;
#[test]
fn test_as_bytes() {
let test_data = b"Test body";
let body = Body::from(&test_data[..]);
assert_eq!(body.as_bytes(), Some(&test_data[..]));
}
#[test]
fn body_exact_length() {
let empty_body = Body::empty();
assert!(empty_body.is_end_stream());
assert_eq!(empty_body.size_hint().exact(), Some(0));
let bytes_body = Body::reusable("abc".into());
assert!(!bytes_body.is_end_stream());
assert_eq!(bytes_body.size_hint().exact(), Some(3));
// can delegate even when wrapped
let stream_body = Body::wrap(empty_body);
assert!(stream_body.is_end_stream());
assert_eq!(stream_body.size_hint().exact(), Some(0));
}
}
================================================
FILE: src/async_impl/client.rs
================================================
#[cfg(any(feature = "__native-tls", feature = "__rustls",))]
use std::any::Any;
use std::future::Future;
use std::net::IpAddr;
use std::pin::Pin;
use std::sync::Arc;
use std::task::{ready, Context, Poll};
use std::time::Duration;
use std::{collections::HashMap, convert::TryInto, net::SocketAddr};
use std::{fmt, str};
use super::request::{Request, RequestBuilder};
use super::response::Response;
use super::Body;
#[cfg(feature = "http3")]
use crate::async_impl::h3_client::connect::{H3ClientConfig, H3Connector};
#[cfg(feature = "http3")]
use crate::async_impl::h3_client::H3Client;
use crate::config::{RequestConfig, TotalTimeout};
#[cfg(unix)]
use crate::connect::uds::UnixSocketProvider;
#[cfg(target_os = "windows")]
use crate::connect::windows_named_pipe::WindowsNamedPipeProvider;
use crate::connect::{
sealed::{Conn, Unnameable},
BoxedConnectorLayer, BoxedConnectorService, Connector, ConnectorBuilder,
};
#[cfg(feature = "cookies")]
use crate::cookie;
#[cfg(feature = "cookies")]
use crate::cookie::service::CookieService;
#[cfg(feature = "hickory-dns")]
use crate::dns::hickory::HickoryDnsResolver;
use crate::dns::{gai::GaiResolver, DnsResolverWithOverrides, DynResolver, Resolve};
use crate::error::{self, BoxError};
use crate::into_url::try_uri;
use crate::proxy::Matcher as ProxyMatcher;
use crate::redirect::{self, TowerRedirectPolicy};
#[cfg(feature = "__rustls")]
use crate::tls::CertificateRevocationList;
#[cfg(feature = "__tls")]
use crate::tls::{self, TlsBackend};
#[cfg(feature = "__tls")]
use crate::Certificate;
#[cfg(any(feature = "__native-tls", feature = "__rustls"))]
use crate::Identity;
use crate::{IntoUrl, Method, Proxy, Url};
use http::header::{Entry, HeaderMap, HeaderValue, ACCEPT, PROXY_AUTHORIZATION, USER_AGENT};
use http::uri::Scheme;
use http::Uri;
use hyper_util::client::legacy::connect::HttpConnector;
#[cfg(feature = "__native-tls")]
use native_tls_crate::TlsConnector;
use pin_project_lite::pin_project;
#[cfg(feature = "http3")]
use quinn::TransportConfig;
#[cfg(feature = "http3")]
use quinn::VarInt;
use tokio::time::Sleep;
use tower::util::BoxCloneSyncServiceLayer;
use tower::{Layer, Service};
#[cfg(any(
feature = "gzip",
feature = "brotli",
feature = "zstd",
feature = "deflate"
))]
use tower_http::decompression::Decompression;
use tower_http::follow_redirect::FollowRedirect;
/// An asynchronous `Client` to make Requests with.
///
/// The Client has various configuration values to tweak, but the defaults
/// are set to what is usually the most commonly desired value. To configure a
/// `Client`, use `Client::builder()`.
///
/// The `Client` holds a connection pool internally to improve performance
/// by reusing connections and avoiding setup overhead, so it is advised that
/// you create one and **reuse** it.
///
/// You do **not** have to wrap the `Client` in an [`Rc`] or [`Arc`] to **reuse** it,
/// because it already uses an [`Arc`] internally.
///
/// # Connection Pooling
///
/// The connection pool can be configured using [`ClientBuilder`] methods
/// with the `pool_` prefix, such as [`ClientBuilder::pool_idle_timeout`]
/// and [`ClientBuilder::pool_max_idle_per_host`].
///
/// [`Rc`]: std::rc::Rc
#[derive(Clone)]
pub struct Client {
inner: Arc<ClientRef>,
}
/// A `ClientBuilder` can be used to create a `Client` with custom configuration.
#[must_use]
pub struct ClientBuilder {
config: Config,
}
enum HttpVersionPref {
Http1,
#[cfg(feature = "http2")]
Http2,
#[cfg(feature = "http3")]
Http3,
All,
}
#[derive(Clone, Copy, Debug)]
struct Accepts {
#[cfg(feature = "gzip")]
gzip: bool,
#[cfg(feature = "brotli")]
brotli: bool,
#[cfg(feature = "zstd")]
zstd: bool,
#[cfg(feature = "deflate")]
deflate: bool,
}
impl Default for Accepts {
fn default() -> Accepts {
Accepts {
#[cfg(feature = "gzip")]
gzip: true,
#[cfg(feature = "brotli")]
brotli: true,
#[cfg(feature = "zstd")]
zstd: true,
#[cfg(feature = "deflate")]
deflate: true,
}
}
}
#[derive(Clone)]
struct HyperService {
hyper: HyperClient,
}
impl Service<hyper::Request<crate::async_impl::body::Body>> for HyperService {
type Error = crate::Error;
type Response = http::Response<hyper::body::Incoming>;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + Sync>>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.hyper.poll_ready(cx).map_err(crate::error::request)
}
fn call(&mut self, req: hyper::Request<crate::async_impl::body::Body>) -> Self::Future {
let clone = self.hyper.clone();
let mut inner = std::mem::replace(&mut self.hyper, clone);
Box::pin(async move { inner.call(req).await.map_err(crate::error::request) })
}
}
struct Config {
// NOTE: When adding a new field, update `fmt::Debug for ClientBuilder`
accepts: Accepts,
headers: HeaderMap,
#[cfg(feature = "__tls")]
hostname_verification: bool,
#[cfg(feature = "__tls")]
certs_verification: bool,
#[cfg(feature = "__tls")]
tls_sni: bool,
connect_timeout: Option<Duration>,
connection_verbose: bool,
pool_idle_timeout: Option<Duration>,
pool_max_idle_per_host: usize,
tcp_keepalive: Option<Duration>,
tcp_keepalive_interval: Option<Duration>,
tcp_keepalive_retries: Option<u32>,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
tcp_user_timeout: Option<Duration>,
#[cfg(any(feature = "__native-tls", feature = "__rustls"))]
identity: Option<Identity>,
proxies: Vec<ProxyMatcher>,
auto_sys_proxy: bool,
redirect_policy: redirect::Policy,
retry_policy: crate::retry::Builder,
referer: bool,
read_timeout: Option<Duration>,
timeout: Option<Duration>,
#[cfg(feature = "__tls")]
root_certs: Vec<Certificate>,
#[cfg(feature = "__tls")]
tls_certs_only: bool,
#[cfg(feature = "__rustls")]
crls: Vec<CertificateRevocationList>,
#[cfg(feature = "__tls")]
min_tls_version: Option<tls::Version>,
#[cfg(feature = "__tls")]
max_tls_version: Option<tls::Version>,
#[cfg(feature = "__tls")]
tls_info: bool,
#[cfg(feature = "__tls")]
tls: TlsBackend,
connector_layers: Vec<BoxedConnectorLayer>,
http_version_pref: HttpVersionPref,
http09_responses: bool,
http1_title_case_headers: bool,
http1_allow_obsolete_multiline_headers_in_responses: bool,
http1_ignore_invalid_headers_in_responses: bool,
http1_allow_spaces_after_header_name_in_responses: bool,
#[cfg(feature = "http2")]
http2_initial_stream_window_size: Option<u32>,
#[cfg(feature = "http2")]
http2_initial_connection_window_size: Option<u32>,
#[cfg(feature = "http2")]
http2_adaptive_window: bool,
#[cfg(feature = "http2")]
http2_max_frame_size: Option<u32>,
#[cfg(feature = "http2")]
http2_max_header_list_size: Option<u32>,
#[cfg(feature = "http2")]
http2_keep_alive_interval: Option<Duration>,
#[cfg(feature = "http2")]
http2_keep_alive_timeout: Option<Duration>,
#[cfg(feature = "http2")]
http2_keep_alive_while_idle: bool,
local_address: Option<IpAddr>,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
interface: Option<String>,
nodelay: bool,
#[cfg(feature = "cookies")]
cookie_store: Option<Arc<dyn cookie::CookieStore>>,
hickory_dns: bool,
error: Option<crate::Error>,
https_only: bool,
#[cfg(feature = "http3")]
tls_enable_early_data: bool,
#[cfg(feature = "http3")]
quic_max_idle_timeout: Option<Duration>,
#[cfg(feature = "http3")]
quic_stream_receive_window: Option<VarInt>,
#[cfg(feature = "http3")]
quic_receive_window: Option<VarInt>,
#[cfg(feature = "http3")]
quic_send_window: Option<u64>,
#[cfg(feature = "http3")]
quic_congestion_bbr: bool,
#[cfg(feature = "http3")]
h3_max_field_section_size: Option<u64>,
#[cfg(feature = "http3")]
h3_send_grease: Option<bool>,
dns_overrides: HashMap<String, Vec<SocketAddr>>,
dns_resolver: Option<Arc<dyn Resolve>>,
#[cfg(unix)]
unix_socket: Option<Arc<std::path::Path>>,
#[cfg(target_os = "windows")]
windows_named_pipe: Option<Arc<std::ffi::OsStr>>,
}
impl Default for ClientBuilder {
fn default() -> Self {
Self::new()
}
}
impl ClientBuilder {
/// Constructs a new `ClientBuilder`.
///
/// This is the same as `Client::builder()`.
pub fn new() -> Self {
let mut headers: HeaderMap<HeaderValue> = HeaderMap::with_capacity(2);
headers.insert(ACCEPT, HeaderValue::from_static("*/*"));
ClientBuilder {
config: Config {
error: None,
accepts: Accepts::default(),
headers,
#[cfg(feature = "__tls")]
hostname_verification: true,
#[cfg(feature = "__tls")]
certs_verification: true,
#[cfg(feature = "__tls")]
tls_sni: true,
connect_timeout: None,
connection_verbose: false,
pool_idle_timeout: Some(Duration::from_secs(90)),
pool_max_idle_per_host: usize::MAX,
tcp_keepalive: Some(Duration::from_secs(15)),
tcp_keepalive_interval: Some(Duration::from_secs(15)),
tcp_keepalive_retries: Some(3),
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
tcp_user_timeout: Some(Duration::from_secs(30)),
proxies: Vec::new(),
auto_sys_proxy: true,
redirect_policy: redirect::Policy::default(),
retry_policy: crate::retry::Builder::default(),
referer: true,
read_timeout: None,
timeout: None,
#[cfg(feature = "__tls")]
root_certs: Vec::new(),
#[cfg(feature = "__tls")]
tls_certs_only: false,
#[cfg(any(feature = "__native-tls", feature = "__rustls"))]
identity: None,
#[cfg(feature = "__rustls")]
crls: vec![],
#[cfg(feature = "__tls")]
min_tls_version: None,
#[cfg(feature = "__tls")]
max_tls_version: None,
#[cfg(feature = "__tls")]
tls_info: false,
#[cfg(feature = "__tls")]
tls: TlsBackend::default(),
connector_layers: Vec::new(),
http_version_pref: HttpVersionPref::All,
http09_responses: false,
http1_title_case_headers: false,
http1_allow_obsolete_multiline_headers_in_responses: false,
http1_ignore_invalid_headers_in_responses: false,
http1_allow_spaces_after_header_name_in_responses: false,
#[cfg(feature = "http2")]
http2_initial_stream_window_size: None,
#[cfg(feature = "http2")]
http2_initial_connection_window_size: None,
#[cfg(feature = "http2")]
http2_adaptive_window: false,
#[cfg(feature = "http2")]
http2_max_frame_size: None,
#[cfg(feature = "http2")]
http2_max_header_list_size: None,
#[cfg(feature = "http2")]
http2_keep_alive_interval: None,
#[cfg(feature = "http2")]
http2_keep_alive_timeout: None,
#[cfg(feature = "http2")]
http2_keep_alive_while_idle: false,
local_address: None,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
interface: None,
nodelay: true,
hickory_dns: cfg!(feature = "hickory-dns"),
#[cfg(feature = "cookies")]
cookie_store: None,
https_only: false,
dns_overrides: HashMap::new(),
#[cfg(feature = "http3")]
tls_enable_early_data: false,
#[cfg(feature = "http3")]
quic_max_idle_timeout: None,
#[cfg(feature = "http3")]
quic_stream_receive_window: None,
#[cfg(feature = "http3")]
quic_receive_window: None,
#[cfg(feature = "http3")]
quic_send_window: None,
#[cfg(feature = "http3")]
quic_congestion_bbr: false,
#[cfg(feature = "http3")]
h3_max_field_section_size: None,
#[cfg(feature = "http3")]
h3_send_grease: None,
dns_resolver: None,
#[cfg(unix)]
unix_socket: None,
#[cfg(target_os = "windows")]
windows_named_pipe: None,
},
}
}
}
impl ClientBuilder {
/// Returns a `Client` that uses this `ClientBuilder` configuration.
///
/// # Errors
///
/// This method fails if a TLS backend cannot be initialized, or the resolver
/// cannot load the system configuration.
pub fn build(self) -> crate::Result<Client> {
let config = self.config;
if let Some(err) = config.error {
return Err(err);
}
let mut proxies = config.proxies;
if config.auto_sys_proxy {
proxies.push(ProxyMatcher::system());
}
let proxies = Arc::new(proxies);
#[allow(unused)]
#[cfg(feature = "http3")]
let mut h3_connector = None;
let resolver = {
let mut resolver: Arc<dyn Resolve> = match config.hickory_dns {
false => Arc::new(GaiResolver::new()),
#[cfg(feature = "hickory-dns")]
true => Arc::new(HickoryDnsResolver::default()),
#[cfg(not(feature = "hickory-dns"))]
true => unreachable!("hickory-dns shouldn't be enabled unless the feature is"),
};
if let Some(dns_resolver) = config.dns_resolver {
resolver = dns_resolver;
}
if !config.dns_overrides.is_empty() {
resolver = Arc::new(DnsResolverWithOverrides::new(
resolver,
config.dns_overrides,
));
}
DynResolver::new(resolver)
};
let mut connector_builder = {
#[cfg(feature = "__tls")]
fn user_agent(headers: &HeaderMap) -> Option<HeaderValue> {
headers.get(USER_AGENT).cloned()
}
let mut http = HttpConnector::new_with_resolver(resolver.clone());
http.set_connect_timeout(config.connect_timeout);
#[cfg(all(feature = "http3", feature = "__rustls"))]
let build_h3_connector =
|resolver,
tls,
quic_max_idle_timeout: Option<Duration>,
quic_stream_receive_window,
quic_receive_window,
quic_send_window,
quic_congestion_bbr,
h3_max_field_section_size,
h3_send_grease,
local_address,
http_version_pref: &HttpVersionPref| {
let mut transport_config = TransportConfig::default();
if let Some(max_idle_timeout) = quic_max_idle_timeout {
transport_config.max_idle_timeout(Some(
max_idle_timeout.try_into().map_err(error::builder)?,
));
}
if let Some(stream_receive_window) = quic_stream_receive_window {
transport_config.stream_receive_window(stream_receive_window);
}
if let Some(receive_window) = quic_receive_window {
transport_config.receive_window(receive_window);
}
if let Some(send_window) = quic_send_window {
transport_config.send_window(send_window);
}
if quic_congestion_bbr {
let factory = Arc::new(quinn::congestion::BbrConfig::default());
transport_config.congestion_controller_factory(factory);
}
let mut h3_client_config = H3ClientConfig::default();
if let Some(max_field_section_size) = h3_max_field_section_size {
h3_client_config.max_field_section_size = Some(max_field_section_size);
}
if let Some(send_grease) = h3_send_grease {
h3_client_config.send_grease = Some(send_grease);
}
let res = H3Connector::new(
resolver,
tls,
local_address,
transport_config,
h3_client_config,
);
match res {
Ok(connector) => Ok(Some(connector)),
Err(err) => {
if let HttpVersionPref::Http3 = http_version_pref {
Err(error::builder(err))
} else {
Ok(None)
}
}
}
};
#[cfg(feature = "__tls")]
match config.tls {
#[cfg(feature = "__native-tls")]
TlsBackend::NativeTls => {
let mut tls = TlsConnector::builder();
#[cfg(all(feature = "__native-tls-alpn", not(feature = "http3")))]
{
match config.http_version_pref {
HttpVersionPref::Http1 => {
tls.request_alpns(&["http/1.1"]);
}
#[cfg(feature = "http2")]
HttpVersionPref::Http2 => {
tls.request_alpns(&["h2"]);
}
HttpVersionPref::All => {
tls.request_alpns(&[
#[cfg(feature = "http2")]
"h2",
"http/1.1",
]);
}
}
}
tls.danger_accept_invalid_hostnames(!config.hostname_verification);
tls.danger_accept_invalid_certs(!config.certs_verification);
tls.use_sni(config.tls_sni);
tls.disable_built_in_roots(config.tls_certs_only);
for cert in config.root_certs {
cert.add_to_native_tls(&mut tls);
}
#[cfg(feature = "__native-tls")]
{
if let Some(id) = config.identity {
id.add_to_native_tls(&mut tls)?;
}
}
#[cfg(all(feature = "__rustls", not(feature = "__native-tls")))]
{
// Default backend + rustls Identity doesn't work.
if let Some(_id) = config.identity {
return Err(crate::error::builder("incompatible TLS identity type"));
}
}
if let Some(min_tls_version) = config.min_tls_version {
let protocol = min_tls_version.to_native_tls().ok_or_else(|| {
// TLS v1.3. This would be entirely reasonable,
// native-tls just doesn't support it.
// https://github.com/sfackler/rust-native-tls/issues/140
crate::error::builder("invalid minimum TLS version for backend")
})?;
tls.min_protocol_version(Some(protocol));
}
if let Some(max_tls_version) = config.max_tls_version {
let protocol = max_tls_version.to_native_tls().ok_or_else(|| {
// TLS v1.3.
// We could arguably do max_protocol_version(None), given
// that 1.4 does not exist yet, but that'd get messy in the
// future.
crate::error::builder("invalid maximum TLS version for backend")
})?;
tls.max_protocol_version(Some(protocol));
}
ConnectorBuilder::new_native_tls(
http,
tls,
proxies.clone(),
user_agent(&config.headers),
config.local_address,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
config.interface.as_deref(),
config.nodelay,
config.tls_info,
)?
}
#[cfg(feature = "__native-tls")]
TlsBackend::BuiltNativeTls(conn) => ConnectorBuilder::from_built_native_tls(
http,
conn,
proxies.clone(),
user_agent(&config.headers),
config.local_address,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
config.interface.as_deref(),
config.nodelay,
config.tls_info,
),
#[cfg(feature = "__rustls")]
TlsBackend::BuiltRustls(conn) => {
#[cfg(feature = "http3")]
{
let mut h3_tls = conn.clone();
h3_tls.alpn_protocols = vec!["h3".into()];
h3_connector = build_h3_connector(
resolver.clone(),
h3_tls,
config.quic_max_idle_timeout,
config.quic_stream_receive_window,
config.quic_receive_window,
config.quic_send_window,
config.quic_congestion_bbr,
config.h3_max_field_section_size,
config.h3_send_grease,
config.local_address,
&config.http_version_pref,
)?;
}
ConnectorBuilder::new_rustls_tls(
http,
conn,
proxies.clone(),
user_agent(&config.headers),
config.local_address,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
config.interface.as_deref(),
config.nodelay,
config.tls_info,
)
}
#[cfg(feature = "__rustls")]
TlsBackend::Rustls => {
use crate::tls::{IgnoreHostname, NoVerifier};
// Set TLS versions.
let mut versions = rustls::ALL_VERSIONS.to_vec();
if let Some(min_tls_version) = config.min_tls_version {
versions.retain(|&supported_version| {
match tls::Version::from_rustls(supported_version.version) {
Some(version) => version >= min_tls_version,
// Assume it's so new we don't know about it, allow it
// (as of writing this is unreachable)
None => true,
}
});
}
if let Some(max_tls_version) = config.max_tls_version {
versions.retain(|&supported_version| {
match tls::Version::from_rustls(supported_version.version) {
Some(version) => version <= max_tls_version,
None => false,
}
});
}
if versions.is_empty() {
return Err(crate::error::builder("empty supported tls versions"));
}
// Allow user to have installed a runtime default.
// If not, we ship with _our_ recommended default.
let provider = rustls::crypto::CryptoProvider::get_default()
.map(|arc| arc.clone())
.unwrap_or_else(default_rustls_crypto_provider);
// Build TLS config
let signature_algorithms = provider.signature_verification_algorithms;
let config_builder =
rustls::ClientConfig::builder_with_provider(provider.clone())
.with_protocol_versions(&versions)
.map_err(|_| crate::error::builder("invalid TLS versions"))?;
let config_builder = if !config.certs_verification {
config_builder
.dangerous()
.with_custom_certificate_verifier(Arc::new(NoVerifier))
} else if !config.hostname_verification {
if !config.tls_certs_only {
// Should this just warn? Error for now...
return Err(crate::error::builder(
"disabling rustls hostname verification only allowed with tls_certs_only()"
));
}
config_builder
.dangerous()
.with_custom_certificate_verifier(Arc::new(IgnoreHostname::new(
crate::tls::rustls_store(config.root_certs)?,
signature_algorithms,
)))
} else if !config.tls_certs_only {
// Check for some misconfigurations and report them.
if !config.crls.is_empty() {
return Err(crate::error::builder(
"CRLs only allowed with tls_certs_only()",
));
}
let verifier = if config.root_certs.is_empty() {
rustls_platform_verifier::Verifier::new(provider.clone())
.map_err(crate::error::builder)?
} else {
#[cfg(any(
all(unix, not(target_os = "android")),
target_os = "windows"
))]
{
rustls_platform_verifier::Verifier::new_with_extra_roots(
crate::tls::rustls_der(config.root_certs)?,
provider.clone(),
)
.map_err(crate::error::builder)?
}
#[cfg(not(any(
all(unix, not(target_os = "android")),
target_os = "windows"
)))]
return Err(crate::error::builder(
"rustls-platform-verifier could not load extra certs",
));
};
config_builder
.dangerous()
.with_custom_certificate_verifier(Arc::new(verifier))
} else {
if config.crls.is_empty() {
config_builder.with_root_certificates(crate::tls::rustls_store(
config.root_certs,
)?)
} else {
let crls = config
.crls
.iter()
.map(|e| e.as_rustls_crl())
.collect::<Vec<_>>();
let verifier =
rustls::client::WebPkiServerVerifier::builder_with_provider(
Arc::new(crate::tls::rustls_store(config.root_certs)?),
provider,
)
.with_crls(crls)
.build()
.map_err(|_| {
crate::error::builder("invalid TLS verification settings")
})?;
config_builder.with_webpki_verifier(verifier)
}
};
// Finalize TLS config
let mut tls = if let Some(id) = config.identity {
id.add_to_rustls(config_builder)?
} else {
config_builder.with_no_client_auth()
};
tls.enable_sni = config.tls_sni;
// ALPN protocol
match config.http_version_pref {
HttpVersionPref::Http1 => {
tls.alpn_protocols = vec!["http/1.1".into()];
}
#[cfg(feature = "http2")]
HttpVersionPref::Http2 => {
tls.alpn_protocols = vec!["h2".into()];
}
#[cfg(feature = "http3")]
HttpVersionPref::Http3 => {
// h3 ALPN is not valid over TCP
}
HttpVersionPref::All => {
tls.alpn_protocols = vec![
#[cfg(feature = "http2")]
"h2".into(),
"http/1.1".into(),
];
}
}
#[cfg(feature = "http3")]
{
let mut h3_tls = tls.clone();
h3_tls.enable_early_data = config.tls_enable_early_data;
// h3 ALPN is required over QUIC for HTTP/3
h3_tls.alpn_protocols = vec!["h3".into()];
h3_connector = build_h3_connector(
resolver.clone(),
h3_tls,
config.quic_max_idle_timeout,
config.quic_stream_receive_window,
config.quic_receive_window,
config.quic_send_window,
config.quic_congestion_bbr,
config.h3_max_field_section_size,
config.h3_send_grease,
config.local_address,
&config.http_version_pref,
)?;
}
ConnectorBuilder::new_rustls_tls(
http,
tls,
proxies.clone(),
user_agent(&config.headers),
config.local_address,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
config.interface.as_deref(),
config.nodelay,
config.tls_info,
)
}
#[cfg(any(feature = "__native-tls", feature = "__rustls",))]
TlsBackend::UnknownPreconfigured => {
return Err(crate::error::builder(
"Unknown TLS backend passed to `use_preconfigured_tls`",
));
}
}
#[cfg(not(feature = "__tls"))]
ConnectorBuilder::new(
http,
proxies.clone(),
config.local_address,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
config.interface.as_deref(),
config.nodelay,
)
};
connector_builder.set_timeout(config.connect_timeout);
connector_builder.set_verbose(config.connection_verbose);
connector_builder.set_keepalive(config.tcp_keepalive);
connector_builder.set_keepalive_interval(config.tcp_keepalive_interval);
connector_builder.set_keepalive_retries(config.tcp_keepalive_retries);
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
connector_builder.set_tcp_user_timeout(config.tcp_user_timeout);
#[cfg(feature = "socks")]
connector_builder.set_socks_resolver(resolver);
// TODO: It'd be best to refactor this so the HttpConnector is never
// constructed at all. But there's a lot of code for all the different
// ways TLS can be configured...
#[cfg(unix)]
connector_builder.set_unix_socket(config.unix_socket);
#[cfg(target_os = "windows")]
connector_builder.set_windows_named_pipe(config.windows_named_pipe.clone());
let mut builder =
hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new());
#[cfg(feature = "http2")]
{
if matches!(config.http_version_pref, HttpVersionPref::Http2) {
builder.http2_only(true);
}
if let Some(http2_initial_stream_window_size) = config.http2_initial_stream_window_size
{
builder.http2_initial_stream_window_size(http2_initial_stream_window_size);
}
if let Some(http2_initial_connection_window_size) =
config.http2_initial_connection_window_size
{
builder.http2_initial_connection_window_size(http2_initial_connection_window_size);
}
if config.http2_adaptive_window {
builder.http2_adaptive_window(true);
}
if let Some(http2_max_frame_size) = config.http2_max_frame_size {
builder.http2_max_frame_size(http2_max_frame_size);
}
if let Some(http2_max_header_list_size) = config.http2_max_header_list_size {
builder.http2_max_header_list_size(http2_max_header_list_size);
}
if let Some(http2_keep_alive_interval) = config.http2_keep_alive_interval {
builder.http2_keep_alive_interval(http2_keep_alive_interval);
}
if let Some(http2_keep_alive_timeout) = config.http2_keep_alive_timeout {
builder.http2_keep_alive_timeout(http2_keep_alive_timeout);
}
if config.http2_keep_alive_while_idle {
builder.http2_keep_alive_while_idle(true);
}
}
builder.timer(hyper_util::rt::TokioTimer::new());
builder.pool_timer(hyper_util::rt::TokioTimer::new());
builder.pool_idle_timeout(config.pool_idle_timeout);
builder.pool_max_idle_per_host(config.pool_max_idle_per_host);
if config.http09_responses {
builder.http09_responses(true);
}
if config.http1_title_case_headers {
builder.http1_title_case_headers(true);
}
if config.http1_allow_obsolete_multiline_headers_in_responses {
builder.http1_allow_obsolete_multiline_headers_in_responses(true);
}
if config.http1_ignore_invalid_headers_in_responses {
builder.http1_ignore_invalid_headers_in_responses(true);
}
if config.http1_allow_spaces_after_header_name_in_responses {
builder.http1_allow_spaces_after_header_name_in_responses(true);
}
let proxies_maybe_http_auth = proxies.iter().any(|p| p.maybe_has_http_auth());
let proxies_maybe_http_custom_headers =
proxies.iter().any(|p| p.maybe_has_http_custom_headers());
let redirect_policy_desc = if config.redirect_policy.is_default() {
None
} else {
Some(format!("{:?}", &config.redirect_policy))
};
let hyper_client = builder.build(connector_builder.build(config.connector_layers));
let hyper_service = HyperService {
hyper: hyper_client,
};
let redirect_policy = {
let mut p = TowerRedirectPolicy::new(config.redirect_policy);
p.with_referer(config.referer)
.with_https_only(config.https_only);
p
};
let retry_policy = config.retry_policy.into_policy();
let svc = tower::retry::Retry::new(retry_policy.clone(), hyper_service);
#[cfg(feature = "cookies")]
let svc = CookieService::new(svc, config.cookie_store.clone());
let hyper = FollowRedirect::with_policy(svc, redirect_policy.clone());
#[cfg(any(
feature = "gzip",
feature = "brotli",
feature = "zstd",
feature = "deflate"
))]
let hyper = Decompression::new(hyper)
// set everything to NO, in case tower-http has it enabled but
// reqwest does not. then set to config value if cfg allows.
.no_gzip()
.no_deflate()
.no_br()
.no_zstd();
#[cfg(feature = "gzip")]
let hyper = hyper.gzip(config.accepts.gzip);
#[cfg(feature = "brotli")]
let hyper = hyper.br(config.accepts.brotli);
#[cfg(feature = "zstd")]
let hyper = hyper.zstd(config.accepts.zstd);
#[cfg(feature = "deflate")]
let hyper = hyper.deflate(config.accepts.deflate);
Ok(Client {
inner: Arc::new(ClientRef {
accepts: config.accepts,
#[cfg(feature = "cookies")]
cookie_store: config.cookie_store.clone(),
// Use match instead of map since config is partially moved,
// and it cannot be used in closure
#[cfg(feature = "http3")]
h3_client: match h3_connector {
Some(h3_connector) => {
let h3_service = H3Client::new(h3_connector, config.pool_idle_timeout);
let svc = tower::retry::Retry::new(retry_policy, h3_service);
#[cfg(feature = "cookies")]
let svc = CookieService::new(svc, config.cookie_store);
let svc = FollowRedirect::with_policy(svc, redirect_policy);
#[cfg(any(
feature = "gzip",
feature = "brotli",
feature = "zstd",
feature = "deflate"
))]
let svc = Decompression::new(svc)
// set everything to NO, in case tower-http has it enabled but
// reqwest does not. then set to config value if cfg allows.
.no_gzip()
.no_deflate()
.no_br()
.no_zstd();
#[cfg(feature = "gzip")]
let svc = svc.gzip(config.accepts.gzip);
#[cfg(feature = "brotli")]
let svc = svc.br(config.accepts.brotli);
#[cfg(feature = "zstd")]
let svc = svc.zstd(config.accepts.zstd);
#[cfg(feature = "deflate")]
let svc = svc.deflate(config.accepts.deflate);
Some(svc)
}
None => None,
},
headers: config.headers,
referer: config.referer,
read_timeout: config.read_timeout,
total_timeout: RequestConfig::new(config.timeout),
hyper,
proxies,
proxies_maybe_http_auth,
proxies_maybe_http_custom_headers,
https_only: config.https_only,
redirect_policy_desc,
}),
})
}
// Higher-level options
/// Sets the `User-Agent` header to be used by this client.
///
/// # Example
///
/// ```rust
/// # async fn doc() -> Result<(), reqwest::Error> {
/// // Name your user agent after your app?
/// static APP_USER_AGENT: &str = concat!(
/// env!("CARGO_PKG_NAME"),
/// "/",
/// env!("CARGO_PKG_VERSION"),
/// );
///
/// let client = reqwest::Client::builder()
/// .user_agent(APP_USER_AGENT)
/// .build()?;
/// let res = client.get("https://www.rust-lang.org").send().await?;
/// # Ok(())
/// # }
/// ```
pub fn user_agent<V>(mut self, value: V) -> ClientBuilder
where
V: TryInto<HeaderValue>,
V::Error: Into<http::Error>,
{
match value.try_into() {
Ok(value) => {
self.config.headers.insert(USER_AGENT, value);
}
Err(e) => {
self.config.error = Some(crate::error::builder(e.into()));
}
};
self
}
/// Sets the default headers for every request.
///
/// # Example
///
/// ```rust
/// use reqwest::header;
/// # async fn doc() -> Result<(), reqwest::Error> {
/// let mut headers = header::HeaderMap::new();
/// headers.insert("X-MY-HEADER", header::HeaderValue::from_static("value"));
///
/// // Consider marking security-sensitive headers with `set_sensitive`.
/// let mut auth_value = header::HeaderValue::from_static("secret");
/// auth_value.set_sensitive(true);
/// headers.insert(header::AUTHORIZATION, auth_value);
///
/// // get a client builder
/// let client = reqwest::Client::builder()
/// .default_headers(headers)
/// .build()?;
/// let res = client.get("https://www.rust-lang.org").send().await?;
/// # Ok(())
/// # }
/// ```
pub fn default_headers(mut self, headers: HeaderMap) -> ClientBuilder {
for (key, value) in headers.iter() {
self.config.headers.insert(key, value.clone());
}
self
}
/// Enable a persistent cookie store for the client.
///
/// Cookies received in responses will be preserved and included in
/// additional requests.
///
/// By default, no cookie store is used. Enabling the cookie store
/// with `cookie_store(true)` will set the store to a default implementation.
/// It is **not** necessary to call [cookie_store(true)](crate::ClientBuilder::cookie_store) if [cookie_provider(my_cookie_store)](crate::ClientBuilder::cookie_provider)
/// is used; calling [cookie_store(true)](crate::ClientBuilder::cookie_store) _after_ [cookie_provider(my_cookie_store)](crate::ClientBuilder::cookie_provider) will result
/// in the provided `my_cookie_store` being **overridden** with a default implementation.
///
/// # Optional
///
/// This requires the optional `cookies` feature to be enabled.
#[cfg(feature = "cookies")]
#[cfg_attr(docsrs, doc(cfg(feature = "cookies")))]
pub fn cookie_store(mut self, enable: bool) -> ClientBuilder {
if enable {
self.cookie_provider(Arc::new(cookie::Jar::default()))
} else {
self.config.cookie_store = None;
self
}
}
/// Set the persistent cookie store for the client.
///
/// Cookies received in responses will be passed to this store, and
/// additional requests will query this store for cookies.
///
/// By default, no cookie store is used. It is **not** necessary to also call
/// [cookie_store(true)](crate::ClientBuilder::cookie_store) if [cookie_provider(my_cookie_store)](crate::ClientBuilder::cookie_provider) is used; calling
/// [cookie_store(true)](crate::ClientBuilder::cookie_store) _after_ [cookie_provider(my_cookie_store)](crate::ClientBuilder::cookie_provider) will result
/// in the provided `my_cookie_store` being **overridden** with a default implementation.
///
/// # Optional
///
/// This requires the optional `cookies` feature to be enabled.
#[cfg(feature = "cookies")]
#[cfg_attr(docsrs, doc(cfg(feature = "cookies")))]
pub fn cookie_provider<C: cookie::CookieStore + 'static>(
mut self,
cookie_store: Arc<C>,
) -> ClientBuilder {
self.config.cookie_store = Some(cookie_store as _);
self
}
/// Enable auto gzip decompression by checking the `Content-Encoding` response header.
///
/// If auto gzip decompression is turned on:
///
/// - When sending a request and if the request's headers do not already contain
/// an `Accept-Encoding` **and** `Range` values, the `Accept-Encoding` header is set to `gzip`.
/// The request body is **not** automatically compressed.
/// - When receiving a response, if its headers contain a `Content-Encoding` value of
/// `gzip`, both `Content-Encoding` and `Content-Length` are removed from the
/// headers' set. The response body is automatically decompressed.
///
/// If the `gzip` feature is turned on, the default option is enabled.
///
/// # Optional
///
/// This requires the optional `gzip` feature to be enabled
#[cfg(feature = "gzip")]
#[cfg_attr(docsrs, doc(cfg(feature = "gzip")))]
pub fn gzip(mut self, enable: bool) -> ClientBuilder {
self.config.accepts.gzip = enable;
self
}
/// Enable auto brotli decompression by checking the `Content-Encoding` response header.
///
/// If auto brotli decompression is turned on:
///
/// - When sending a request and if the request's headers do not already contain
/// an `Accept-Encoding` **and** `Range` values, the `Accept-Encoding` header is set to `br`.
/// The request body is **not** automatically compressed.
/// - When receiving a response, if its headers contain a `Content-Encoding` value of
/// `br`, both `Content-Encoding` and `Content-Length` are removed from the
/// headers' set. The response body is automatically decompressed.
///
/// If the `brotli` feature is turned on, the default option is enabled.
///
/// # Optional
///
/// This requires the optional `brotli` feature to be enabled
#[cfg(feature = "brotli")]
#[cfg_attr(docsrs, doc(cfg(feature = "brotli")))]
pub fn brotli(mut self, enable: bool) -> ClientBuilder {
self.config.accepts.brotli = enable;
self
}
/// Enable auto zstd decompression by checking the `Content-Encoding` response header.
///
/// If auto zstd decompression is turned on:
///
/// - When sending a request and if the request's headers do not already contain
/// an `Accept-Encoding` **and** `Range` values, the `Accept-Encoding` header is set to `zstd`.
/// The request body is **not** automatically compressed.
/// - When receiving a response, if its headers contain a `Content-Encoding` value of
/// `zstd`, both `Content-Encoding` and `Content-Length` are removed from the
/// headers' set. The response body is automatically decompressed.
///
/// If the `zstd` feature is turned on, the default option is enabled.
///
/// # Optional
///
/// This requires the optional `zstd` feature to be enabled
#[cfg(feature = "zstd")]
#[cfg_attr(docsrs, doc(cfg(feature = "zstd")))]
pub fn zstd(mut self, enable: bool) -> ClientBuilder {
self.config.accepts.zstd = enable;
self
}
/// Enable auto deflate decompression by checking the `Content-Encoding` response header.
///
/// If auto deflate decompression is turned on:
///
/// - When sending a request and if the request's headers do not already contain
/// an `Accept-Encoding` **and** `Range` values, the `Accept-Encoding` header is set to `deflate`.
/// The request body is **not** automatically compressed.
/// - When receiving a response, if it's headers contain a `Content-Encoding` value that
/// equals to `deflate`, both values `Content-Encoding` and `Content-Length` are removed from the
/// headers' set. The response body is automatically decompressed.
///
/// If the `deflate` feature is turned on, the default option is enabled.
///
/// # Optional
///
/// This requires the optional `deflate` feature to be enabled
#[cfg(feature = "deflate")]
#[cfg_attr(docsrs, doc(cfg(feature = "deflate")))]
pub fn deflate(mut self, enable: bool) -> ClientBuilder {
self.config.accepts.deflate = enable;
self
}
/// Disable auto response body gzip decompression.
///
/// This method exists even if the optional `gzip` feature is not enabled.
/// This can be used to ensure a `Client` doesn't use gzip decompression
/// even if another dependency were to enable the optional `gzip` feature.
pub fn no_gzip(self) -> ClientBuilder {
#[cfg(feature = "gzip")]
{
self.gzip(false)
}
#[cfg(not(feature = "gzip"))]
{
self
}
}
/// Disable auto response body brotli decompression.
///
/// This method exists even if the optional `brotli` feature is not enabled.
/// This can be used to ensure a `Client` doesn't use brotli decompression
/// even if another dependency were to enable the optional `brotli` feature.
pub fn no_brotli(self) -> ClientBuilder {
#[cfg(feature = "brotli")]
{
self.brotli(false)
}
#[cfg(not(feature = "brotli"))]
{
self
}
}
/// Disable auto response body zstd decompression.
///
/// This method exists even if the optional `zstd` feature is not enabled.
/// This can be used to ensure a `Client` doesn't use zstd decompression
/// even if another dependency were to enable the optional `zstd` feature.
pub fn no_zstd(self) -> ClientBuilder {
#[cfg(feature = "zstd")]
{
self.zstd(false)
}
#[cfg(not(feature = "zstd"))]
{
self
}
}
/// Disable auto response body deflate decompression.
///
/// This method exists even if the optional `deflate` feature is not enabled.
/// This can be used to ensure a `Client` doesn't use deflate decompression
/// even if another dependency were to enable the optional `deflate` feature.
pub fn no_deflate(self) -> ClientBuilder {
#[cfg(feature = "deflate")]
{
self.deflate(false)
}
#[cfg(not(feature = "deflate"))]
{
self
}
}
// Redirect options
/// Set a `RedirectPolicy` for this client.
///
/// Default will follow redirects up to a maximum of 10.
pub fn redirect(mut self, policy: redirect::Policy) -> ClientBuilder {
self.config.redirect_policy = policy;
self
}
/// Enable or disable automatic setting of the `Referer` header.
///
/// Default is `true`.
pub fn referer(mut self, enable: bool) -> ClientBuilder {
self.config.referer = enable;
self
}
// Retry options
/// Set a request retry policy.
///
/// Default behavior is to retry protocol NACKs.
// XXX: accept an `impl retry::IntoPolicy` instead?
pub fn retry(mut self, policy: crate::retry::Builder) -> ClientBuilder {
self.config.retry_policy = policy;
self
}
// Proxy options
/// Add a `Proxy` to the list of proxies the `Client` will use.
///
/// # Note
///
/// Adding a proxy will disable the automatic usage of the "system" proxy.
pub fn proxy(mut self, proxy: Proxy) -> ClientBuilder {
self.config.proxies.push(proxy.into_matcher());
self.config.auto_sys_proxy = false;
self
}
/// Clear all `Proxies`, so `Client` will use no proxy anymore.
///
/// # Note
/// To add a proxy exclusion list, use [crate::proxy::Proxy::no_proxy()]
/// on all desired proxies instead.
///
/// This also disables the automatic usage of the "system" proxy.
pub fn no_proxy(mut self) -> ClientBuilder {
self.config.proxies.clear();
self.config.auto_sys_proxy = false;
self
}
// Timeout options
/// Enables a total request timeout.
///
/// The timeout is applied from when the request starts connecting until the
/// response body has finished. Also considered a total deadline.
///
/// Default is no timeout.
pub fn timeout(mut self, timeout: Duration) -> ClientBuilder {
self.config.timeout = Some(timeout);
self
}
/// Enables a read timeout.
///
/// The timeout applies to each read operation, and resets after a
/// successful read. This is more appropriate for detecting stalled
/// connections when the size isn't known beforehand.
///
/// Default is no timeout.
pub fn read_timeout(mut self, timeout: Duration) -> ClientBuilder {
self.config.read_timeout = Some(timeout);
self
}
/// Set a timeout for only the connect phase of a `Client`.
///
/// Default is `None`.
///
/// # Note
///
/// This **requires** the futures be executed in a tokio runtime with
/// a tokio timer enabled.
pub fn connect_timeout(mut self, timeout: Duration) -> ClientBuilder {
self.config.connect_timeout = Some(timeout);
self
}
/// Set whether connections should emit verbose logs.
///
/// Enabling this option will emit [log][] messages at the `TRACE` level
/// for read and write operations on connections.
///
/// [log]: https://crates.io/crates/log
pub fn connection_verbose(mut self, verbose: bool) -> ClientBuilder {
self.config.connection_verbose = verbose;
self
}
// HTTP options
/// Set an optional timeout for idle sockets being kept-alive.
///
/// Pass `None` to disable timeout.
///
/// Default is 90 seconds.
pub fn pool_idle_timeout<D>(mut self, val: D) -> ClientBuilder
where
D: Into<Option<Duration>>,
{
self.config.pool_idle_timeout = val.into();
self
}
/// Sets the maximum idle connection per host allowed in the pool.
///
/// Default is `usize::MAX` (no limit).
pub fn pool_max_idle_per_host(mut self, max: usize) -> ClientBuilder {
self.config.pool_max_idle_per_host = max;
self
}
/// Send headers as title case instead of lowercase.
pub fn http1_title_case_headers(mut self) -> ClientBuilder {
self.config.http1_title_case_headers = true;
self
}
/// Set whether HTTP/1 connections will accept obsolete line folding for
/// header values.
///
/// Newline codepoints (`\r` and `\n`) will be transformed to spaces when
/// parsing.
pub fn http1_allow_obsolete_multiline_headers_in_responses(
mut self,
value: bool,
) -> ClientBuilder {
self.config
.http1_allow_obsolete_multiline_headers_in_responses = value;
self
}
/// Sets whether invalid header lines should be silently ignored in HTTP/1 responses.
pub fn http1_ignore_invalid_headers_in_responses(mut self, value: bool) -> ClientBuilder {
self.config.http1_ignore_invalid_headers_in_responses = value;
self
}
/// Set whether HTTP/1 connections will accept spaces between header
/// names and the colon that follow them in responses.
///
/// Newline codepoints (`\r` and `\n`) will be transformed to spaces when
/// parsing.
pub fn http1_allow_spaces_after_header_name_in_responses(
mut self,
value: bool,
) -> ClientBuilder {
self.config
.http1_allow_spaces_after_header_name_in_responses = value;
self
}
/// Only use HTTP/1.
pub fn http1_only(mut self) -> ClientBuilder {
self.config.http_version_pref = HttpVersionPref::Http1;
self
}
/// Allow HTTP/0.9 responses
pub fn http09_responses(mut self) -> ClientBuilder {
self.config.http09_responses = true;
self
}
/// Only use HTTP/2.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_prior_knowledge(mut self) -> ClientBuilder {
self.config.http_version_pref = HttpVersionPref::Http2;
self
}
/// Only use HTTP/3.
#[cfg(feature = "http3")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3",))))]
pub fn http3_prior_knowledge(mut self) -> ClientBuilder {
self.config.http_version_pref = HttpVersionPref::Http3;
self
}
/// Sets the `SETTINGS_INITIAL_WINDOW_SIZE` option for HTTP2 stream-level flow control.
///
/// Default is currently 65,535 but may change internally to optimize for common uses.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_initial_stream_window_size(mut self, sz: impl Into<Option<u32>>) -> ClientBuilder {
self.config.http2_initial_stream_window_size = sz.into();
self
}
/// Sets the max connection-level flow control for HTTP2
///
/// Default is currently 65,535 but may change internally to optimize for common uses.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_initial_connection_window_size(
mut self,
sz: impl Into<Option<u32>>,
) -> ClientBuilder {
self.config.http2_initial_connection_window_size = sz.into();
self
}
/// Sets whether to use an adaptive flow control.
///
/// Enabling this will override the limits set in `http2_initial_stream_window_size` and
/// `http2_initial_connection_window_size`.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_adaptive_window(mut self, enabled: bool) -> ClientBuilder {
self.config.http2_adaptive_window = enabled;
self
}
/// Sets the maximum frame size to use for HTTP2.
///
/// Default is currently 16,384 but may change internally to optimize for common uses.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_max_frame_size(mut self, sz: impl Into<Option<u32>>) -> ClientBuilder {
self.config.http2_max_frame_size = sz.into();
self
}
/// Sets the maximum size of received header frames for HTTP2.
///
/// Default is currently 16KB, but can change.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_max_header_list_size(mut self, max_header_size_bytes: u32) -> ClientBuilder {
self.config.http2_max_header_list_size = Some(max_header_size_bytes);
self
}
/// Sets an interval for HTTP2 Ping frames should be sent to keep a connection alive.
///
/// Pass `None` to disable HTTP2 keep-alive.
/// Default is currently disabled.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_keep_alive_interval(
mut self,
interval: impl Into<Option<Duration>>,
) -> ClientBuilder {
self.config.http2_keep_alive_interval = interval.into();
self
}
/// Sets a timeout for receiving an acknowledgement of the keep-alive ping.
///
/// If the ping is not acknowledged within the timeout, the connection will be closed.
/// Does nothing if `http2_keep_alive_interval` is disabled.
/// Default is currently disabled.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_keep_alive_timeout(mut self, timeout: Duration) -> ClientBuilder {
self.config.http2_keep_alive_timeout = Some(timeout);
self
}
/// Sets whether HTTP2 keep-alive should apply while the connection is idle.
///
/// If disabled, keep-alive pings are only sent while there are open request/responses streams.
/// If enabled, pings are also sent when no streams are active.
/// Does nothing if `http2_keep_alive_interval` is disabled.
/// Default is `false`.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub fn http2_keep_alive_while_idle(mut self, enabled: bool) -> ClientBuilder {
self.config.http2_keep_alive_while_idle = enabled;
self
}
// TCP options
/// Set whether sockets have `TCP_NODELAY` enabled.
///
/// Default is `true`.
pub fn tcp_nodelay(mut self, enabled: bool) -> ClientBuilder {
self.config.nodelay = enabled;
self
}
/// Bind to a local IP Address.
///
/// # Example
///
/// ```
/// # fn doc() -> Result<(), reqwest::Error> {
/// use std::net::IpAddr;
/// let local_addr = IpAddr::from([12, 4, 1, 8]);
/// let client = reqwest::Client::builder()
/// .local_address(local_addr)
/// .build()?;
/// # Ok(())
/// # }
/// ```
pub fn local_address<T>(mut self, addr: T) -> ClientBuilder
where
T: Into<Option<IpAddr>>,
{
self.config.local_address = addr.into();
self
}
/// Bind connections only on the specified network interface.
///
/// This option is only available on the following operating systems:
///
/// - Android
/// - Fuchsia
/// - Linux,
/// - macOS and macOS-like systems (iOS, tvOS, watchOS and visionOS)
/// - Solaris and illumos
///
/// On Android, Linux, and Fuchsia, this uses the
/// [`SO_BINDTODEVICE`][man-7-socket] socket option. On macOS and macOS-like
/// systems, Solaris, and illumos, this instead uses the [`IP_BOUND_IF` and
/// `IPV6_BOUND_IF`][man-7p-ip] socket options (as appropriate).
///
/// Note that connections will fail if the provided interface name is not a
/// network interface that currently exists when a connection is established.
///
/// # Example
///
/// ```
/// # fn doc() -> Result<(), reqwest::Error> {
/// let interface = "lo";
/// let client = reqwest::Client::builder()
/// .interface(interface)
/// .build()?;
/// # Ok(())
/// # }
/// ```
///
/// [man-7-socket]: https://man7.org/linux/man-pages/man7/socket.7.html
/// [man-7p-ip]: https://docs.oracle.com/cd/E86824_01/html/E54777/ip-7p.html
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
pub fn interface(mut self, interface: &str) -> ClientBuilder {
self.config.interface = Some(interface.to_string());
self
}
/// Set that all sockets have `SO_KEEPALIVE` set with the supplied duration.
///
/// If `None`, the option will not be set.
pub fn tcp_keepalive<D>(mut self, val: D) -> ClientBuilder
where
D: Into<Option<Duration>>,
{
self.config.tcp_keepalive = val.into();
self
}
/// Set that all sockets have `SO_KEEPALIVE` set with the supplied interval.
///
/// If `None`, the option will not be set.
pub fn tcp_keepalive_interval<D>(mut self, val: D) -> ClientBuilder
where
D: Into<Option<Duration>>,
{
self.config.tcp_keepalive_interval = val.into();
self
}
/// Set that all sockets have `SO_KEEPALIVE` set with the supplied retry count.
///
/// If `None`, the option will not be set.
pub fn tcp_keepalive_retries<C>(mut self, retries: C) -> ClientBuilder
where
C: Into<Option<u32>>,
{
self.config.tcp_keepalive_retries = retries.into();
self
}
/// Set that all sockets have `TCP_USER_TIMEOUT` set with the supplied duration.
///
/// This option controls how long transmitted data may remain unacknowledged before
/// the connection is force-closed.
///
/// If `None`, the option will not be set.
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
pub fn tcp_user_timeout<D>(mut self, val: D) -> ClientBuilder
where
D: Into<Option<Duration>>,
{
self.config.tcp_user_timeout = val.into();
self
}
// Alt Transports
/// Set that all connections will use this Unix socket.
///
/// If a request URI uses the `https` scheme, TLS will still be used over
/// the Unix socket.
///
/// # Note
///
/// This option is not compatible with any of the TCP or Proxy options.
/// Setting this will ignore all those options previously set.
///
/// Likewise, DNS resolution will not be done on the domain name.
#[cfg(unix)]
pub fn unix_socket(mut self, path: impl UnixSocketProvider) -> ClientBuilder {
self.config.unix_socket = Some(path.reqwest_uds_path(crate::connect::uds::Internal).into());
self
}
/// Set that all connections will use this Windows named pipe.
///
/// If a request URI uses the `https` scheme, TLS will still be used over
/// the Windows named pipe.
///
/// # Note
///
/// This option is not compatible with any of the TCP or Proxy options.
/// Setting this will ignore all those options previously set.
///
/// Likewise, DNS resolution will not be done on the domain name.
#[cfg(target_os = "windows")]
pub fn windows_named_pipe(mut self, pipe: impl WindowsNamedPipeProvider) -> ClientBuilder {
self.config.windows_named_pipe = Some(
pipe.reqwest_windows_named_pipe_path(crate::connect::windows_named_pipe::Internal)
.into(),
);
self
}
// TLS options
/// Add custom certificate roots.
///
/// This can be used to connect to a server that has a self-signed
/// certificate for example.
///
/// This optional attempts to merge with any native or built-in roots.
///
/// # Errors
///
/// If the selected TLS backend or verifier does not support merging
/// certificates, the builder will return an error.
///
/// # Optional
///
/// This requires the optional `default-tls`, `native-tls`, or `rustls(-...)`
/// feature to be enabled.
#[cfg(feature = "__tls")]
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "default-tls", feature = "native-tls", feature = "rustls")))
)]
pub fn tls_certs_merge(
mut self,
certs: impl IntoIterator<Item = Certificate>,
) -> ClientBuilder {
self.config.root_certs.extend(certs);
self
}
/// Use only the provided certificate roots.
///
/// This can be used to connect to a server that has a self-signed
/// certificate for example.
///
/// This option disables any native or built-in roots, and **only** uses
/// the roots provided to this method.
///
/// # Optional
///
/// This requires the optional `default-tls`, `native-tls`, or `rustls(-...)`
/// feature to be enabled.
#[cfg(feature = "__tls")]
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "default-tls", feature = "native-tls", feature = "rustls")))
)]
pub fn tls_certs_only(mut self, certs: impl IntoIterator<Item = Certificate>) -> ClientBuilder {
self.config.root_certs.extend(certs);
self.config.tls_certs_only = true;
self
}
/// Deprecated: use [`ClientBuilder::tls_certs_merge()`] or
/// [`ClientBuilder::tls_certs_only()`] instead.
#[cfg(feature = "__tls")]
pub fn add_root_certificate(mut self, cert: Certificate) -> ClientBuilder {
self.config.root_certs.push(cert);
self
}
/// Add multiple certificate revocation lists.
///
/// # Errors
///
/// This only works if also using only provided root certificates. This
/// cannot work with the native verifier.
///
/// If CRLs are added but `tls_certs_only()` is not called, the builder
/// will return an error.
///
/// # Optional
///
/// This requires the `rustls(-...)` Cargo feature enabled.
#[cfg(feature = "__rustls")]
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
pub fn tls_crls_only(
mut self,
crls: impl IntoIterator<Item = CertificateRevocationList>,
) -> ClientBuilder {
self.config.crls.extend(crls);
self
}
/// Deprecated: use [`ClientBuilder::tls_crls_only()`] instead.
#[cfg(feature = "__rustls")]
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
pub fn add_crl(mut self, crl: CertificateRevocationList) -> ClientBuilder {
self.config.crls.push(crl);
self
}
/// Deprecated: use [`ClientBuilder::tls_crls_only()`] instead.
#[cfg(feature = "__rustls")]
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
pub fn add_crls(
mut self,
crls: impl IntoIterator<Item = CertificateRevocationList>,
) -> ClientBuilder {
self.config.crls.extend(crls);
self
}
/// Sets the identity to be used for client certificate authentication.
///
/// # Optional
///
/// This requires the optional `native-tls` or `rustls(-...)` feature to be
/// enabled.
#[cfg(any(feature = "__native-tls", feature = "__rustls"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "native-tls", feature = "rustls"))))]
pub fn identity(mut self, identity: Identity) -> ClientBuilder {
self.config.identity = Some(identity);
self
}
/// Controls the use of hostname verification.
///
/// Defaults to `false`.
///
/// # Warning
///
/// You should think very carefully before you use this method. If
/// hostname verification is not used, any valid certificate for any
/// site will be trusted for use from any other. This introduces a
/// significant vulnerability to man-in-the-middle attacks.
///
/// # Errors
///
/// Depending on the TLS backend and verifier, this might not work with
/// native certificates, only those added with [`ClientBuilder::tls_certs_only()`].
///
/// # Optional
///
/// This requires the optional `default-tls`, `native-tls`, or `rustls(-...)`
/// feature to be enabled.
#[cfg(feature = "__tls")]
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "default-tls", feature = "native-tls", feature = "rustls")))
)]
pub fn tls_danger_accept_invalid_hostnames(
mut self,
accept_invalid_hostname: bool,
) -> ClientBuilder {
self.config.hostname_verification = !accept_invalid_hostname;
self
}
/// Deprecated: use [`ClientBuilder::tls_danger_accept_invalid_hostnames()`] instead.
#[cfg(feature = "__tls")]
pub fn danger_accept_invalid_hostnames(self, accept_invalid_hostname: bool) -> ClientBuilder {
self.tls_danger_accept_invalid_hostnames(accept_invalid_hostname)
}
/// Controls the use of certificate validation.
///
/// Defaults to `false`.
///
/// # Warning
///
/// You should think very carefully before using this method. If
/// invalid certificates are trusted, *any* certificate for *any* site
/// will be trusted for use. This includes expired certificates. This
/// introduces significant vulnerabilities, and should only be used
/// as a last resort.
///
/// # Optional
///
/// This requires the optional `default-tls`, `native-tls`, or `rustls(-...)`
/// feature to be enabled.
#[cfg(feature = "__tls")]
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "default-tls", feature = "native-tls", feature = "rustls")))
)]
pub fn tls_danger_accept_invalid_certs(mut self, accept_invalid_certs: bool) -> ClientBuilder {
self.config.certs_verification = !accept_invalid_certs;
self
}
/// Deprecated: use [`ClientBuilder::tls_danger_accept_invalid_certs()`] instead.
#[cfg(feature = "__tls")]
pub fn danger_accept_invalid_certs(self, accept_invalid_certs: bool) -> ClientBuilder {
self.tls_danger_accept_invalid_certs(accept_invalid_certs)
}
/// Controls the use of TLS server name indication.
///
/// Defaults to `true`.
///
/// # Optional
///
/// This requires the optional `default-tls`, `native-tls`, or `rustls(-...)`
/// feature to be enabled.
#[cfg(feature = "__tls")]
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "default-tls", feature = "native-tls", feature = "rustls")))
)]
pub fn tls_sni(mut self, tls_sni: bool) -> ClientBuilder {
self.config.tls_sni = tls_sni;
self
}
/// Set the minimum required TLS version for connections.
///
/// By default, the TLS backend's own default is used.
///
/// # Errors
///
/// A value of `tls::Version::TLS_1_3` will cause an error with the
/// `native-tls` backend. This does not mean the version
/// isn't supported, just that it can't be set as a minimum due to
/// technical limitations.
///
/// # Optional
///
/// This requires the optional `default-tls`, `native-tls`, or `rustls(-...)`
/// feature to be enabled.
#[cfg(feature = "__tls")]
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "default-tls", feature = "native-tls", feature = "rustls")))
)]
pub fn tls_version_min(mut self, version: tls::Version) -> ClientBuilder {
self.config.min_tls_version = Some(version);
self
}
/// Deprecated: use [`ClientBuilder::tls_version_min()`] instead.
#[cfg(feature = "__tls")]
pub fn min_tls_version(self, version: tls::Version) -> ClientBuilder {
self.tls_version_min(version)
}
/// Set the maximum allowed TLS version for connections.
///
/// By default, there's no maximum.
///
/// # Errors
///
/// A value of `tls::Version::TLS_1_3` will cause an error with the
/// `native-tls` backend. This does not mean the version
/// isn't supported, just that it can't be set as a maximum due to
/// technical limitations.
///
/// Cannot set a maximum outside the protocol versions supported by
/// `rustls` with the `rustls` backend.
///
/// # Optional
///
/// This requires the optional `default-tls`, `native-tls`, or `rustls(-...)`
/// feature to be enabled.
#[cfg(feature = "__tls")]
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "default-tls", feature = "native-tls", feature = "rustls")))
)]
pub fn tls_version_max(mut self, version: tls::Version) -> ClientBuilder {
self.config.max_tls_version = Some(version);
self
}
/// Deprecated: use [`ClientBuilder::tls_version_max()`] instead.
#[cfg(feature = "__tls")]
pub fn max_tls_version(self, version: tls::Version) -> ClientBuilder {
self.tls_version_max(version)
}
/// Force using the native TLS backend.
///
/// Since multiple TLS backends can be optionally enabled, this option will
/// force the `native-tls` backend to be used for this `Client`.
///
/// # Optional
///
/// This requires the optional `native-tls` feature to be enabled.
#[cfg(feature = "__native-tls")]
#[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))]
pub fn tls_backend_native(mut self) -> ClientBuilder {
self.config.tls = TlsBackend::NativeTls;
self
}
/// Deprecated: use [`ClientBuilder::tls_backend_native()`] instead.
#[cfg(feature = "__native-tls")]
pub fn use_native_tls(self) -> ClientBuilder {
self.tls_backend_native()
}
/// Force using the Rustls TLS backend.
///
/// Since multiple TLS backends can be optionally enabled, this option will
/// force the `rustls` backend to be used for this `Client`.
///
/// # Optional
///
/// This requires the optional `rustls(-...)` feature to be enabled.
#[cfg(feature = "__rustls")]
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
pub fn tls_backend_rustls(mut self) -> ClientBuilder {
self.config.tls = TlsBackend::Rustls;
self
}
/// Deprecated: use [`ClientBuilder::tls_backend_rustls()`] instead.
#[cfg(feature = "__rustls")]
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
pub fn use_rustls_tls(self) -> ClientBuilder {
self.tls_backend_rustls()
}
/// Use a preconfigured TLS backend.
///
/// If the passed `Any` argument is not a TLS backend that reqwest
/// understands, the `ClientBuilder` will error when calling `build`.
///
/// # Advanced
///
/// <div class="warning">
///
/// There is no semver stability on the internals of this method. Use at
/// your own risk.
///
/// </div>
///
/// This is an advanced option, and can be somewhat brittle. Usage requires
/// keeping the preconfigured TLS argument version in sync with reqwest,
/// since version mismatches will result in an "unknown" TLS backend.
///
/// If possible, it's preferable to use the methods on `ClientBuilder`
/// to configure reqwest's TLS.
///
/// # Optional
///
/// This requires one of the optional features `native-tls` or
/// `rustls(-...)` to be enabled.
#[cfg(any(feature = "__native-tls", feature = "__rustls",))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "native-tls", feature = "rustls"))))]
pub fn tls_backend_preconfigured(mut self, tls: impl Any) -> ClientBuilder {
let mut tls = Some(tls);
#[cfg(feature = "__native-tls")]
{
if let Some(conn) = (&mut tls as &mut dyn Any).downcast_mut::<Option<TlsConnector>>() {
let tls = conn.take().expect("is definitely Some");
let tls = crate::tls::TlsBackend::BuiltNativeTls(tls);
self.config.tls = tls;
return self;
}
}
#[cfg(feature = "__rustls")]
{
if let Some(conn) =
(&mut tls as &mut dyn Any).downcast_mut::<Option<rustls::ClientConfig>>()
{
let tls = conn.take().expect("is definitely Some");
let tls = crate::tls::TlsBackend::BuiltRustls(tls);
self.config.tls = tls;
return self;
}
}
// Otherwise, we don't recognize the TLS backend!
self.config.tls = crate::tls::TlsBackend::UnknownPreconfigured;
self
}
/// Deprecated: use [`ClientBuilder::tls_backend_preconfigured()`] instead.
#[cfg(any(feature = "__native-tls", feature = "__rustls",))]
pub fn use_preconfigured_tls(self, tls: impl Any) -> ClientBuilder {
self.tls_backend_preconfigured(tls)
}
/// Add TLS information as `TlsInfo` extension to responses.
///
/// # Optional
///
/// This requires the optional `default-tls`, `native-tls`, or `rustls(-...)`
/// feature to be enabled.
#[cfg(feature = "__tls")]
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "default-tls", feature = "native-tls", feature = "rustls")))
)]
pub fn tls_info(mut self, tls_info: bool) -> ClientBuilder {
self.config.tls_info = tls_info;
self
}
/// Restrict the Client to be used with HTTPS only requests.
///
/// Defaults to false.
pub fn https_only(mut self, enabled: bool) -> ClientBuilder {
self.config.https_only = enabled;
self
}
/// Enables the [hickory-dns](hickory_resolver) async resolver instead of a default threadpool
/// using `getaddrinfo`.
///
/// If the `hickory-dns` feature is turned on, the default option is enabled.
///
/// # Optional
///
/// This requires the optional `hickory-dns` feature to be enabled
///
/// # Warning
///
/// The hickory resolver does not work exactly the same, or on all the platforms
/// that the default resolver does
#[cfg(feature = "hickory-dns")]
#[cfg_attr(docsrs, doc(cfg(feature = "hickory-dns")))]
pub fn hickory_dns(mut self, enable: bool) -> ClientBuilder {
self.config.hickory_dns = enable;
self
}
/// Disables the hickory-dns async resolver.
///
/// This method exists even if the optional `hickory-dns` feature is not enabled.
/// This can be used to ensure a `Client` doesn't use the hickory-dns async resolver
/// even if another dependency were to enable the optional `hickory-dns` feature.
pub fn no_hickory_dns(self) -> ClientBuilder {
#[cfg(feature = "hickory-dns")]
{
self.hickory_dns(false)
}
#[cfg(not(feature = "hickory-dns"))]
{
self
}
}
/// Override DNS resolution for specific domains to a particular IP address.
///
/// Set the port to `0` to use the conventional port for the given scheme (e.g. 80 for http).
/// Ports in the URL itself will always be used instead of the port in the overridden addr.
pub fn resolve(self, domain: &str, addr: SocketAddr) -> ClientBuilder {
self.resolve_to_addrs(domain, &[addr])
}
/// Override DNS resolution for specific domains to particular IP addresses.
///
/// Set the port to `0` to use the conventional port for the given scheme (e.g. 80 for http).
/// Ports in the URL itself will always be used instead of the port in the overridden addr.
pub fn resolve_to_addrs(mut self, domain: &str, addrs: &[SocketAddr]) -> ClientBuilder {
self.config
.dns_overrides
.insert(domain.to_ascii_lowercase(), addrs.to_vec());
self
}
/// Override the DNS resolver implementation.
///
/// Overrides for specific names passed to `resolve` and `resolve_to_addrs` will
/// still be applied on top of this resolver.
pub fn dns_resolver<R>(mut self, resolver: R) -> ClientBuilder
where
R: crate::dns::resolve::IntoResolve,
{
self.config.dns_resolver = Some(resolver.into_resolve());
self
gitextract_aj92qe_u/
├── .github/
│ ├── FUNDING.yml
│ ├── dependabot.yml
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── examples/
│ ├── blocking.rs
│ ├── connect_via_lower_priority_tokio_runtime.rs
│ ├── form.rs
│ ├── h3_simple.rs
│ ├── json_dynamic.rs
│ ├── json_typed.rs
│ ├── simple.rs
│ ├── tor_socks.rs
│ └── wasm_github_fetch/
│ ├── .gitignore
│ ├── Cargo.toml
│ ├── README.md
│ ├── index.js
│ ├── osv-scanner.toml
│ ├── package.json
│ ├── src/
│ │ └── lib.rs
│ └── webpack.config.js
├── src/
│ ├── async_impl/
│ │ ├── body.rs
│ │ ├── client.rs
│ │ ├── h3_client/
│ │ │ ├── connect.rs
│ │ │ ├── dns.rs
│ │ │ ├── mod.rs
│ │ │ └── pool.rs
│ │ ├── mod.rs
│ │ ├── multipart.rs
│ │ ├── request.rs
│ │ ├── response.rs
│ │ └── upgrade.rs
│ ├── blocking/
│ │ ├── body.rs
│ │ ├── client.rs
│ │ ├── mod.rs
│ │ ├── multipart.rs
│ │ ├── request.rs
│ │ ├── response.rs
│ │ └── wait.rs
│ ├── config.rs
│ ├── connect.rs
│ ├── cookie.rs
│ ├── dns/
│ │ ├── gai.rs
│ │ ├── hickory.rs
│ │ ├── mod.rs
│ │ └── resolve.rs
│ ├── error.rs
│ ├── into_url.rs
│ ├── lib.rs
│ ├── proxy.rs
│ ├── redirect.rs
│ ├── response.rs
│ ├── retry.rs
│ ├── tls.rs
│ ├── util.rs
│ └── wasm/
│ ├── body.rs
│ ├── client.rs
│ ├── mod.rs
│ ├── multipart.rs
│ ├── request.rs
│ └── response.rs
└── tests/
├── badssl.rs
├── blocking.rs
├── brotli.rs
├── ci.rs
├── client.rs
├── connector_layers.rs
├── cookie.rs
├── deflate.rs
├── gzip.rs
├── http3.rs
├── multipart.rs
├── not_tcp.rs
├── proxy.rs
├── redirect.rs
├── retry.rs
├── support/
│ ├── crl.pem
│ ├── delay_layer.rs
│ ├── delay_server.rs
│ ├── error.rs
│ ├── mod.rs
│ ├── not_tcp.rs
│ ├── server.cert
│ ├── server.key
│ └── server.rs
├── timeouts.rs
├── upgrade.rs
├── wasm_simple.rs
└── zstd.rs
SYMBOL INDEX (1606 symbols across 71 files)
FILE: examples/blocking.rs
function main (line 4) | fn main() -> Result<(), Box<dyn std::error::Error>> {
FILE: examples/connect_via_lower_priority_tokio_runtime.rs
function main (line 21) | async fn main() -> Result<(), reqwest::Error> {
function init_background_runtime (line 70) | pub(crate) fn init_background_runtime() {
function process_cpu_work (line 106) | async fn process_cpu_work() {
function send_to_background_runtime (line 118) | fn send_to_background_runtime(future: impl Future<Output = ()> + Send + ...
type BackgroundProcessorLayer (line 146) | pub struct BackgroundProcessorLayer {}
method new (line 148) | pub fn new() -> Self {
type Service (line 153) | type Service = BackgroundProcessor<S>;
method layer (line 154) | fn layer(&self, service: S) -> Self::Service {
method fmt (line 160) | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
type BackgroundProcessor (line 167) | pub struct BackgroundProcessor<S> {
function new (line 172) | pub fn new(inner: S) -> Self {
type Response (line 184) | type Response = S::Response;
type Error (line 186) | type Error = BoxError;
type Future (line 188) | type Future = BackgroundResponseFuture<S::Response>;
type Output (line 242) | type Output = Result<S, BoxError>;
method poll (line 244) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Outp...
function poll_ready (line 190) | fn poll_ready(
function call (line 200) | fn call(&mut self, req: Request) -> Self::Future {
function new (line 233) | pub(crate) fn new(rx: tokio::sync::oneshot::Receiver<Result<S, BoxError>...
function main (line 264) | fn main() {}
FILE: examples/form.rs
function main (line 8) | async fn main() {
function main (line 23) | fn main() {}
FILE: examples/h3_simple.rs
function main (line 9) | async fn main() -> Result<(), reqwest::Error> {
function main (line 44) | fn main() {}
FILE: examples/json_dynamic.rs
function main (line 11) | async fn main() -> Result<(), reqwest::Error> {
FILE: examples/json_typed.rs
type Post (line 11) | struct Post {
function main (line 23) | async fn main() -> Result<(), reqwest::Error> {
FILE: examples/simple.rs
function main (line 8) | async fn main() -> Result<(), reqwest::Error> {
function main (line 40) | fn main() {}
FILE: examples/tor_socks.rs
function main (line 7) | async fn main() -> Result<(), reqwest::Error> {
FILE: examples/wasm_github_fetch/src/lib.rs
type Branch (line 12) | pub struct Branch {
type Commit (line 18) | pub struct Commit {
type CommitDetails (line 24) | pub struct CommitDetails {
type Signature (line 30) | pub struct Signature {
function run (line 36) | pub async fn run() -> Result<JsValue, JsValue> {
FILE: src/async_impl/body.rs
type Body (line 18) | pub struct Body {
method as_bytes (line 53) | pub fn as_bytes(&self) -> Option<&[u8]> {
method wrap_stream (line 85) | pub fn wrap_stream<S>(stream: S) -> Body
method stream (line 95) | pub(crate) fn stream<S>(stream: S) -> Body
method empty (line 115) | pub(crate) fn empty() -> Body {
method reusable (line 119) | pub(crate) fn reusable(chunk: Bytes) -> Body {
method wrap (line 138) | pub fn wrap<B>(inner: B) -> Body
method try_clone (line 153) | pub(crate) fn try_clone(&self) -> Option<Body> {
method content_length (line 161) | pub(crate) fn content_length(&self) -> Option<u64> {
method from (line 191) | fn from(bytes: Bytes) -> Body {
method from (line 198) | fn from(vec: Vec<u8>) -> Body {
method from (line 205) | fn from(s: &'static [u8]) -> Body {
method from (line 212) | fn from(s: String) -> Body {
method from (line 219) | fn from(s: &'static str) -> Body {
method from (line 228) | fn from(file: File) -> Body {
method fmt (line 234) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Inner (line 22) | enum Inner {
method default (line 171) | fn default() -> Body {
type Data (line 240) | type Data = Bytes;
type Error (line 241) | type Error = crate::Error;
method poll_frame (line 243) | fn poll_frame(
method size_hint (line 263) | fn size_hint(&self) -> http_body::SizeHint {
method is_end_stream (line 270) | fn is_end_stream(&self) -> bool {
function total_timeout (line 280) | pub(crate) fn total_timeout<B>(body: B, timeout: Pin<Box<Sleep>>) -> Tot...
function with_read_timeout (line 287) | pub(crate) fn with_read_timeout<B>(body: B, timeout: Duration) -> ReadTi...
type Data (line 300) | type Data = B::Data;
type Error (line 301) | type Error = crate::Error;
function poll_frame (line 303) | fn poll_frame(
function size_hint (line 318) | fn size_hint(&self) -> http_body::SizeHint {
function is_end_stream (line 323) | fn is_end_stream(&self) -> bool {
type Data (line 333) | type Data = B::Data;
type Error (line 334) | type Error = crate::Error;
function poll_frame (line 336) | fn poll_frame(
function size_hint (line 363) | fn size_hint(&self) -> http_body::SizeHint {
function is_end_stream (line 368) | fn is_end_stream(&self) -> bool {
type ResponseBody (line 373) | pub(crate) type ResponseBody =
function boxed (line 376) | pub(crate) fn boxed<B>(body: B) -> ResponseBody
function response (line 386) | pub(crate) fn response<B>(
function box_err (line 408) | fn box_err<E>(err: E) -> Box<dyn std::error::Error + Send + Sync>
type Data (line 431) | type Data = Bytes;
type Error (line 432) | type Error = B::Error;
function poll_frame (line 434) | fn poll_frame(
function size_hint (line 446) | fn size_hint(&self) -> http_body::SizeHint {
function is_end_stream (line 451) | fn is_end_stream(&self) -> bool {
function test_as_bytes (line 463) | fn test_as_bytes() {
function body_exact_length (line 470) | fn body_exact_length() {
FILE: src/async_impl/client.rs
type Client (line 93) | pub struct Client {
method new (line 2477) | pub fn new() -> Client {
method builder (line 2484) | pub fn builder() -> ClientBuilder {
method get (line 2493) | pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method post (line 2502) | pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method put (line 2511) | pub fn put<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method patch (line 2520) | pub fn patch<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method delete (line 2529) | pub fn delete<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method head (line 2538) | pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method request (line 2550) | pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBu...
method execute (line 2567) | pub fn execute(
method execute_request (line 2574) | pub(super) fn execute_request(&self, req: Request) -> Pending {
method proxy_auth (line 2654) | fn proxy_auth(&self, dst: &Uri, headers: &mut HeaderMap) {
method proxy_custom_headers (line 2678) | fn proxy_custom_headers(&self, dst: &Uri, headers: &mut HeaderMap) {
method fmt (line 2699) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Response (line 2707) | type Response = Response;
type Error (line 2708) | type Error = crate::Error;
type Future (line 2709) | type Future = Pending;
method poll_ready (line 2711) | fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Sel...
method call (line 2715) | fn call(&mut self, req: Request) -> Self::Future {
type ClientBuilder (line 99) | pub struct ClientBuilder {
method new (line 280) | pub fn new() -> Self {
method build (line 403) | pub fn build(self) -> crate::Result<Client> {
method user_agent (line 1119) | pub fn user_agent<V>(mut self, value: V) -> ClientBuilder
method default_headers (line 1157) | pub fn default_headers(mut self, headers: HeaderMap) -> ClientBuilder {
method cookie_store (line 1180) | pub fn cookie_store(mut self, enable: bool) -> ClientBuilder {
method cookie_provider (line 1204) | pub fn cookie_provider<C: cookie::CookieStore + 'static>(
method gzip (line 1230) | pub fn gzip(mut self, enable: bool) -> ClientBuilder {
method brotli (line 1253) | pub fn brotli(mut self, enable: bool) -> ClientBuilder {
method zstd (line 1276) | pub fn zstd(mut self, enable: bool) -> ClientBuilder {
method deflate (line 1299) | pub fn deflate(mut self, enable: bool) -> ClientBuilder {
method no_gzip (line 1309) | pub fn no_gzip(self) -> ClientBuilder {
method no_brotli (line 1326) | pub fn no_brotli(self) -> ClientBuilder {
method no_zstd (line 1343) | pub fn no_zstd(self) -> ClientBuilder {
method no_deflate (line 1360) | pub fn no_deflate(self) -> ClientBuilder {
method redirect (line 1377) | pub fn redirect(mut self, policy: redirect::Policy) -> ClientBuilder {
method referer (line 1385) | pub fn referer(mut self, enable: bool) -> ClientBuilder {
method retry (line 1396) | pub fn retry(mut self, policy: crate::retry::Builder) -> ClientBuilder {
method proxy (line 1408) | pub fn proxy(mut self, proxy: Proxy) -> ClientBuilder {
method no_proxy (line 1421) | pub fn no_proxy(mut self) -> ClientBuilder {
method timeout (line 1435) | pub fn timeout(mut self, timeout: Duration) -> ClientBuilder {
method read_timeout (line 1447) | pub fn read_timeout(mut self, timeout: Duration) -> ClientBuilder {
method connect_timeout (line 1460) | pub fn connect_timeout(mut self, timeout: Duration) -> ClientBuilder {
method connection_verbose (line 1471) | pub fn connection_verbose(mut self, verbose: bool) -> ClientBuilder {
method pool_idle_timeout (line 1483) | pub fn pool_idle_timeout<D>(mut self, val: D) -> ClientBuilder
method pool_max_idle_per_host (line 1494) | pub fn pool_max_idle_per_host(mut self, max: usize) -> ClientBuilder {
method http1_title_case_headers (line 1500) | pub fn http1_title_case_headers(mut self) -> ClientBuilder {
method http1_allow_obsolete_multiline_headers_in_responses (line 1510) | pub fn http1_allow_obsolete_multiline_headers_in_responses(
method http1_ignore_invalid_headers_in_responses (line 1520) | pub fn http1_ignore_invalid_headers_in_responses(mut self, value: bool...
method http1_allow_spaces_after_header_name_in_responses (line 1530) | pub fn http1_allow_spaces_after_header_name_in_responses(
method http1_only (line 1540) | pub fn http1_only(mut self) -> ClientBuilder {
method http09_responses (line 1546) | pub fn http09_responses(mut self) -> ClientBuilder {
method http2_prior_knowledge (line 1554) | pub fn http2_prior_knowledge(mut self) -> ClientBuilder {
method http3_prior_knowledge (line 1562) | pub fn http3_prior_knowledge(mut self) -> ClientBuilder {
method http2_initial_stream_window_size (line 1572) | pub fn http2_initial_stream_window_size(mut self, sz: impl Into<Option...
method http2_initial_connection_window_size (line 1582) | pub fn http2_initial_connection_window_size(
method http2_adaptive_window (line 1596) | pub fn http2_adaptive_window(mut self, enabled: bool) -> ClientBuilder {
method http2_max_frame_size (line 1606) | pub fn http2_max_frame_size(mut self, sz: impl Into<Option<u32>>) -> C...
method http2_max_header_list_size (line 1616) | pub fn http2_max_header_list_size(mut self, max_header_size_bytes: u32...
method http2_keep_alive_interval (line 1627) | pub fn http2_keep_alive_interval(
method http2_keep_alive_timeout (line 1642) | pub fn http2_keep_alive_timeout(mut self, timeout: Duration) -> Client...
method http2_keep_alive_while_idle (line 1655) | pub fn http2_keep_alive_while_idle(mut self, enabled: bool) -> ClientB...
method tcp_nodelay (line 1665) | pub fn tcp_nodelay(mut self, enabled: bool) -> ClientBuilder {
method local_address (line 1684) | pub fn local_address<T>(mut self, addr: T) -> ClientBuilder
method interface (line 1736) | pub fn interface(mut self, interface: &str) -> ClientBuilder {
method tcp_keepalive (line 1744) | pub fn tcp_keepalive<D>(mut self, val: D) -> ClientBuilder
method tcp_keepalive_interval (line 1755) | pub fn tcp_keepalive_interval<D>(mut self, val: D) -> ClientBuilder
method tcp_keepalive_retries (line 1766) | pub fn tcp_keepalive_retries<C>(mut self, retries: C) -> ClientBuilder
method tcp_user_timeout (line 1781) | pub fn tcp_user_timeout<D>(mut self, val: D) -> ClientBuilder
method unix_socket (line 1803) | pub fn unix_socket(mut self, path: impl UnixSocketProvider) -> ClientB...
method windows_named_pipe (line 1820) | pub fn windows_named_pipe(mut self, pipe: impl WindowsNamedPipeProvide...
method tls_certs_merge (line 1851) | pub fn tls_certs_merge(
method tls_certs_only (line 1876) | pub fn tls_certs_only(mut self, certs: impl IntoIterator<Item = Certif...
method add_root_certificate (line 1885) | pub fn add_root_certificate(mut self, cert: Certificate) -> ClientBuil...
method tls_crls_only (line 1905) | pub fn tls_crls_only(
method add_crl (line 1916) | pub fn add_crl(mut self, crl: CertificateRevocationList) -> ClientBuil...
method add_crls (line 1924) | pub fn add_crls(
method identity (line 1940) | pub fn identity(mut self, identity: Identity) -> ClientBuilder {
method tls_danger_accept_invalid_hostnames (line 1970) | pub fn tls_danger_accept_invalid_hostnames(
method danger_accept_invalid_hostnames (line 1980) | pub fn danger_accept_invalid_hostnames(self, accept_invalid_hostname: ...
method tls_danger_accept_invalid_certs (line 2005) | pub fn tls_danger_accept_invalid_certs(mut self, accept_invalid_certs:...
method danger_accept_invalid_certs (line 2012) | pub fn danger_accept_invalid_certs(self, accept_invalid_certs: bool) -...
method tls_sni (line 2029) | pub fn tls_sni(mut self, tls_sni: bool) -> ClientBuilder {
method tls_version_min (line 2054) | pub fn tls_version_min(mut self, version: tls::Version) -> ClientBuild...
method min_tls_version (line 2061) | pub fn min_tls_version(self, version: tls::Version) -> ClientBuilder {
method tls_version_max (line 2088) | pub fn tls_version_max(mut self, version: tls::Version) -> ClientBuild...
method max_tls_version (line 2095) | pub fn max_tls_version(self, version: tls::Version) -> ClientBuilder {
method tls_backend_native (line 2109) | pub fn tls_backend_native(mut self) -> ClientBuilder {
method use_native_tls (line 2116) | pub fn use_native_tls(self) -> ClientBuilder {
method tls_backend_rustls (line 2130) | pub fn tls_backend_rustls(mut self) -> ClientBuilder {
method use_rustls_tls (line 2138) | pub fn use_rustls_tls(self) -> ClientBuilder {
method tls_backend_preconfigured (line 2169) | pub fn tls_backend_preconfigured(mut self, tls: impl Any) -> ClientBui...
method use_preconfigured_tls (line 2199) | pub fn use_preconfigured_tls(self, tls: impl Any) -> ClientBuilder {
method tls_info (line 2214) | pub fn tls_info(mut self, tls_info: bool) -> ClientBuilder {
method https_only (line 2222) | pub fn https_only(mut self, enabled: bool) -> ClientBuilder {
method hickory_dns (line 2242) | pub fn hickory_dns(mut self, enable: bool) -> ClientBuilder {
method no_hickory_dns (line 2252) | pub fn no_hickory_dns(self) -> ClientBuilder {
method resolve (line 2268) | pub fn resolve(self, domain: &str, addr: SocketAddr) -> ClientBuilder {
method resolve_to_addrs (line 2276) | pub fn resolve_to_addrs(mut self, domain: &str, addrs: &[SocketAddr]) ...
method dns_resolver (line 2287) | pub fn dns_resolver<R>(mut self, resolver: R) -> ClientBuilder
method tls_early_data (line 2301) | pub fn tls_early_data(mut self, enabled: bool) -> ClientBuilder {
method http3_max_idle_timeout (line 2313) | pub fn http3_max_idle_timeout(mut self, value: Duration) -> ClientBuil...
method http3_stream_receive_window (line 2330) | pub fn http3_stream_receive_window(mut self, value: u64) -> ClientBuil...
method http3_conn_receive_window (line 2347) | pub fn http3_conn_receive_window(mut self, value: u64) -> ClientBuilder {
method http3_send_window (line 2359) | pub fn http3_send_window(mut self, value: u64) -> ClientBuilder {
method http3_congestion_bbr (line 2373) | pub fn http3_congestion_bbr(mut self) -> ClientBuilder {
method http3_max_field_section_size (line 2389) | pub fn http3_max_field_section_size(mut self, value: u64) -> ClientBui...
method http3_send_grease (line 2407) | pub fn http3_send_grease(mut self, enabled: bool) -> ClientBuilder {
method connector_layer (line 2435) | pub fn connector_layer<L>(mut self, layer: L) -> ClientBuilder
method fmt (line 2735) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type HttpVersionPref (line 103) | enum HttpVersionPref {
type Accepts (line 113) | struct Accepts {
method default (line 125) | fn default() -> Accepts {
type HyperService (line 140) | struct HyperService {
type Error (line 145) | type Error = crate::Error;
type Response (line 146) | type Response = http::Response<hyper::body::Incoming>;
type Future (line 147) | type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self:...
method poll_ready (line 149) | fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self...
method call (line 153) | fn call(&mut self, req: hyper::Request<crate::async_impl::body::Body>)...
type Config (line 160) | struct Config {
method fmt_fields (line 2743) | fn fmt_fields(&self, f: &mut fmt::DebugStruct<'_, '_>) {
method default (line 271) | fn default() -> Self {
type HyperClient (line 2450) | type HyperClient = hyper_util::client::legacy::Client<Connector, super::...
method default (line 2453) | fn default() -> Self {
function default_rustls_crypto_provider (line 2459) | fn default_rustls_crypto_provider() -> Arc<rustls::crypto::CryptoProvide...
type Response (line 2721) | type Response = Response;
type Error (line 2722) | type Error = crate::Error;
type Future (line 2723) | type Future = Pending;
type Output (line 3023) | type Output = Result<Response, crate::Error>;
method poll (line 3025) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Outp...
type Output (line 3037) | type Output = Result<Response, crate::Error>;
method poll (line 3039) | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::...
function poll_ready (line 2725) | fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self:...
function call (line 2729) | fn call(&mut self, req: Request) -> Self::Future {
type MaybeCookieService (line 2877) | type MaybeCookieService<T> = T;
type MaybeCookieService (line 2880) | type MaybeCookieService<T> = CookieService<T>;
type MaybeDecompression (line 2888) | type MaybeDecompression<T> = T;
type MaybeDecompression (line 2896) | type MaybeDecompression<T> = Decompression<T>;
type LayeredService (line 2898) | type LayeredService<T> = MaybeDecompression<
type LayeredFuture (line 2904) | type LayeredFuture<T> = <LayeredService<T> as Service<http::Request<Body...
type ClientRef (line 2906) | struct ClientRef {
method fmt_fields (line 2925) | fn fmt_fields(&self, f: &mut fmt::DebugStruct<'_, '_>) {
type PendingInner (line 2967) | enum PendingInner {
type ResponseFuture (line 2990) | enum ResponseFuture {
method in_flight (line 2997) | fn in_flight(self: Pin<&mut Self>) -> Pin<&mut ResponseFuture> {
method total_timeout (line 3001) | fn total_timeout(self: Pin<&mut Self>) -> Pin<&mut Option<Pin<Box<Sleep>...
method read_timeout (line 3005) | fn read_timeout(self: Pin<&mut Self>) -> Pin<&mut Option<Pin<Box<Sleep>>...
method new_err (line 3011) | pub(super) fn new_err(err: crate::Error) -> Pending {
method inner (line 3017) | fn inner(self: Pin<&mut Self>) -> Pin<&mut PendingInner> {
method fmt (line 3093) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
function execute_request_rejects_invalid_urls (line 3110) | async fn execute_request_rejects_invalid_urls() {
function execute_request_rejects_invalid_hostname (line 3123) | async fn execute_request_rejects_invalid_hostname() {
function test_future_size (line 3135) | fn test_future_size() {
FILE: src/async_impl/h3_client/connect.rs
type H3Connection (line 15) | type H3Connection = (
type H3ClientConfig (line 22) | pub(crate) struct H3ClientConfig {
method default (line 49) | fn default() -> Self {
type H3Connector (line 58) | pub(crate) struct H3Connector {
method new (line 65) | pub fn new(
method connect (line 92) | pub async fn connect(&mut self, dest: Uri) -> Result<H3Connection, Box...
method remote_connect (line 115) | async fn remote_connect(
FILE: src/async_impl/h3_client/dns.rs
type Resolve (line 9) | pub trait Resolve {
method poll_ready (line 14) | fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<()...
method resolve (line 15) | fn resolve(&mut self, name: Name) -> Self::Future;
type Addrs (line 24) | type Addrs = S::Response;
type Error (line 25) | type Error = S::Error;
type Future (line 26) | type Future = S::Future;
method poll_ready (line 28) | fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<()...
method resolve (line 32) | fn resolve(&mut self, name: Name) -> Self::Future {
function resolve (line 37) | pub(super) async fn resolve<R>(resolver: &mut R, name: Name) -> Result<R...
FILE: src/async_impl/h3_client/mod.rs
type H3Client (line 22) | pub(crate) struct H3Client {
method new (line 28) | pub fn new(connector: H3Connector, pool_timeout: Option<Duration>) -> ...
method get_pooled_client (line 35) | async fn get_pooled_client(&mut self, key: Key) -> Result<PoolClient, ...
method send_request (line 62) | async fn send_request(
method request (line 77) | pub fn request(&self, mut req: Request<Body>) -> H3ResponseFuture {
type Response (line 93) | type Response = Response<ResponseBody>;
type Error (line 94) | type Error = Error;
type Future (line 95) | type Future = H3ResponseFuture;
method poll_ready (line 97) | fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Sel...
method call (line 101) | fn call(&mut self, req: Request<Body>) -> Self::Future {
type H3ResponseFuture (line 106) | pub(crate) struct H3ResponseFuture {
type Output (line 111) | type Output = Result<Response<ResponseBody>, Error>;
method poll (line 113) | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Ou...
FILE: src/async_impl/h3_client/pool.rs
type Key (line 22) | pub(super) type Key = (Scheme, Authority);
type Pool (line 25) | pub struct Pool {
method new (line 88) | pub fn new(timeout: Option<Duration>) -> Self {
method connecting (line 100) | pub fn connecting(&self, key: &Key) -> Connecting {
method try_pool (line 114) | pub fn try_pool(&self, key: &Key) -> Option<PoolClient> {
method new_connection (line 141) | pub fn new_connection(
type ConnectingLockInner (line 29) | struct ConnectingLockInner {
type ConnectingLock (line 36) | pub struct ConnectingLock(Option<ConnectingLockInner>);
method new (line 55) | fn new(key: Key, pool: Arc<Mutex<PoolInner>>) -> Self {
method forget (line 60) | fn forget(mut self) -> Key {
type ConnectingWaiter (line 41) | pub struct ConnectingWaiter {
method receive (line 78) | pub async fn receive(mut self) -> Option<PoolClient> {
type Connecting (line 45) | pub enum Connecting {
method drop (line 68) | fn drop(&mut self) {
type PoolInner (line 181) | struct PoolInner {
method insert (line 188) | fn insert(&mut self, key: Key, conn: PoolConnection) {
type PoolClient (line 198) | pub struct PoolClient {
method new (line 203) | pub fn new(tx: SendRequest<OpenStreams, Bytes>) -> Self {
method send_request (line 207) | pub async fn send_request(
type PoolConnection (line 278) | pub struct PoolConnection {
method new (line 286) | pub fn new(client: PoolClient, close_rx: Receiver<h3::error::Connectio...
method pool (line 294) | pub fn pool(&mut self) -> PoolClient {
method is_invalid (line 299) | pub fn is_invalid(&self) -> bool {
type Incoming (line 308) | struct Incoming<S, B> {
function new (line 315) | fn new(
type Data (line 335) | type Data = Bytes;
type Error (line 336) | type Error = crate::error::Error;
function poll_frame (line 338) | fn poll_frame(
function size_hint (line 355) | fn size_hint(&self) -> hyper::body::SizeHint {
function extract_domain (line 364) | pub(crate) fn extract_domain(uri: &mut Uri) -> Result<Key, Error> {
function domain_as_uri (line 372) | pub(crate) fn domain_as_uri((scheme, auth): Key) -> Uri {
function is_stop_sending (line 382) | fn is_stop_sending(e: &h3::error::StreamError) -> bool {
FILE: src/async_impl/multipart.rs
type Form (line 25) | pub struct Form {
method new (line 64) | pub fn new() -> Form {
method boundary (line 72) | pub fn boundary(&self) -> &str {
method text (line 85) | pub fn text<T, U>(self, name: T, value: U) -> Form
method file (line 112) | pub async fn file<T, U>(self, name: T, path: U) -> io::Result<Form>
method part (line 121) | pub fn part<T>(self, name: T, part: Part) -> Form
method percent_encode_path_segment (line 129) | pub fn percent_encode_path_segment(self) -> Form {
method percent_encode_attr_chars (line 134) | pub fn percent_encode_attr_chars(self) -> Form {
method percent_encode_noop (line 139) | pub fn percent_encode_noop(self) -> Form {
method stream (line 144) | pub(crate) fn stream(self) -> Body {
method into_stream (line 153) | pub fn into_stream(mut self) -> impl Stream<Item = Result<Bytes, crate...
method part_stream (line 181) | pub(crate) fn part_stream<T>(
method compute_length (line 209) | pub(crate) fn compute_length(&mut self) -> Option<u64> {
method with_inner (line 213) | fn with_inner<F>(self, func: F) -> Self
method fmt (line 224) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Part (line 30) | pub struct Part {
method text (line 233) | pub fn text<T>(value: T) -> Part
method bytes (line 245) | pub fn bytes<T>(value: T) -> Part
method stream (line 257) | pub fn stream<T: Into<Body>>(value: T) -> Part {
method stream_with_length (line 264) | pub fn stream_with_length<T: Into<Body>>(value: T, length: u64) -> Part {
method file (line 275) | pub async fn file<T: AsRef<Path>>(path: T) -> io::Result<Part> {
method new (line 297) | fn new(value: Body, body_length: Option<u64>) -> Part {
method mime_str (line 306) | pub fn mime_str(self, mime: &str) -> crate::Result<Part> {
method mime (line 311) | fn mime(self, mime: Mime) -> Part {
method file_name (line 316) | pub fn file_name<T>(self, filename: T) -> Part
method headers (line 324) | pub fn headers(self, headers: HeaderMap) -> Part {
method with_inner (line 328) | fn with_inner<F>(self, func: F) -> Self
method fmt (line 340) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type FormParts (line 36) | pub(crate) struct FormParts<P> {
type PartMetadata (line 43) | pub(crate) struct PartMetadata {
method new (line 458) | pub(crate) fn new() -> Self {
method mime (line 466) | pub(crate) fn mime(mut self, mime: Mime) -> Self {
method file_name (line 471) | pub(crate) fn file_name<T>(mut self, filename: T) -> Self
method headers (line 479) | pub(crate) fn headers<T>(mut self, headers: T) -> Self
method fmt_fields (line 489) | pub(crate) fn fmt_fields<'f, 'fa, 'fb>(
type PartProps (line 49) | pub(crate) trait PartProps {
method value_len (line 50) | fn value_len(&self) -> Option<u64>;
method metadata (line 51) | fn metadata(&self) -> &PartMetadata;
method value_len (line 349) | fn value_len(&self) -> Option<u64> {
method metadata (line 357) | fn metadata(&self) -> &PartMetadata {
method default (line 57) | fn default() -> Self {
function new (line 365) | pub(crate) fn new() -> Self {
function boundary (line 374) | pub(crate) fn boundary(&self) -> &str {
function part (line 379) | pub(crate) fn part<T>(mut self, name: T, part: P) -> Self
function percent_encode_path_segment (line 388) | pub(crate) fn percent_encode_path_segment(mut self) -> Self {
function percent_encode_attr_chars (line 394) | pub(crate) fn percent_encode_attr_chars(mut self) -> Self {
function percent_encode_noop (line 400) | pub(crate) fn percent_encode_noop(mut self) -> Self {
function compute_length (line 408) | pub(crate) fn compute_length(&mut self) -> Option<u64> {
function take_fields (line 441) | fn take_fields(&mut self) -> Vec<(Cow<'static, str>, P)> {
function fmt_fields (line 447) | pub(crate) fn fmt_fields(&self, ty_name: &'static str, f: &mut fmt::Form...
constant FRAGMENT_ENCODE_SET (line 501) | const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS
constant PATH_ENCODE_SET (line 509) | const PATH_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'#').add(b'...
constant PATH_SEGMENT_ENCODE_SET (line 511) | const PATH_SEGMENT_ENCODE_SET: &AsciiSet = &PATH_ENCODE_SET.add(b'/').ad...
constant ATTR_CHAR_ENCODE_SET (line 514) | const ATTR_CHAR_ENCODE_SET: &AsciiSet = &NON_ALPHANUMERIC
type PercentEncoding (line 528) | pub(crate) enum PercentEncoding {
method encode_headers (line 535) | pub(crate) fn encode_headers(&self, name: &str, field: &PartMetadata) ...
method percent_encode (line 580) | fn percent_encode<'a>(&self, value: &'a str) -> Cow<'a, str> {
function gen_boundary (line 591) | fn gen_boundary() -> String {
function form_empty (line 611) | fn form_empty() {
function stream_to_end (line 626) | fn stream_to_end() {
function stream_to_end_with_header (line 685) | fn stream_to_end_with_header() {
function correct_content_length (line 717) | fn correct_content_length() {
function header_percent_encoding (line 740) | fn header_percent_encoding() {
FILE: src/async_impl/request.rs
type Request (line 26) | pub struct Request {
method new (line 47) | pub fn new(method: Method, url: Url) -> Self {
method method (line 60) | pub fn method(&self) -> &Method {
method method_mut (line 66) | pub fn method_mut(&mut self) -> &mut Method {
method url (line 72) | pub fn url(&self) -> &Url {
method url_mut (line 78) | pub fn url_mut(&mut self) -> &mut Url {
method headers (line 84) | pub fn headers(&self) -> &HeaderMap {
method headers_mut (line 90) | pub fn headers_mut(&mut self) -> &mut HeaderMap {
method body (line 96) | pub fn body(&self) -> Option<&Body> {
method body_mut (line 102) | pub fn body_mut(&mut self) -> &mut Option<Body> {
method extensions (line 108) | pub(crate) fn extensions(&self) -> &Extensions {
method extensions_mut (line 114) | pub(crate) fn extensions_mut(&mut self) -> &mut Extensions {
method timeout (line 120) | pub fn timeout(&self) -> Option<&Duration> {
method timeout_mut (line 126) | pub fn timeout_mut(&mut self) -> &mut Option<Duration> {
method version (line 132) | pub fn version(&self) -> Version {
method version_mut (line 138) | pub fn version_mut(&mut self) -> &mut Version {
method try_clone (line 145) | pub fn try_clone(&self) -> Option<Request> {
method pieces (line 159) | pub(super) fn pieces(self) -> (Method, Url, HeaderMap, Option<Body>, V...
method fmt (line 556) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Error (line 612) | type Error = crate::Error;
method try_from (line 614) | fn try_from(req: HttpRequest<T>) -> crate::Result<Self> {
type RequestBuilder (line 39) | pub struct RequestBuilder {
method new (line 172) | pub(super) fn new(client: Client, request: crate::Result<Request>) -> ...
method from_parts (line 189) | pub fn from_parts(client: Client, request: Request) -> RequestBuilder {
method header (line 197) | pub fn header<K, V>(self, key: K, value: V) -> RequestBuilder
method header_sensitive (line 208) | fn header_sensitive<K, V>(mut self, key: K, value: V, sensitive: bool)...
method headers (line 242) | pub fn headers(mut self, headers: crate::header::HeaderMap) -> Request...
method basic_auth (line 263) | pub fn basic_auth<U, P>(self, username: U, password: Option<P>) -> Req...
method bearer_auth (line 273) | pub fn bearer_auth<T>(self, token: T) -> RequestBuilder
method body (line 282) | pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder {
method timeout (line 294) | pub fn timeout(mut self, timeout: Duration) -> RequestBuilder {
method multipart (line 325) | pub fn multipart(self, mut multipart: multipart::Form) -> RequestBuild...
method query (line 366) | pub fn query<T: Serialize + ?Sized>(mut self, query: &T) -> RequestBui...
method version (line 389) | pub fn version(mut self, version: Version) -> RequestBuilder {
method form (line 429) | pub fn form<T: Serialize + ?Sized>(mut self, form: &T) -> RequestBuild...
method json (line 462) | pub fn json<T: Serialize + ?Sized>(mut self, json: &T) -> RequestBuild...
method build (line 483) | pub fn build(self) -> crate::Result<Request> {
method build_split (line 492) | pub fn build_split(self) -> (Client, crate::Result<Request>) {
method send (line 517) | pub fn send(self) -> impl Future<Output = Result<Response, crate::Erro...
method try_clone (line 543) | pub fn try_clone(&self) -> Option<RequestBuilder> {
method fmt (line 562) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
function fmt_request_fields (line 571) | fn fmt_request_fields<'a, 'b>(
function extract_authority (line 582) | pub(crate) fn extract_authority(url: &mut Url) -> Option<(String, Option...
type Error (line 637) | type Error = crate::Error;
function try_from (line 639) | fn try_from(req: Request) -> crate::Result<Self> {
function add_query_append (line 673) | fn add_query_append() {
function add_query_append_same (line 687) | fn add_query_append_same() {
function add_query_struct (line 700) | fn add_query_struct() {
function add_query_map (line 724) | fn add_query_map() {
function test_replace_headers (line 740) | fn test_replace_headers() {
function normalize_empty_query (line 766) | fn normalize_empty_query() {
function try_clone_reusable (line 782) | fn try_clone_reusable() {
function try_clone_no_body (line 799) | fn try_clone_no_body() {
function try_clone_stream (line 814) | fn try_clone_stream() {
function convert_url_authority_into_basic_auth (line 826) | fn convert_url_authority_into_basic_auth() {
function test_basic_auth_sensitive_header (line 840) | fn test_basic_auth_sensitive_header() {
function test_bearer_auth_sensitive_header (line 859) | fn test_bearer_auth_sensitive_header() {
function test_explicit_sensitive_header (line 875) | fn test_explicit_sensitive_header() {
function convert_from_http_request (line 894) | fn convert_from_http_request() {
function set_http_request_version (line 912) | fn set_http_request_version() {
function builder_split_reassemble (line 932) | fn builder_split_reassemble() {
FILE: src/async_impl/response.rs
type Response (line 28) | pub struct Response {
method new (line 36) | pub(super) fn new(
method status (line 56) | pub fn status(&self) -> StatusCode {
method version (line 62) | pub fn version(&self) -> Version {
method headers (line 68) | pub fn headers(&self) -> &HeaderMap {
method headers_mut (line 74) | pub fn headers_mut(&mut self) -> &mut HeaderMap {
method content_length (line 90) | pub fn content_length(&self) -> Option<u64> {
method cookies (line 105) | pub fn cookies<'a>(&'a self) -> impl Iterator<Item = cookie::Cookie<'a...
method url (line 111) | pub fn url(&self) -> &Url {
method remote_addr (line 116) | pub fn remote_addr(&self) -> Option<SocketAddr> {
method extensions (line 124) | pub fn extensions(&self) -> &http::Extensions {
method extensions_mut (line 129) | pub fn extensions_mut(&mut self) -> &mut http::Extensions {
method text (line 163) | pub async fn text(self) -> crate::Result<String> {
method text_with_charset (line 208) | pub async fn text_with_charset(self, default_encoding: &str) -> crate:...
method json (line 269) | pub async fn json<T: DeserializeOwned>(self) -> crate::Result<T> {
method bytes (line 290) | pub async fn bytes(self) -> crate::Result<Bytes> {
method chunk (line 315) | pub async fn chunk(&mut self) -> crate::Result<Option<Bytes>> {
method bytes_stream (line 356) | pub fn bytes_stream(self) -> impl futures_core::Stream<Item = crate::R...
method error_for_status (line 383) | pub fn error_for_status(self) -> crate::Result<Self> {
method error_for_status_ref (line 414) | pub fn error_for_status_ref(&self) -> crate::Result<&Self> {
method body_mut (line 432) | pub(crate) fn body_mut(&mut self) -> &mut ResponseBody {
method fmt (line 438) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method from (line 457) | fn from(r: http::Response<T>) -> Response {
method from (line 449) | fn from(r: Response) -> Body {
function from (line 478) | fn from(r: Response) -> http::Response<Body> {
function test_from_http_response (line 493) | fn test_from_http_response() {
FILE: src/async_impl/upgrade.rs
type Upgraded (line 9) | pub struct Upgraded {
method fmt (line 54) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 60) | fn from(inner: hyper::upgrade::Upgraded) -> Self {
method poll_read (line 14) | fn poll_read(
method poll_write (line 24) | fn poll_write(
method poll_write_vectored (line 32) | fn poll_write_vectored(
method poll_flush (line 40) | fn poll_flush(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> P...
method poll_shutdown (line 44) | fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -...
method is_write_vectored (line 48) | fn is_write_vectored(&self) -> bool {
function upgrade (line 69) | pub async fn upgrade(self) -> crate::Result<Upgraded> {
FILE: src/blocking/body.rs
type Body (line 23) | pub struct Body {
method new (line 60) | pub fn new<R: Read + Send + 'static>(reader: R) -> Body {
method sized (line 80) | pub fn sized<R: Read + Send + 'static>(reader: R, len: u64) -> Body {
method as_bytes (line 88) | pub fn as_bytes(&self) -> Option<&[u8]> {
method buffer (line 101) | pub fn buffer(&mut self) -> Result<&[u8], crate::Error> {
method len (line 118) | pub(crate) fn len(&self) -> Option<u64> {
method into_reader (line 126) | pub(crate) fn into_reader(self) -> Reader {
method into_async (line 133) | pub(crate) fn into_async(self) -> (Option<Sender>, async_impl::Body, O...
method try_clone (line 150) | pub(crate) fn try_clone(&self) -> Option<Body> {
method from (line 171) | fn from(v: Vec<u8>) -> Body {
method from (line 180) | fn from(s: String) -> Body {
method from (line 187) | fn from(s: &'static [u8]) -> Body {
method from (line 196) | fn from(s: &'static str) -> Body {
method from (line 203) | fn from(f: File) -> Body {
method from (line 212) | fn from(b: Bytes) -> Body {
type Kind (line 155) | enum Kind {
method try_clone (line 161) | fn try_clone(&self) -> Option<Kind> {
method fmt (line 220) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type DebugLength (line 231) | struct DebugLength<'a>(&'a Option<u64>);
function fmt (line 234) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Reader (line 243) | pub(crate) enum Reader {
method read (line 250) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
type Sender (line 258) | pub(crate) struct Sender {
method send (line 358) | pub(crate) fn send(self) -> impl Future<Output = Result<(), crate::Err...
type Abort (line 264) | struct Abort;
method fmt (line 267) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
function send_future (line 274) | async fn send_future(sender: Sender) -> Result<(), crate::Error> {
function read_to_string (line 365) | pub(crate) fn read_to_string(mut body: Body) -> io::Result<String> {
FILE: src/blocking/client.rs
type Client (line 61) | pub struct Client {
method new (line 1217) | pub fn new() -> Client {
method builder (line 1224) | pub fn builder() -> ClientBuilder {
method get (line 1233) | pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method post (line 1242) | pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method put (line 1251) | pub fn put<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method patch (line 1260) | pub fn patch<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method delete (line 1269) | pub fn delete<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method head (line 1278) | pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method request (line 1290) | pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBu...
method execute (line 1307) | pub fn execute(&self, request: Request) -> crate::Result<Response> {
method fmt (line 1313) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type ClientBuilder (line 80) | pub struct ClientBuilder {
method new (line 95) | pub fn new() -> Self {
method build (line 115) | pub fn build(self) -> crate::Result<Client> {
method user_agent (line 141) | pub fn user_agent<V>(self, value: V) -> ClientBuilder
method default_headers (line 173) | pub fn default_headers(self, headers: header::HeaderMap) -> ClientBuil...
method cookie_store (line 189) | pub fn cookie_store(self, enable: bool) -> ClientBuilder {
method cookie_provider (line 205) | pub fn cookie_provider<C: crate::cookie::CookieStore + 'static>(
method gzip (line 230) | pub fn gzip(self, enable: bool) -> ClientBuilder {
method brotli (line 252) | pub fn brotli(self, enable: bool) -> ClientBuilder {
method zstd (line 274) | pub fn zstd(self, enable: bool) -> ClientBuilder {
method deflate (line 296) | pub fn deflate(self, enable: bool) -> ClientBuilder {
method no_gzip (line 305) | pub fn no_gzip(self) -> ClientBuilder {
method no_brotli (line 314) | pub fn no_brotli(self) -> ClientBuilder {
method no_zstd (line 323) | pub fn no_zstd(self) -> ClientBuilder {
method no_deflate (line 332) | pub fn no_deflate(self) -> ClientBuilder {
method redirect (line 341) | pub fn redirect(self, policy: redirect::Policy) -> ClientBuilder {
method retry (line 348) | pub fn retry(self, policy: crate::retry::Builder) -> ClientBuilder {
method referer (line 355) | pub fn referer(self, enable: bool) -> ClientBuilder {
method proxy (line 366) | pub fn proxy(self, proxy: Proxy) -> ClientBuilder {
method no_proxy (line 377) | pub fn no_proxy(self) -> ClientBuilder {
method timeout (line 388) | pub fn timeout<T>(mut self, timeout: T) -> ClientBuilder
method connect_timeout (line 399) | pub fn connect_timeout<T>(self, timeout: T) -> ClientBuilder
method connection_verbose (line 417) | pub fn connection_verbose(self, verbose: bool) -> ClientBuilder {
method pool_idle_timeout (line 428) | pub fn pool_idle_timeout<D>(self, val: D) -> ClientBuilder
method pool_max_idle_per_host (line 436) | pub fn pool_max_idle_per_host(self, max: usize) -> ClientBuilder {
method http1_title_case_headers (line 441) | pub fn http1_title_case_headers(self) -> ClientBuilder {
method http1_allow_obsolete_multiline_headers_in_responses (line 450) | pub fn http1_allow_obsolete_multiline_headers_in_responses(self, value...
method http1_ignore_invalid_headers_in_responses (line 455) | pub fn http1_ignore_invalid_headers_in_responses(self, value: bool) ->...
method http1_allow_spaces_after_header_name_in_responses (line 464) | pub fn http1_allow_spaces_after_header_name_in_responses(self, value: ...
method http1_only (line 469) | pub fn http1_only(self) -> ClientBuilder {
method http09_responses (line 474) | pub fn http09_responses(self) -> ClientBuilder {
method http2_prior_knowledge (line 481) | pub fn http2_prior_knowledge(self) -> ClientBuilder {
method http2_initial_stream_window_size (line 490) | pub fn http2_initial_stream_window_size(self, sz: impl Into<Option<u32...
method http2_initial_connection_window_size (line 499) | pub fn http2_initial_connection_window_size(self, sz: impl Into<Option...
method http2_adaptive_window (line 509) | pub fn http2_adaptive_window(self, enabled: bool) -> ClientBuilder {
method http2_max_frame_size (line 518) | pub fn http2_max_frame_size(self, sz: impl Into<Option<u32>>) -> Clien...
method http2_max_header_list_size (line 527) | pub fn http2_max_header_list_size(self, max_header_size_bytes: u32) ->...
method http3_prior_knowledge (line 535) | pub fn http3_prior_knowledge(self) -> ClientBuilder {
method http3_max_idle_timeout (line 546) | pub fn http3_max_idle_timeout(self, value: Duration) -> ClientBuilder {
method http3_stream_receive_window (line 562) | pub fn http3_stream_receive_window(self, value: u64) -> ClientBuilder {
method http3_conn_receive_window (line 578) | pub fn http3_conn_receive_window(self, value: u64) -> ClientBuilder {
method http3_send_window (line 589) | pub fn http3_send_window(self, value: u64) -> ClientBuilder {
method http3_congestion_bbr (line 602) | pub fn http3_congestion_bbr(self) -> ClientBuilder {
method http3_max_field_section_size (line 617) | pub fn http3_max_field_section_size(self, value: u64) -> ClientBuilder {
method http3_send_grease (line 634) | pub fn http3_send_grease(self, enabled: bool) -> ClientBuilder {
method tcp_nodelay (line 643) | pub fn tcp_nodelay(self, enabled: bool) -> ClientBuilder {
method local_address (line 658) | pub fn local_address<T>(self, addr: T) -> ClientBuilder
method interface (line 687) | pub fn interface(self, interface: &str) -> ClientBuilder {
method tcp_keepalive (line 694) | pub fn tcp_keepalive<D>(self, val: D) -> ClientBuilder
method tcp_keepalive_interval (line 704) | pub fn tcp_keepalive_interval<D>(self, val: D) -> ClientBuilder
method tcp_keepalive_retries (line 714) | pub fn tcp_keepalive_retries<C>(self, retries: C) -> ClientBuilder
method tcp_user_timeout (line 728) | pub fn tcp_user_timeout<D>(self, val: D) -> ClientBuilder
method unix_socket (line 749) | pub fn unix_socket(self, path: impl UnixSocketProvider) -> ClientBuild...
method tls_certs_merge (line 791) | pub fn tls_certs_merge(self, certs: impl IntoIterator<Item = Certifica...
method tls_certs_only (line 812) | pub fn tls_certs_only(self, certs: impl IntoIterator<Item = Certificat...
method add_root_certificate (line 818) | pub fn add_root_certificate(self, cert: Certificate) -> ClientBuilder {
method tls_crls_only (line 837) | pub fn tls_crls_only(
method add_crl (line 847) | pub fn add_crl(self, crl: CertificateRevocationList) -> ClientBuilder {
method add_crls (line 854) | pub fn add_crls(
method identity (line 869) | pub fn identity(self, identity: Identity) -> ClientBuilder {
method tls_danger_accept_invalid_hostnames (line 898) | pub fn tls_danger_accept_invalid_hostnames(
method danger_accept_invalid_hostnames (line 907) | pub fn danger_accept_invalid_hostnames(self, accept_invalid_hostname: ...
method tls_danger_accept_invalid_certs (line 927) | pub fn tls_danger_accept_invalid_certs(self, accept_invalid_certs: boo...
method danger_accept_invalid_certs (line 933) | pub fn danger_accept_invalid_certs(self, accept_invalid_certs: bool) -...
method tls_sni (line 945) | pub fn tls_sni(self, tls_sni: bool) -> ClientBuilder {
method tls_version_min (line 969) | pub fn tls_version_min(self, version: tls::Version) -> ClientBuilder {
method min_tls_version (line 975) | pub fn min_tls_version(self, version: tls::Version) -> ClientBuilder {
method tls_version_max (line 999) | pub fn tls_version_max(self, version: tls::Version) -> ClientBuilder {
method max_tls_version (line 1005) | pub fn max_tls_version(self, version: tls::Version) -> ClientBuilder {
method tls_backend_native (line 1019) | pub fn tls_backend_native(self) -> ClientBuilder {
method use_native_tls (line 1025) | pub fn use_native_tls(self) -> ClientBuilder {
method tls_backend_rustls (line 1039) | pub fn tls_backend_rustls(self) -> ClientBuilder {
method use_rustls_tls (line 1046) | pub fn use_rustls_tls(self) -> ClientBuilder {
method tls_info (line 1061) | pub fn tls_info(self, tls_info: bool) -> ClientBuilder {
method tls_backend_preconfigured (line 1085) | pub fn tls_backend_preconfigured(self, tls: impl Any) -> ClientBuilder {
method use_preconfigured_tls (line 1091) | pub fn use_preconfigured_tls(self, tls: impl Any) -> ClientBuilder {
method hickory_dns (line 1104) | pub fn hickory_dns(self, enable: bool) -> ClientBuilder {
method no_hickory_dns (line 1113) | pub fn no_hickory_dns(self) -> ClientBuilder {
method https_only (line 1120) | pub fn https_only(self, enabled: bool) -> ClientBuilder {
method resolve (line 1128) | pub fn resolve(self, domain: &str, addr: SocketAddr) -> ClientBuilder {
method resolve_to_addrs (line 1136) | pub fn resolve_to_addrs(self, domain: &str, addrs: &[SocketAddr]) -> C...
method dns_resolver (line 1145) | pub fn dns_resolver<R: Resolve + 'static>(self, resolver: Arc<R>) -> C...
method connector_layer (line 1168) | pub fn connector_layer<L>(self, layer: L) -> ClientBuilder
method with_inner (line 1180) | fn with_inner<F>(mut self, func: F) -> ClientBuilder
method from (line 1190) | fn from(builder: async_impl::ClientBuilder) -> Self {
method fmt (line 1323) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method default (line 86) | fn default() -> Self {
method default (line 1199) | fn default() -> Self {
type ClientHandle (line 1329) | struct ClientHandle {
method new (line 1359) | fn new(builder: ClientBuilder) -> crate::Result<ClientHandle> {
method execute_request (line 1433) | fn execute_request(&self, req: Request) -> crate::Result<Response> {
type OneshotResponse (line 1334) | type OneshotResponse = oneshot::Sender<crate::Result<async_impl::Respons...
type ThreadSender (line 1335) | type ThreadSender = mpsc::UnboundedSender<(async_impl::Request, OneshotR...
type InnerClientHandle (line 1337) | struct InnerClientHandle {
method drop (line 1343) | fn drop(&mut self) {
function forward (line 1471) | async fn forward<F>(fut: F, mut tx: OneshotResponse)
type Timeout (line 1497) | struct Timeout(Option<Duration>);
method default (line 1500) | fn default() -> Timeout {
type KeepCoreThreadAlive (line 1506) | pub(crate) struct KeepCoreThreadAlive(#[allow(dead_code)] Option<Arc<Inn...
method empty (line 1509) | pub(crate) fn empty() -> KeepCoreThreadAlive {
function event_loop_panicked (line 1516) | fn event_loop_panicked() -> ! {
FILE: src/blocking/mod.rs
function get (line 106) | pub fn get<T: crate::IntoUrl>(url: T) -> crate::Result<Response> {
FILE: src/blocking/multipart.rs
type Form (line 52) | pub struct Form {
method new (line 70) | pub fn new() -> Form {
method boundary (line 78) | pub fn boundary(&self) -> &str {
method text (line 91) | pub fn text<T, U>(self, name: T, value: U) -> Form
method file (line 116) | pub fn file<T, U>(self, name: T, path: U) -> io::Result<Form>
method part (line 125) | pub fn part<T>(self, name: T, part: Part) -> Form
method percent_encode_path_segment (line 133) | pub fn percent_encode_path_segment(self) -> Form {
method percent_encode_attr_chars (line 138) | pub fn percent_encode_attr_chars(self) -> Form {
method percent_encode_noop (line 143) | pub fn percent_encode_noop(self) -> Form {
method reader (line 147) | pub(crate) fn reader(self) -> Reader {
method into_reader (line 152) | pub fn into_reader(self) -> impl Read {
method compute_length (line 159) | pub(crate) fn compute_length(&mut self) -> Option<u64> {
method with_inner (line 163) | fn with_inner<F>(self, func: F) -> Self
method fmt (line 174) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Part (line 57) | pub struct Part {
method text (line 181) | pub fn text<T>(value: T) -> Part
method bytes (line 193) | pub fn bytes<T>(value: T) -> Part
method reader (line 207) | pub fn reader<T: Read + Send + 'static>(value: T) -> Part {
method reader_with_length (line 214) | pub fn reader_with_length<T: Read + Send + 'static>(value: T, length: ...
method file (line 223) | pub fn file<T: AsRef<Path>>(path: T) -> io::Result<Part> {
method new (line 240) | fn new(value: Body) -> Part {
method mime_str (line 248) | pub fn mime_str(self, mime: &str) -> crate::Result<Part> {
method mime (line 253) | fn mime(self, mime: Mime) -> Part {
method file_name (line 258) | pub fn file_name<T>(self, filename: T) -> Part
method headers (line 266) | pub fn headers(self, headers: HeaderMap) -> Part {
method with_inner (line 270) | fn with_inner<F>(self, func: F) -> Self
method fmt (line 282) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method default (line 63) | fn default() -> Self {
method value_len (line 291) | fn value_len(&self) -> Option<u64> {
method metadata (line 295) | fn metadata(&self) -> &PartMetadata {
type Reader (line 300) | pub(crate) struct Reader {
method fmt (line 306) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method new (line 312) | fn new(form: Form) -> Reader {
method next_reader (line 321) | fn next_reader(&mut self) {
method read (line 360) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
function form_empty (line 386) | fn form_empty() {
function read_to_end (line 396) | fn read_to_end() {
function read_to_end_with_length (line 437) | fn read_to_end_with_length() {
function read_to_end_with_header (line 470) | fn read_to_end_with_header() {
FILE: src/blocking/request.rs
type Request (line 21) | pub struct Request {
method new (line 39) | pub fn new(method: Method, url: Url) -> Self {
method method (line 48) | pub fn method(&self) -> &Method {
method method_mut (line 54) | pub fn method_mut(&mut self) -> &mut Method {
method url (line 60) | pub fn url(&self) -> &Url {
method url_mut (line 66) | pub fn url_mut(&mut self) -> &mut Url {
method headers (line 72) | pub fn headers(&self) -> &HeaderMap {
method headers_mut (line 78) | pub fn headers_mut(&mut self) -> &mut HeaderMap {
method version (line 84) | pub fn version(&self) -> Version {
method version_mut (line 90) | pub fn version_mut(&mut self) -> &mut Version {
method body (line 96) | pub fn body(&self) -> Option<&Body> {
method body_mut (line 102) | pub fn body_mut(&mut self) -> &mut Option<Body> {
method timeout (line 108) | pub fn timeout(&self) -> Option<&Duration> {
method timeout_mut (line 114) | pub fn timeout_mut(&mut self) -> &mut Option<Duration> {
method try_clone (line 122) | pub fn try_clone(&self) -> Option<Request> {
method into_async (line 140) | pub(crate) fn into_async(self) -> (async_impl::Request, Option<body::S...
type Error (line 660) | type Error = crate::Error;
method try_from (line 662) | fn try_from(req: HttpRequest<T>) -> crate::Result<Self> {
method fmt (line 681) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type RequestBuilder (line 31) | pub struct RequestBuilder {
method new (line 157) | pub(crate) fn new(client: Client, request: crate::Result<Request>) -> ...
method from_parts (line 174) | pub fn from_parts(client: Client, request: Request) -> RequestBuilder {
method header (line 194) | pub fn header<K, V>(self, key: K, value: V) -> RequestBuilder
method header_sensitive (line 205) | fn header_sensitive<K, V>(mut self, key: K, value: V, sensitive: bool)...
method headers (line 261) | pub fn headers(mut self, headers: crate::header::HeaderMap) -> Request...
method basic_auth (line 279) | pub fn basic_auth<U, P>(self, username: U, password: Option<P>) -> Req...
method bearer_auth (line 299) | pub fn bearer_auth<T>(self, token: T) -> RequestBuilder
method body (line 350) | pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder {
method timeout (line 362) | pub fn timeout(mut self, timeout: Duration) -> RequestBuilder {
method query (line 405) | pub fn query<T: Serialize + ?Sized>(mut self, query: &T) -> RequestBui...
method version (line 428) | pub fn version(mut self, version: Version) -> RequestBuilder {
method form (line 467) | pub fn form<T: Serialize + ?Sized>(mut self, form: &T) -> RequestBuild...
method json (line 521) | pub fn json<T: Serialize + ?Sized>(mut self, json: &T) -> RequestBuild...
method multipart (line 561) | pub fn multipart(self, mut multipart: multipart::Form) -> RequestBuild...
method build (line 577) | pub fn build(self) -> crate::Result<Request> {
method build_split (line 586) | pub fn build_split(self) -> (Client, crate::Result<Request>) {
method send (line 596) | pub fn send(self) -> crate::Result<super::Response> {
method try_clone (line 644) | pub fn try_clone(&self) -> Option<RequestBuilder> {
function fmt_request_fields (line 686) | fn fmt_request_fields<'a, 'b>(
function basic_get_request (line 705) | fn basic_get_request() {
function basic_head_request (line 715) | fn basic_head_request() {
function basic_post_request (line 725) | fn basic_post_request() {
function basic_put_request (line 735) | fn basic_put_request() {
function basic_patch_request (line 745) | fn basic_patch_request() {
function basic_delete_request (line 755) | fn basic_delete_request() {
function add_header (line 765) | fn add_header() {
function add_headers (line 780) | fn add_headers() {
function add_headers_multi (line 798) | fn add_headers_multi() {
function add_body (line 822) | fn add_body() {
function add_query_append (line 838) | fn add_query_append() {
function add_query_append_same (line 852) | fn add_query_append_same() {
function add_query_struct (line 865) | fn add_query_struct() {
function add_query_map (line 889) | fn add_query_map() {
function add_form (line 906) | fn add_form() {
function add_json (line 930) | fn add_json() {
function add_json_fail (line 951) | fn add_json_fail() {
function test_replace_headers (line 975) | fn test_replace_headers() {
function normalize_empty_query (line 1001) | fn normalize_empty_query() {
function convert_url_authority_into_basic_auth (line 1017) | fn convert_url_authority_into_basic_auth() {
function convert_from_http_request (line 1031) | fn convert_from_http_request() {
function set_http_request_version (line 1049) | fn set_http_request_version() {
function test_basic_auth_sensitive_header (line 1069) | fn test_basic_auth_sensitive_header() {
function test_bearer_auth_sensitive_header (line 1088) | fn test_bearer_auth_sensitive_header() {
function test_request_cloning (line 1104) | fn test_request_cloning() {
FILE: src/blocking/response.rs
type Response (line 23) | pub struct Response {
method fmt (line 31) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method new (line 37) | pub(crate) fn new(
method status (line 94) | pub fn status(&self) -> StatusCode {
method headers (line 123) | pub fn headers(&self) -> &HeaderMap {
method headers_mut (line 129) | pub fn headers_mut(&mut self) -> &mut HeaderMap {
method cookies (line 142) | pub fn cookies<'a>(&'a self) -> impl Iterator<Item = cookie::Cookie<'a...
method version (line 148) | pub fn version(&self) -> Version {
method url (line 164) | pub fn url(&self) -> &Url {
method remote_addr (line 179) | pub fn remote_addr(&self) -> Option<SocketAddr> {
method extensions (line 184) | pub fn extensions(&self) -> &http::Extensions {
method extensions_mut (line 189) | pub fn extensions_mut(&mut self) -> &mut http::Extensions {
method content_length (line 206) | pub fn content_length(&self) -> Option<u64> {
method json (line 248) | pub fn json<T: DeserializeOwned>(self) -> crate::Result<T> {
method bytes (line 267) | pub fn bytes(self) -> crate::Result<Bytes> {
method text (line 295) | pub fn text(self) -> crate::Result<String> {
method text_with_charset (line 328) | pub fn text_with_charset(self, default_encoding: &str) -> crate::Resul...
method copy_to (line 357) | pub fn copy_to<W: ?Sized>(&mut self, w: &mut W) -> crate::Result<u64>
method error_for_status (line 380) | pub fn error_for_status(self) -> crate::Result<Self> {
method error_for_status_ref (line 411) | pub fn error_for_status_ref(&self) -> crate::Result<&Self> {
method body_mut (line 417) | fn body_mut(&mut self) -> Pin<&mut dyn futures_util::io::AsyncRead> {
method from (line 448) | fn from(r: http::Response<T>) -> Response {
method read (line 436) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
FILE: src/blocking/wait.rs
function timeout (line 9) | pub(crate) fn timeout<F, I, E>(fut: F, timeout: Option<Duration>) -> Res...
type Waited (line 56) | pub(crate) enum Waited<E> {
type ThreadWaker (line 61) | struct ThreadWaker(Thread);
method wake (line 64) | fn wake(self: Arc<Self>) {
method wake_by_ref (line 68) | fn wake_by_ref(self: &Arc<Self>) {
function enter (line 73) | fn enter() {
FILE: src/config.rs
type RequestConfigValue (line 35) | pub(crate) trait RequestConfigValue: Copy + Clone + 'static {
type Value (line 109) | type Value = Duration;
type RequestConfig (line 41) | pub(crate) struct RequestConfig<T: RequestConfigValue>(Option<T::Value>);
method default (line 44) | fn default() -> Self {
function new (line 53) | pub(crate) fn new(v: Option<T::Value>) -> Self {
function fmt_as_field (line 60) | pub(crate) fn fmt_as_field(&self, f: &mut std::fmt::DebugStruct<'_, '_>) {
function fetch (line 69) | pub(crate) fn fetch<'client, 'request>(
function get (line 82) | pub(crate) fn get(ext: &Extensions) -> Option<&T::Value> {
function get_mut (line 87) | pub(crate) fn get_mut(ext: &mut Extensions) -> &mut Option<T::Value> {
type TotalTimeout (line 106) | pub(crate) struct TotalTimeout;
FILE: src/connect.rs
type HttpConnector (line 34) | pub(crate) type HttpConnector = hyper_util::client::legacy::connect::Htt...
type Connector (line 37) | pub(crate) enum Connector {
type Response (line 46) | type Response = Conn;
type Error (line 47) | type Error = BoxError;
type Future (line 48) | type Future = Connecting;
method poll_ready (line 50) | fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self...
method call (line 57) | fn call(&mut self, dst: Uri) -> Self::Future {
type BoxedConnectorService (line 65) | pub(crate) type BoxedConnectorService = BoxCloneSyncService<Unnameable, ...
type BoxedConnectorLayer (line 67) | pub(crate) type BoxedConnectorLayer =
type ConnectorBuilder (line 70) | pub(crate) struct ConnectorBuilder {
method build (line 90) | pub(crate) fn build(self, layers: Vec<BoxedConnectorLayer>) -> Connector
method new (line 171) | pub(crate) fn new<T>(
method new_native_tls (line 226) | pub(crate) fn new_native_tls<T>(
method from_built_native_tls (line 277) | pub(crate) fn from_built_native_tls<T>(
method new_rustls_tls (line 339) | pub(crate) fn new_rustls_tls<T>(
method set_timeout (line 413) | pub(crate) fn set_timeout(&mut self, timeout: Option<Duration>) {
method set_verbose (line 417) | pub(crate) fn set_verbose(&mut self, enabled: bool) {
method set_keepalive (line 421) | pub(crate) fn set_keepalive(&mut self, dur: Option<Duration>) {
method set_keepalive_interval (line 432) | pub(crate) fn set_keepalive_interval(&mut self, dur: Option<Duration>) {
method set_keepalive_retries (line 443) | pub(crate) fn set_keepalive_retries(&mut self, retries: Option<u32>) {
method set_socks_resolver (line 455) | pub(crate) fn set_socks_resolver(&mut self, resolver: DynResolver) {
method set_tcp_user_timeout (line 460) | pub(crate) fn set_tcp_user_timeout(&mut self, dur: Option<Duration>) {
method set_unix_socket (line 472) | pub(crate) fn set_unix_socket(&mut self, path: Option<Arc<std::path::P...
method set_windows_named_pipe (line 477) | pub(crate) fn set_windows_named_pipe(&mut self, pipe: Option<Arc<std::...
type ConnectorService (line 484) | pub(crate) struct ConnectorService {
method connect_socks (line 538) | async fn connect_socks(mut self, dst: Uri, proxy: Intercepted) -> Resu...
method connect_with_maybe_proxy (line 613) | async fn connect_with_maybe_proxy(self, dst: Uri, is_proxy: bool) -> R...
method connect_local_transport (line 700) | async fn connect_local_transport(self, dst: Uri) -> Result<Conn, BoxEr...
method connect_via_proxy (line 783) | async fn connect_via_proxy(self, dst: Uri, proxy: Intercepted) -> Resu...
method should_use_local_transport (line 895) | fn should_use_local_transport(&self) -> bool {
type Response (line 920) | type Response = Conn;
type Error (line 921) | type Error = BoxError;
type Future (line 922) | type Future = Connecting;
method poll_ready (line 924) | fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Sel...
method call (line 928) | fn call(&mut self, dst: Uri) -> Self::Future {
type Inner (line 509) | enum Inner {
method get_http_connector (line 524) | fn get_http_connector(&mut self) -> &mut crate::connect::HttpConnector {
function with_timeout (line 904) | async fn with_timeout<T, F>(f: F, timeout: Option<Duration>) -> Result<T...
type TlsInfoFactory (line 958) | trait TlsInfoFactory {
method tls_info (line 959) | fn tls_info(&self) -> Option<crate::tls::TlsInfo>;
method tls_info (line 964) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 973) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 980) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 997) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1010) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1020) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1037) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1050) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1063) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1071) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1089) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1103) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1114) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1132) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1146) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1159) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1171) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1191) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1207) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1222) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1244) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1260) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1635) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
method tls_info (line 1823) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
type AsyncConn (line 1268) | pub(crate) trait AsyncConn:
type AsyncConnWithInfo (line 1276) | trait AsyncConnWithInfo: AsyncConn + TlsInfoFactory {}
type AsyncConnWithInfo (line 1278) | trait AsyncConnWithInfo: AsyncConn {}
type BoxConn (line 1285) | type BoxConn = Box<dyn AsyncConnWithInfo>;
type Unnameable (line 1290) | pub struct Unnameable(pub(super) Uri);
method connected (line 1308) | fn connected(&self) -> Connected {
method poll_read (line 1326) | fn poll_read(
method poll_write (line 1337) | fn poll_write(
method poll_write_vectored (line 1346) | fn poll_write_vectored(
method is_write_vectored (line 1355) | fn is_write_vectored(&self) -> bool {
method poll_flush (line 1359) | fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(),...
method poll_shutdown (line 1364) | fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<...
type UnixSocketProvider (line 1383) | pub trait UnixSocketProvider {
method reqwest_uds_path (line 1385) | fn reqwest_uds_path(&self, _: Internal) -> &Path;
type Internal (line 1389) | pub struct Internal;
type WindowsNamedPipeProvider (line 1422) | pub trait WindowsNamedPipeProvider {
method reqwest_windows_named_pipe_path (line 1424) | fn reqwest_windows_named_pipe_path(&self, _: Internal) -> &OsStr;
type Internal (line 1428) | pub struct Internal;
type Connecting (line 1453) | pub(crate) type Connecting = Pin<Box<dyn Future<Output = Result<Conn, Bo...
method connected (line 1479) | fn connected(&self) -> Connected {
method connected (line 1499) | fn connected(&self) -> Connected {
method connected (line 1520) | fn connected(&self) -> Connected {
method connected (line 1534) | fn connected(&self) -> Connected {
method connected (line 1550) | fn connected(&self) -> Connected {
method connected (line 1568) | fn connected(&self) -> Connected {
method poll_read (line 1581) | fn poll_read(
method poll_write (line 1592) | fn poll_write(
method poll_write_vectored (line 1601) | fn poll_write_vectored(
method is_write_vectored (line 1610) | fn is_write_vectored(&self) -> bool {
method poll_flush (line 1614) | fn poll_flush(
method poll_shutdown (line 1622) | fn poll_shutdown(
method connected (line 1665) | fn connected(&self) -> Connected {
method connected (line 1680) | fn connected(&self) -> Connected {
method connected (line 1697) | fn connected(&self) -> Connected {
method connected (line 1714) | fn connected(&self) -> Connected {
method connected (line 1733) | fn connected(&self) -> Connected {
method connected (line 1754) | fn connected(&self) -> Connected {
method poll_read (line 1770) | fn poll_read(
method poll_write (line 1781) | fn poll_write(
method poll_write_vectored (line 1790) | fn poll_write_vectored(
method is_write_vectored (line 1799) | fn is_write_vectored(&self) -> bool {
method poll_flush (line 1803) | fn poll_flush(
method poll_shutdown (line 1811) | fn poll_shutdown(
type DnsResolve (line 1841) | pub(super) enum DnsResolve {
type SocksProxyError (line 1847) | pub(super) enum SocksProxyError {
method fmt (line 1924) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
method source (line 1934) | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
function connect (line 1853) | pub(super) async fn connect(
constant OFF (line 1954) | pub(super) const OFF: Wrapper = Wrapper(false);
type Wrapper (line 1957) | pub(super) struct Wrapper(pub(super) bool);
method wrap (line 1960) | pub(super) fn wrap<T: super::AsyncConnWithInfo>(&self, conn: T) -> sup...
type Verbose (line 1973) | struct Verbose<T> {
method connected (line 1979) | fn connected(&self) -> Connected {
method poll_read (line 1985) | fn poll_read(
method poll_write (line 2012) | fn poll_write(
method poll_write_vectored (line 2027) | fn poll_write_vectored(
method is_write_vectored (line 2046) | fn is_write_vectored(&self) -> bool {
method poll_flush (line 2050) | fn poll_flush(
method poll_shutdown (line 2057) | fn poll_shutdown(
function tls_info (line 2067) | fn tls_info(&self) -> Option<crate::tls::TlsInfo> {
type Vectored (line 2072) | struct Vectored<'a, 'b> {
function fmt (line 2078) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
FILE: src/cookie.rs
type CookieStore (line 11) | pub trait CookieStore: Send + Sync {
method set_cookies (line 13) | fn set_cookies(&self, cookie_headers: &mut dyn Iterator<Item = &Header...
method cookies (line 15) | fn cookies(&self, url: &url::Url) -> Option<HeaderValue>;
method set_cookies (line 167) | fn set_cookies(&self, cookie_headers: &mut dyn Iterator<Item = &Header...
method cookies (line 174) | fn cookies(&self, url: &url::Url) -> Option<HeaderValue> {
type Cookie (line 19) | pub struct Cookie<'a>(cookie_crate::Cookie<'a>);
type Jar (line 31) | pub struct Jar(RwLock<cookie_store::CookieStore>);
method add_cookie_str (line 157) | pub fn add_cookie_str(&self, cookie: &str, url: &url::Url) {
function parse (line 36) | fn parse(value: &'a HeaderValue) -> Result<Cookie<'a>, CookieParseError> {
function name (line 45) | pub fn name(&self) -> &str {
function value (line 50) | pub fn value(&self) -> &str {
function http_only (line 55) | pub fn http_only(&self) -> bool {
function secure (line 60) | pub fn secure(&self) -> bool {
function same_site_lax (line 65) | pub fn same_site_lax(&self) -> bool {
function same_site_strict (line 70) | pub fn same_site_strict(&self) -> bool {
function path (line 75) | pub fn path(&self) -> Option<&str> {
function domain (line 80) | pub fn domain(&self) -> Option<&str> {
function max_age (line 85) | pub fn max_age(&self) -> Option<std::time::Duration> {
function expires (line 93) | pub fn expires(&self) -> Option<SystemTime> {
function fmt (line 102) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
function extract_response_cookie_headers (line 107) | pub(crate) fn extract_response_cookie_headers<'a>(
function extract_response_cookies (line 113) | pub(crate) fn extract_response_cookies<'a>(
type CookieParseError (line 123) | pub(crate) struct CookieParseError(cookie_crate::ParseError);
method fmt (line 126) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method fmt (line 132) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type CookieService (line 208) | pub struct CookieService<S> {
function new (line 215) | pub fn new(inner: S, cookie_store: Option<Arc<dyn cookie::CookieStore>>)...
type Response (line 228) | type Response = Response<ResBody>;
type Error (line 229) | type Error = S::Error;
type Future (line 230) | type Future = ResponseFuture<S, ReqBody>;
type Output (line 277) | type Output = Result<Response<ResBody>, S::Error>;
method poll (line 279) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Outp...
function poll_ready (line 233) | fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::...
function call (line 237) | fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
FILE: src/dns/gai.rs
type GaiResolver (line 8) | pub struct GaiResolver(HyperGaiResolver);
method new (line 11) | pub fn new() -> Self {
method default (line 17) | fn default() -> Self {
method resolve (line 23) | fn resolve(&self, name: Name) -> Resolving {
FILE: src/dns/hickory.rs
type HickoryDnsResolver (line 18) | pub(crate) struct HickoryDnsResolver {
type SocketAddrs (line 25) | struct SocketAddrs {
method resolve (line 30) | fn resolve(&self, name: Name) -> Resolving {
type Item (line 45) | type Item = SocketAddr;
method next (line 47) | fn next(&mut self) -> Option<Self::Item> {
function new_resolver (line 57) | fn new_resolver() -> TokioResolver {
FILE: src/dns/resolve.rs
type Addrs (line 15) | pub type Addrs = Box<dyn Iterator<Item = SocketAddr> + Send>;
type Resolving (line 18) | pub type Resolving = Pin<Box<dyn Future<Output = Result<Addrs, BoxError>...
type Resolve (line 21) | pub trait Resolve: Send + Sync {
method resolve (line 33) | fn resolve(&self, name: Name) -> Resolving;
method resolve (line 143) | fn resolve(&self, name: Name) -> Resolving {
type Name (line 38) | pub struct Name(pub(super) HyperName);
method as_str (line 50) | pub fn as_str(&self) -> &str {
type IntoResolve (line 43) | pub trait IntoResolve {
method into_resolve (line 45) | fn into_resolve(self) -> Arc<dyn Resolve>;
method into_resolve (line 155) | fn into_resolve(self) -> Arc<dyn Resolve> {
method into_resolve (line 164) | fn into_resolve(self) -> Arc<dyn Resolve> {
method into_resolve (line 173) | fn into_resolve(self) -> Arc<dyn Resolve> {
type Err (line 56) | type Err = sealed::InvalidNameError;
method from_str (line 58) | fn from_str(host: &str) -> Result<Self, Self::Err> {
type DynResolver (line 66) | pub(crate) struct DynResolver {
method new (line 71) | pub(crate) fn new(resolver: Arc<dyn Resolve>) -> Self {
method gai (line 76) | pub(crate) fn gai() -> Self {
method http_resolve (line 85) | pub(crate) async fn http_resolve(
type Response (line 112) | type Response = Addrs;
type Error (line 113) | type Error = BoxError;
type Future (line 114) | type Future = Resolving;
method poll_ready (line 116) | fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self:...
method call (line 120) | fn call(&mut self, name: HyperName) -> Self::Future {
type DnsResolverWithOverrides (line 125) | pub(crate) struct DnsResolverWithOverrides {
method new (line 131) | pub(crate) fn new(
type InvalidNameError (line 182) | pub struct InvalidNameError {
method fmt (line 187) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
FILE: src/error.rs
type Result (line 10) | pub type Result<T> = std::result::Result<T, Error>;
type Error (line 17) | pub struct Error {
method new (line 30) | pub(crate) fn new<E>(kind: Kind, source: Option<E>) -> Error
method url (line 60) | pub fn url(&self) -> Option<&Url> {
method url_mut (line 69) | pub fn url_mut(&mut self) -> Option<&mut Url> {
method with_url (line 74) | pub fn with_url(mut self, url: Url) -> Self {
method if_no_url (line 79) | pub(crate) fn if_no_url(mut self, f: impl FnOnce() -> Url) -> Self {
method without_url (line 88) | pub fn without_url(mut self) -> Self {
method is_builder (line 94) | pub fn is_builder(&self) -> bool {
method is_redirect (line 99) | pub fn is_redirect(&self) -> bool {
method is_status (line 104) | pub fn is_status(&self) -> bool {
method is_timeout (line 116) | pub fn is_timeout(&self) -> bool {
method is_request (line 141) | pub fn is_request(&self) -> bool {
method is_connect (line 147) | pub fn is_connect(&self) -> bool {
method is_body (line 164) | pub fn is_body(&self) -> bool {
method is_decode (line 169) | pub fn is_decode(&self) -> bool {
method status (line 174) | pub fn status(&self) -> Option<StatusCode> {
method is_upgrade (line 185) | pub fn is_upgrade(&self) -> bool {
method into_io (line 192) | pub(crate) fn into_io(self) -> io::Error {
method fmt (line 211) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method fmt (line 228) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type BoxError (line 21) | pub(crate) type BoxError = Box<dyn StdError + Send + Sync>;
type Inner (line 23) | struct Inner {
function cast_to_internal_error (line 202) | pub(crate) fn cast_to_internal_error(error: BoxError) -> BoxError {
method source (line 276) | fn source(&self) -> Option<&(dyn StdError + 'static)> {
function from (line 283) | fn from(err: Error) -> wasm_bindgen::JsValue {
function from (line 290) | fn from(err: Error) -> js_sys::Error {
type Kind (line 296) | pub(crate) enum Kind {
function builder (line 311) | pub(crate) fn builder<E: Into<BoxError>>(e: E) -> Error {
function body (line 315) | pub(crate) fn body<E: Into<BoxError>>(e: E) -> Error {
function decode (line 319) | pub(crate) fn decode<E: Into<BoxError>>(e: E) -> Error {
function request (line 323) | pub(crate) fn request<E: Into<BoxError>>(e: E) -> Error {
function redirect (line 327) | pub(crate) fn redirect<E: Into<BoxError>>(e: E, url: Url) -> Error {
function status_code (line 331) | pub(crate) fn status_code(
function url_bad_scheme (line 347) | pub(crate) fn url_bad_scheme(url: Url) -> Error {
function url_invalid_uri (line 351) | pub(crate) fn url_invalid_uri(url: Url) -> Error {
function upgrade (line 361) | pub(crate) fn upgrade<E: Into<BoxError>>(e: E) -> Error {
function decode_io (line 368) | pub(crate) fn decode_io(e: io::Error) -> Error {
type TimedOut (line 382) | pub(crate) struct TimedOut;
method fmt (line 385) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type BadScheme (line 393) | pub(crate) struct BadScheme;
method fmt (line 396) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
function assert_send (line 407) | fn assert_send<T: Send>() {}
function assert_sync (line 408) | fn assert_sync<T: Sync>() {}
function test_source_chain (line 411) | fn test_source_chain() {
function mem_size_of (line 422) | fn mem_size_of() {
function roundtrip_io_error (line 428) | fn roundtrip_io_error() {
function from_unknown_io_error (line 442) | fn from_unknown_io_error() {
function is_timeout (line 452) | fn is_timeout() {
FILE: src/into_url.rs
type IntoUrl (line 7) | pub trait IntoUrl: IntoUrlSealed {}
type IntoUrlSealed (line 14) | pub trait IntoUrlSealed {
method into_url (line 17) | fn into_url(self) -> crate::Result<Url>;
method as_str (line 19) | fn as_str(&self) -> &str;
method into_url (line 23) | fn into_url(self) -> crate::Result<Url> {
method as_str (line 41) | fn as_str(&self) -> &str {
method into_url (line 47) | fn into_url(self) -> crate::Result<Url> {
method as_str (line 51) | fn as_str(&self) -> &str {
method into_url (line 57) | fn into_url(self) -> crate::Result<Url> {
method as_str (line 61) | fn as_str(&self) -> &str {
method into_url (line 67) | fn into_url(self) -> crate::Result<Url> {
method as_str (line 71) | fn as_str(&self) -> &str {
function into_url_file_scheme (line 90) | fn into_url_file_scheme() {
function into_url_blob_scheme (line 99) | fn into_url_blob_scheme() {
FILE: src/lib.rs
function get (line 325) | pub async fn get<T: IntoUrl>(url: T) -> crate::Result<Response> {
function _assert_impls (line 329) | fn _assert_impls() {
FILE: src/proxy.rs
type Proxy (line 56) | pub struct Proxy {
method http (line 191) | pub fn http<U: IntoProxy>(proxy_scheme: U) -> crate::Result<Proxy> {
method https (line 209) | pub fn https<U: IntoProxy>(proxy_scheme: U) -> crate::Result<Proxy> {
method all (line 230) | pub fn all<U: IntoProxy>(proxy_scheme: U) -> crate::Result<Proxy> {
method custom (line 255) | pub fn custom<F, U: IntoProxy>(fun: F) -> Proxy
method new (line 265) | fn new(intercept: Intercept) -> Proxy {
method basic_auth (line 289) | pub fn basic_auth(mut self, username: &str, password: &str) -> Proxy {
method custom_http_auth (line 317) | pub fn custom_http_auth(mut self, header_value: HeaderValue) -> Proxy {
method headers (line 338) | pub fn headers(mut self, headers: HeaderMap) -> Proxy {
method no_proxy (line 361) | pub fn no_proxy(mut self, no_proxy: Option<NoProxy>) -> Proxy {
method into_matcher (line 366) | pub(crate) fn into_matcher(self) -> Matcher {
method fmt (line 465) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type NoProxy (line 64) | pub struct NoProxy {
method from_env (line 476) | pub fn from_env() -> Option<NoProxy> {
method from_string (line 506) | pub fn from_string(no_proxy_list: &str) -> Option<Self> {
type Extra (line 69) | struct Extra {
type Matcher (line 76) | pub(crate) struct Matcher {
method system (line 515) | pub(crate) fn system() -> Self {
method intercept (line 528) | pub(crate) fn intercept(&self, dst: &Uri) -> Option<Intercepted> {
method maybe_has_http_auth (line 549) | pub(crate) fn maybe_has_http_auth(&self) -> bool {
method http_non_tunnel_basic_auth (line 553) | pub(crate) fn http_non_tunnel_basic_auth(&self, dst: &Uri) -> Option<H...
method maybe_has_http_custom_headers (line 564) | pub(crate) fn maybe_has_http_custom_headers(&self) -> bool {
method http_non_tunnel_custom_headers (line 568) | pub(crate) fn http_non_tunnel_custom_headers(&self, dst: &Uri) -> Opti...
method fmt (line 581) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Matcher_ (line 83) | enum Matcher_ {
type Intercepted (line 90) | pub(crate) struct Intercepted {
method uri (line 590) | pub(crate) fn uri(&self) -> &http::Uri {
method basic_auth (line 594) | pub(crate) fn basic_auth(&self) -> Option<&HeaderValue> {
method custom_headers (line 601) | pub(crate) fn custom_headers(&self) -> Option<&HeaderMap> {
method raw_auth (line 609) | pub(crate) fn raw_auth(&self) -> Option<(&str, &str)> {
method fmt (line 615) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type IntoProxy (line 120) | pub trait IntoProxy {
method into_proxy (line 121) | fn into_proxy(self) -> crate::Result<Url>;
method into_proxy (line 125) | fn into_proxy(self) -> crate::Result<Url> {
function _implied_bounds (line 168) | fn _implied_bounds() {
function cache_maybe_has_http_auth (line 455) | fn cache_maybe_has_http_auth(url: &Url, extra: &Option<HeaderValue>) -> ...
function cache_maybe_has_http_custom_headers (line 460) | fn cache_maybe_has_http_custom_headers(url: &Url, extra: &Option<HeaderM...
type Intercept (line 760) | enum Intercept {
function url_auth (line 767) | fn url_auth(url: &mut Url, username: &str, password: &str) {
type Custom (line 773) | struct Custom {
method call (line 779) | fn call(&self, uri: &http::Uri) -> Option<matcher::Intercept> {
method fmt (line 804) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
function encode_basic_auth (line 809) | pub(crate) fn encode_basic_auth(username: &str, password: &str) -> Heade...
function url (line 817) | fn url(s: &str) -> http::Uri {
function intercepted_uri (line 821) | fn intercepted_uri(p: &Matcher, s: &str) -> Uri {
function test_http (line 826) | fn test_http() {
function test_https (line 838) | fn test_https() {
function test_all (line 850) | fn test_all() {
function test_custom (line 865) | fn test_custom() {
function test_standard_with_custom_auth_header (line 889) | fn test_standard_with_custom_auth_header() {
function test_custom_with_custom_auth_header (line 902) | fn test_custom_with_custom_auth_header() {
function test_maybe_has_http_auth (line 914) | fn test_maybe_has_http_auth() {
function test_socks_proxy_default_port (line 933) | fn test_socks_proxy_default_port() {
FILE: src/redirect.rs
type Policy (line 28) | pub struct Policy {
method limited (line 51) | pub fn limited(max: usize) -> Self {
method none (line 58) | pub fn none() -> Self {
method custom (line 102) | pub fn custom<T>(policy: T) -> Self
method redirect (line 131) | pub fn redirect(&self, attempt: Attempt) -> Action {
method check (line 146) | pub(crate) fn check(&self, status: StatusCode, next: &Url, previous: &...
method is_default (line 155) | pub(crate) fn is_default(&self) -> bool {
method fmt (line 215) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Attempt (line 35) | pub struct Attempt<'a> {
type Action (line 43) | pub struct Action {
method default (line 161) | fn default() -> Policy {
function status (line 169) | pub fn status(&self) -> StatusCode {
function url (line 174) | pub fn url(&self) -> &Url {
function previous (line 179) | pub fn previous(&self) -> &[Url] {
function follow (line 183) | pub fn follow(self) -> Action {
function stop (line 192) | pub fn stop(self) -> Action {
function error (line 201) | pub fn error<E: Into<Box<dyn StdError + Send + Sync>>>(self, error: E) -...
type PolicyKind (line 208) | enum PolicyKind {
method fmt (line 221) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type ActionKind (line 233) | pub(crate) enum ActionKind {
function remove_sensitive_headers (line 239) | pub(crate) fn remove_sensitive_headers(headers: &mut HeaderMap, next: &U...
type TooManyRedirects (line 254) | struct TooManyRedirects;
method fmt (line 257) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type TowerRedirectPolicy (line 265) | pub(crate) struct TowerRedirectPolicy {
method new (line 273) | pub(crate) fn new(policy: Policy) -> Self {
method with_referer (line 282) | pub(crate) fn with_referer(&mut self, referer: bool) -> &mut Self {
method with_https_only (line 287) | pub(crate) fn with_https_only(&mut self, https_only: bool) -> &mut Self {
method redirect (line 306) | fn redirect(&mut self, attempt: &TowerAttempt<'_>) -> Result<TowerActi...
method on_request (line 336) | fn on_request(&mut self, req: &mut http::Request<async_impl::body::Bod...
method clone_body (line 350) | fn clone_body(&self, body: &async_impl::body::Body) -> Option<async_im...
function make_referer (line 293) | fn make_referer(next: &Url, previous: &Url) -> Option<HeaderValue> {
function test_redirect_policy_limit (line 356) | fn test_redirect_policy_limit() {
function test_redirect_policy_limit_to_0 (line 377) | fn test_redirect_policy_limit_to_0() {
function test_redirect_policy_custom (line 389) | fn test_redirect_policy_custom() {
function test_remove_sensitive_headers (line 412) | fn test_remove_sensitive_headers() {
FILE: src/response.rs
type ResponseUrl (line 4) | pub(crate) struct ResponseUrl(pub Url);
type ResponseBuilderExt (line 9) | pub trait ResponseBuilderExt {
method url (line 12) | fn url(self, url: Url) -> Self;
method url (line 16) | fn url(self, url: Url) -> Self {
function test_response_builder_ext (line 28) | fn test_response_builder_ext() {
FILE: src/retry.rs
type Builder (line 48) | pub struct Builder {
method scoped (line 102) | pub fn scoped(scope: impl scope::Scope) -> Self {
method no_budget (line 118) | pub fn no_budget(mut self) -> Self {
method max_extra_load (line 138) | pub fn max_extra_load(mut self, extra_percent: f32) -> Self {
method max_retries_per_request (line 158) | pub fn max_retries_per_request(mut self, max: u32) -> Self {
method classify_fn (line 179) | pub fn classify_fn<F>(self, func: F) -> Self
method classify (line 187) | pub fn classify(mut self, classifier: impl classify::Classify) -> Self {
method default (line 192) | pub(crate) fn default() -> Builder {
method into_policy (line 202) | pub(crate) fn into_policy(self) -> Policy {
type Policy (line 59) | pub(crate) struct Policy {
type Future (line 222) | type Future = std::future::Ready<()>;
method retry (line 224) | fn retry(
method clone_request (line 250) | fn clone_request(&mut self, req: &Req) -> Option<Req> {
function for_host (line 74) | pub fn for_host<S>(host: S) -> Builder
function never (line 85) | pub fn never() -> Builder {
function scoped (line 89) | fn scoped<F>(func: F) -> Builder
type Req (line 218) | type Req = http::Request<crate::async_impl::body::Body>;
function is_retryable_error (line 270) | fn is_retryable_error(err: &crate::Error) -> bool {
type Scope (line 319) | pub trait Scope: Send + Sync + 'static {
method applies_to (line 320) | fn applies_to(&self, req: &super::Req) -> bool;
method applies_to (line 341) | fn applies_to(&self, req: &super::Req) -> bool {
type ScopeFn (line 335) | pub struct ScopeFn<F>(pub(super) F);
type Scoped (line 347) | pub(super) enum Scoped {
method applies_to (line 353) | pub(super) fn applies_to(&self, req: &super::Req) -> bool {
method fmt (line 364) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type Classify (line 375) | pub trait Classify: Send + Sync + 'static {
method classify (line 376) | fn classify(&self, req_rep: ReqRep<'_>) -> Action;
method classify (line 391) | fn classify(&self, req_rep: ReqRep<'_>) -> Action {
type ClassifyFn (line 385) | pub struct ClassifyFn<F>(pub(super) F);
type ReqRep (line 397) | pub struct ReqRep<'a>(&'a super::Req, Result<http::StatusCode, &'a crate...
function method (line 400) | pub fn method(&self) -> &http::Method {
function uri (line 404) | pub fn uri(&self) -> &http::Uri {
function status (line 408) | pub fn status(&self) -> Option<http::StatusCode> {
function error (line 412) | pub fn error(&self) -> Option<&(dyn std::error::Error + 'static)> {
function retryable (line 416) | pub fn retryable(self) -> Action {
function success (line 420) | pub fn success(self) -> Action {
function is_protocol_nack (line 424) | fn is_protocol_nack(&self) -> bool {
type Action (line 435) | pub enum Action {
type Classifier (line 441) | pub(super) enum Classifier {
method classify (line 448) | pub(super) fn classify<B>(
method fmt (line 469) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
FILE: src/tls.rs
type CertificateRevocationList (line 63) | pub struct CertificateRevocationList {
method from_pem (line 453) | pub fn from_pem(pem: &[u8]) -> crate::Result<CertificateRevocationList> {
method from_pem_bundle (line 482) | pub fn from_pem_bundle(pem_bundle: &[u8]) -> crate::Result<Vec<Certifi...
method as_rustls_crl (line 492) | pub(crate) fn as_rustls_crl<'a>(&self) -> rustls_pki_types::Certificat...
method fmt (line 511) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Certificate (line 70) | pub struct Certificate {
method from_der (line 144) | pub fn from_der(der: &[u8]) -> crate::Result<Certificate> {
method from_pem (line 169) | pub fn from_pem(pem: &[u8]) -> crate::Result<Certificate> {
method from_pem_bundle (line 195) | pub fn from_pem_bundle(pem_bundle: &[u8]) -> crate::Result<Vec<Certifi...
method add_to_native_tls (line 212) | pub(crate) fn add_to_native_tls(self, tls: &mut native_tls_crate::TlsC...
method add_to_rustls (line 217) | pub(crate) fn add_to_rustls(
method read_pem_certs (line 240) | fn read_pem_certs(reader: &mut impl BufRead) -> crate::Result<Vec<Vec<...
method fmt (line 498) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Cert (line 79) | enum Cert {
type Identity (line 86) | pub struct Identity {
method from_pkcs12_der (line 283) | pub fn from_pkcs12_der(der: &[u8], password: &str) -> crate::Result<Id...
method from_pkcs8_pem (line 317) | pub fn from_pkcs8_pem(pem: &[u8], key: &[u8]) -> crate::Result<Identit...
method from_pem (line 351) | pub fn from_pem(buf: &[u8]) -> crate::Result<Identity> {
method add_to_native_tls (line 395) | pub(crate) fn add_to_native_tls(
method add_to_rustls (line 410) | pub(crate) fn add_to_rustls(
method fmt (line 504) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type ClientCert (line 94) | enum ClientCert {
method clone (line 107) | fn clone(&self) -> Self {
type Version (line 518) | pub struct Version(InnerVersion);
constant TLS_1_0 (line 533) | pub const TLS_1_0: Version = Version(InnerVersion::Tls1_0);
constant TLS_1_1 (line 535) | pub const TLS_1_1: Version = Version(InnerVersion::Tls1_1);
constant TLS_1_2 (line 537) | pub const TLS_1_2: Version = Version(InnerVersion::Tls1_2);
constant TLS_1_3 (line 539) | pub const TLS_1_3: Version = Version(InnerVersion::Tls1_3);
method to_native_tls (line 542) | pub(crate) fn to_native_tls(self) -> Option<native_tls_crate::Protocol> {
method from_rustls (line 552) | pub(crate) fn from_rustls(version: rustls::ProtocolVersion) -> Option<...
type InnerVersion (line 522) | enum InnerVersion {
type TlsBackend (line 565) | pub(crate) enum TlsBackend {
method fmt (line 581) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method default (line 599) | fn default() -> TlsBackend {
function rustls_store (line 616) | pub(crate) fn rustls_store(certs: Vec<Certificate>) -> crate::Result<Roo...
function rustls_der (line 626) | pub(crate) fn rustls_der(
type NoVerifier (line 647) | pub(crate) struct NoVerifier;
method verify_server_cert (line 651) | fn verify_server_cert(
method verify_tls12_signature (line 662) | fn verify_tls12_signature(
method verify_tls13_signature (line 671) | fn verify_tls13_signature(
method supported_verify_schemes (line 680) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
type IgnoreHostname (line 701) | pub(crate) struct IgnoreHostname {
method new (line 708) | pub(crate) fn new(
method verify_server_cert (line 721) | fn verify_server_cert(
method verify_tls12_signature (line 741) | fn verify_tls12_signature(
method verify_tls13_signature (line 750) | fn verify_tls13_signature(
method supported_verify_schemes (line 759) | fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
type TlsInfo (line 767) | pub struct TlsInfo {
method peer_certificate (line 773) | pub fn peer_certificate(&self) -> Option<&[u8]> {
method fmt (line 779) | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
function certificate_from_der_invalid (line 790) | fn certificate_from_der_invalid() {
function certificate_from_pem_invalid (line 796) | fn certificate_from_pem_invalid() {
function identity_from_pkcs12_der_invalid (line 802) | fn identity_from_pkcs12_der_invalid() {
function identity_from_pkcs8_pem_invalid (line 808) | fn identity_from_pkcs8_pem_invalid() {
function identity_from_pem_invalid (line 814) | fn identity_from_pem_invalid() {
function identity_from_pem_pkcs1_key (line 820) | fn identity_from_pem_pkcs1_key() {
function certificates_from_pem_bundle (line 830) | fn certificates_from_pem_bundle() {
function crl_from_pem (line 865) | fn crl_from_pem() {
function crl_from_pem_bundle (line 873) | fn crl_from_pem_bundle() {
FILE: src/util.rs
function basic_auth (line 4) | pub fn basic_auth<U, P>(username: U, password: Option<P>) -> HeaderValue
function fast_random (line 28) | pub(crate) fn fast_random() -> u64 {
function replace_headers (line 50) | pub(crate) fn replace_headers(dst: &mut HeaderMap, src: HeaderMap) {
function add_cookie_header (line 81) | pub(crate) fn add_cookie_header(
type Escape (line 91) | pub(crate) struct Escape<'a>(&'a [u8]);
function new (line 95) | pub(crate) fn new(bytes: &'a [u8]) -> Self {
function fmt (line 101) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
function fmt (line 108) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
FILE: src/wasm/body.rs
type Body (line 16) | pub struct Body {
method as_bytes (line 66) | pub fn as_bytes(&self) -> Option<&[u8]> {
method to_js_value (line 74) | pub(crate) fn to_js_value(&self) -> crate::Result<JsValue> {
method as_single (line 87) | pub(crate) fn as_single(&self) -> Option<&Single> {
method from_form (line 96) | pub(crate) fn from_form(f: Form) -> Body {
method into_part (line 104) | pub(crate) fn into_part(self) -> Body {
method is_empty (line 115) | pub(crate) fn is_empty(&self) -> bool {
method try_clone (line 123) | pub(crate) fn try_clone(&self) -> Option<Body> {
method from (line 136) | fn from(bytes: Bytes) -> Body {
method from (line 145) | fn from(vec: Vec<u8>) -> Body {
method from (line 154) | fn from(s: &'static [u8]) -> Body {
method from (line 163) | fn from(s: String) -> Body {
method from (line 172) | fn from(s: &'static str) -> Body {
method fmt (line 180) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Inner (line 20) | enum Inner {
type Single (line 28) | pub(crate) enum Single {
method as_bytes (line 34) | fn as_bytes(&self) -> &[u8] {
method to_js_value (line 41) | pub(crate) fn to_js_value(&self) -> JsValue {
method is_empty (line 53) | fn is_empty(&self) -> bool {
method default (line 186) | fn default() -> Body {
function log (line 211) | fn log(s: String);
function test_body (line 215) | async fn test_body() {
function test_body_js_static_str (line 221) | async fn test_body_js_static_str() {
function test_body_js_string (line 243) | async fn test_body_js_string() {
function test_body_js_static_u8_slice (line 266) | async fn test_body_js_static_u8_slice() {
function test_body_js_vec_u8 (line 294) | async fn test_body_js_vec_u8() {
FILE: src/wasm/client.rs
function fetch_with_request (line 16) | fn fetch_with_request(input: &web_sys::Request) -> Promise;
function js_fetch (line 19) | fn js_fetch(req: &web_sys::Request) -> Promise {
type Client (line 40) | pub struct Client {
method new (line 51) | pub fn new() -> Self {
method builder (line 58) | pub fn builder() -> ClientBuilder {
method get (line 67) | pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method post (line 76) | pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method put (line 85) | pub fn put<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method patch (line 94) | pub fn patch<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method delete (line 103) | pub fn delete<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method head (line 112) | pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
method request (line 124) | pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBu...
method execute (line 141) | pub fn execute(
method merge_headers (line 149) | fn merge_headers(&self, req: &mut Request) {
method execute_request (line 161) | pub(super) fn execute_request(
method fmt (line 177) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type ClientBuilder (line 45) | pub struct ClientBuilder {
method fmt (line 185) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method new (line 293) | pub fn new() -> Self {
method build (line 300) | pub fn build(mut self) -> Result<Client, crate::Error> {
method user_agent (line 312) | pub fn user_agent<V>(mut self, value: V) -> ClientBuilder
method default_headers (line 329) | pub fn default_headers(mut self, headers: HeaderMap) -> ClientBuilder {
method default (line 171) | fn default() -> Self {
function fetch (line 196) | async fn fetch(req: Request) -> crate::Result<Response> {
method default (line 338) | fn default() -> Self {
type Config (line 344) | struct Config {
method fmt_fields (line 359) | fn fmt_fields(&self, f: &mut fmt::DebugStruct<'_, '_>) {
method default (line 350) | fn default() -> Config {
function default_headers (line 371) | async fn default_headers() {
function default_headers_clone (line 395) | async fn default_headers_clone() {
function user_agent_header (line 436) | fn user_agent_header() {
FILE: src/wasm/mod.rs
function set_timeout (line 25) | fn set_timeout(handler: &Function, timeout: i32) -> JsValue;
function clear_timeout (line 28) | fn clear_timeout(handle: JsValue) -> JsValue;
function promise (line 31) | async fn promise<T>(promise: js_sys::Promise) -> Result<T, crate::error:...
type AbortGuard (line 45) | struct AbortGuard {
method new (line 51) | fn new() -> crate::Result<Self> {
method signal (line 60) | fn signal(&self) -> AbortSignal {
method timeout (line 64) | fn timeout(&mut self, timeout: Duration) {
method drop (line 79) | fn drop(&mut self) {
FILE: src/wasm/multipart.rs
type Form (line 12) | pub struct Form {
method is_empty (line 17) | pub(crate) fn is_empty(&self) -> bool {
method new (line 52) | pub fn new() -> Form {
method text (line 67) | pub fn text<T, U>(self, name: T, value: U) -> Form
method part (line 76) | pub fn part<T>(self, name: T, part: Part) -> Form
method with_inner (line 83) | fn with_inner<F>(self, func: F) -> Self
method to_form_data (line 92) | pub(crate) fn to_form_data(&self) -> crate::Result<FormData> {
method fmt (line 107) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Part (line 23) | pub struct Part {
method text (line 116) | pub fn text<T>(value: T) -> Part
method bytes (line 128) | pub fn bytes<T>(value: T) -> Part
method stream (line 140) | pub fn stream<T: Into<Body>>(value: T) -> Part {
method new (line 144) | fn new(value: Body) -> Part {
method mime_str (line 152) | pub fn mime_str(self, mime: &str) -> crate::Result<Part> {
method mime (line 157) | fn mime(self, mime: Mime) -> Part {
method file_name (line 162) | pub fn file_name<T>(self, filename: T) -> Part
method headers (line 170) | pub fn headers(self, headers: HeaderMap) -> Part {
method with_inner (line 174) | fn with_inner<F>(self, func: F) -> Self
method append_to_form (line 184) | fn append_to_form(
method blob (line 218) | fn blob(&self, mime_type: Option<&Mime>) -> crate::Result<web_sys::Blo...
method fmt (line 242) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type FormParts (line 28) | pub(crate) struct FormParts<P> {
type PartMetadata (line 32) | pub(crate) struct PartMetadata {
method new (line 284) | pub(crate) fn new() -> Self {
method mime (line 292) | pub(crate) fn mime(mut self, mime: Mime) -> Self {
method file_name (line 297) | pub(crate) fn file_name<T>(mut self, filename: T) -> Self
method headers (line 305) | pub(crate) fn headers<T>(mut self, headers: T) -> Self
method fmt_fields (line 315) | pub(crate) fn fmt_fields<'f, 'fa, 'fb>(
type PartProps (line 38) | pub(crate) trait PartProps {
method metadata (line 39) | fn metadata(&self) -> &PartMetadata;
method metadata (line 251) | fn metadata(&self) -> &PartMetadata {
method default (line 45) | fn default() -> Self {
function new (line 259) | pub(crate) fn new() -> Self {
function part (line 264) | pub(crate) fn part<T>(mut self, name: T, part: P) -> Self
function fmt_fields (line 274) | pub(crate) fn fmt_fields(&self, ty_name: &'static str, f: &mut fmt::Form...
function test_multipart_js (line 334) | async fn test_multipart_js() {
FILE: src/wasm/request.rs
type Request (line 20) | pub struct Request {
method new (line 40) | pub fn new(method: Method, url: Url) -> Self {
method method (line 55) | pub fn method(&self) -> &Method {
method method_mut (line 61) | pub fn method_mut(&mut self) -> &mut Method {
method url (line 67) | pub fn url(&self) -> &Url {
method url_mut (line 73) | pub fn url_mut(&mut self) -> &mut Url {
method headers (line 79) | pub fn headers(&self) -> &HeaderMap {
method headers_mut (line 85) | pub fn headers_mut(&mut self) -> &mut HeaderMap {
method body (line 91) | pub fn body(&self) -> Option<&Body> {
method body_mut (line 97) | pub fn body_mut(&mut self) -> &mut Option<Body> {
method timeout (line 103) | pub fn timeout(&self) -> Option<&Duration> {
method timeout_mut (line 109) | pub fn timeout_mut(&mut self) -> &mut Option<Duration> {
method try_clone (line 116) | pub fn try_clone(&self) -> Option<Request> {
method fmt (line 564) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Error (line 592) | type Error = crate::Error;
method try_from (line 594) | fn try_from(req: HttpRequest<T>) -> crate::Result<Self> {
type RequestBuilder (line 32) | pub struct RequestBuilder {
method new (line 136) | pub(super) fn new(client: Client, request: crate::Result<Request>) -> ...
method from_parts (line 141) | pub fn from_parts(client: crate::Client, request: crate::Request) -> c...
method query (line 172) | pub fn query<T: Serialize + ?Sized>(mut self, query: &T) -> RequestBui...
method form (line 210) | pub fn form<T: Serialize + ?Sized>(mut self, form: &T) -> RequestBuild...
method json (line 233) | pub fn json<T: Serialize + ?Sized>(mut self, json: &T) -> RequestBuild...
method basic_auth (line 253) | pub fn basic_auth<U, P>(self, username: U, password: Option<P>) -> Req...
method bearer_auth (line 263) | pub fn bearer_auth<T>(self, token: T) -> RequestBuilder
method body (line 272) | pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder {
method timeout (line 280) | pub fn timeout(mut self, timeout: Duration) -> RequestBuilder {
method multipart (line 290) | pub fn multipart(mut self, multipart: super::multipart::Form) -> Reque...
method header (line 298) | pub fn header<K, V>(mut self, key: K, value: V) -> RequestBuilder
method headers (line 326) | pub fn headers(mut self, headers: crate::header::HeaderMap) -> Request...
method fetch_mode_no_cors (line 342) | pub fn fetch_mode_no_cors(mut self) -> RequestBuilder {
method fetch_credentials_same_origin (line 358) | pub fn fetch_credentials_same_origin(mut self) -> RequestBuilder {
method fetch_credentials_include (line 374) | pub fn fetch_credentials_include(mut self) -> RequestBuilder {
method fetch_credentials_omit (line 390) | pub fn fetch_credentials_omit(mut self) -> RequestBuilder {
method fetch_cache_default (line 406) | pub fn fetch_cache_default(mut self) -> RequestBuilder {
method fetch_cache_no_store (line 422) | pub fn fetch_cache_no_store(mut self) -> RequestBuilder {
method fetch_cache_reload (line 438) | pub fn fetch_cache_reload(mut self) -> RequestBuilder {
method fetch_cache_no_cache (line 454) | pub fn fetch_cache_no_cache(mut self) -> RequestBuilder {
method fetch_cache_force_cache (line 470) | pub fn fetch_cache_force_cache(mut self) -> RequestBuilder {
method fetch_cache_only_if_cached (line 486) | pub fn fetch_cache_only_if_cached(mut self) -> RequestBuilder {
method build (line 495) | pub fn build(self) -> crate::Result<Request> {
method build_split (line 504) | pub fn build_split(self) -> (Client, crate::Result<Request>) {
method send (line 528) | pub async fn send(self) -> crate::Result<Response> {
method try_clone (line 551) | pub fn try_clone(&self) -> Option<RequestBuilder> {
method fmt (line 570) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
function fmt_request_fields (line 579) | fn fmt_request_fields<'a, 'b>(
type Error (line 617) | type Error = crate::Error;
function try_from (line 619) | fn try_from(req: Request) -> crate::Result<Self> {
FILE: src/wasm/response.rs
type Response (line 20) | pub struct Response {
method new (line 29) | pub(super) fn new(
method status (line 43) | pub fn status(&self) -> StatusCode {
method headers (line 49) | pub fn headers(&self) -> &HeaderMap {
method headers_mut (line 55) | pub fn headers_mut(&mut self) -> &mut HeaderMap {
method content_length (line 66) | pub fn content_length(&self) -> Option<u64> {
method url (line 77) | pub fn url(&self) -> &Url {
method json (line 92) | pub async fn json<T: DeserializeOwned>(self) -> crate::Result<T> {
method text (line 99) | pub async fn text(self) -> crate::Result<String> {
method bytes (line 117) | pub async fn bytes(self) -> crate::Result<Bytes> {
method bytes_stream (line 137) | pub fn bytes_stream(self) -> impl futures_core::Stream<Item = crate::R...
method error_for_status (line 167) | pub fn error_for_status(self) -> crate::Result<Self> {
method error_for_status_ref (line 177) | pub fn error_for_status_ref(&self) -> crate::Result<&Self> {
method fmt (line 188) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
FILE: tests/badssl.rs
function test_badssl_modern (line 6) | async fn test_badssl_modern() {
function test_badssl_self_signed (line 24) | async fn test_badssl_self_signed() {
function test_badssl_no_built_in_roots (line 43) | async fn test_badssl_no_built_in_roots() {
function test_badssl_wrong_host (line 58) | async fn test_badssl_wrong_host() {
FILE: tests/blocking.rs
function test_response_text (line 10) | fn test_response_text() {
function donot_set_content_length_0_if_have_no_body (line 24) | fn donot_set_content_length_0_if_have_no_body() {
function test_response_non_utf_8_text (line 47) | fn test_response_non_utf_8_text() {
function test_response_json (line 68) | fn test_response_json() {
function test_response_copy_to (line 82) | fn test_response_copy_to() {
function test_get (line 96) | fn test_get() {
function test_post (line 110) | fn test_post() {
function test_post_form (line 134) | fn test_post_form() {
function test_error_for_status_4xx (line 165) | fn test_error_for_status_4xx() {
function test_error_for_status_5xx (line 184) | fn test_error_for_status_5xx() {
function test_default_headers (line 204) | fn test_default_headers() {
function test_override_default_headers (line 225) | fn test_override_default_headers() {
function test_appended_headers_not_overwritten (line 259) | fn test_appended_headers_not_overwritten() {
function test_blocking_inside_a_runtime (line 309) | fn test_blocking_inside_a_runtime() {
function test_allowed_methods_blocking (line 325) | fn test_allowed_methods_blocking() {
function test_body_from_bytes (line 347) | fn test_body_from_bytes() {
function blocking_add_json_default_content_type_if_not_set_manually (line 363) | fn blocking_add_json_default_content_type_if_not_set_manually() {
function blocking_update_json_content_type_if_set_manually (line 381) | fn blocking_update_json_content_type_if_set_manually() {
function test_response_no_tls_info_for_http (line 395) | fn test_response_no_tls_info_for_http() {
FILE: tests/brotli.rs
function brotli_response (line 7) | async fn brotli_response() {
function brotli_single_byte_chunks (line 12) | async fn brotli_single_byte_chunks() {
function test_brotli_empty_body (line 17) | async fn test_brotli_empty_body() {
function test_accept_header_is_not_changed_if_set (line 40) | async fn test_accept_header_is_not_changed_if_set() {
function test_accept_encoding_header_is_not_changed_if_set (line 66) | async fn test_accept_encoding_header_is_not_changed_if_set() {
function brotli_case (line 88) | async fn brotli_case(response_size: usize, chunk_size: usize) {
constant COMPRESSED_RESPONSE_HEADERS (line 150) | const COMPRESSED_RESPONSE_HEADERS: &[u8] = b"HTTP/1.1 200 OK\x0d\x0a\
constant RESPONSE_CONTENT (line 155) | const RESPONSE_CONTENT: &str = "some message here";
function brotli_compress (line 157) | fn brotli_compress(input: &[u8]) -> Vec<u8> {
function test_non_chunked_non_fragmented_response (line 165) | async fn test_non_chunked_non_fragmented_response() {
function test_chunked_fragmented_response_1 (line 196) | async fn test_chunked_fragmented_response_1() {
function test_chunked_fragmented_response_2 (line 250) | async fn test_chunked_fragmented_response_2() {
function test_chunked_fragmented_response_with_extra_bytes (line 305) | async fn test_chunked_fragmented_response_with_extra_bytes() {
FILE: tests/ci.rs
function server_panics_should_propagate (line 8) | async fn server_panics_should_propagate() {
FILE: tests/client.rs
function auto_headers (line 15) | async fn auto_headers() {
function donot_set_content_length_0_if_have_no_body (line 65) | async fn donot_set_content_length_0_if_have_no_body() {
function user_agent (line 89) | async fn user_agent() {
function response_text (line 109) | async fn response_text() {
function response_bytes (line 127) | async fn response_bytes() {
function response_json (line 146) | async fn response_json() {
function body_pipe_response (line 163) | async fn body_pipe_response() {
function overridden_dns_resolution_with_gai (line 211) | async fn overridden_dns_resolution_with_gai() {
function overridden_dns_resolution_with_gai_multiple (line 234) | async fn overridden_dns_resolution_with_gai_multiple() {
function overridden_dns_resolution_with_hickory_dns (line 269) | async fn overridden_dns_resolution_with_hickory_dns() {
function overridden_dns_resolution_with_hickory_dns_multiple (line 294) | async fn overridden_dns_resolution_with_hickory_dns_multiple() {
function use_preconfigured_tls_with_bogus_backend (line 330) | fn use_preconfigured_tls_with_bogus_backend() {
function use_preconfigured_native_tls_default (line 341) | fn use_preconfigured_native_tls_default() {
function use_preconfigured_rustls_default (line 356) | fn use_preconfigured_rustls_default() {
function http1_only (line 376) | async fn http1_only() {
function http2_upgrade (line 392) | async fn http2_upgrade() {
function test_allowed_methods (line 413) | async fn test_allowed_methods() {
function add_json_default_content_type_if_not_set_manually (line 437) | fn add_json_default_content_type_if_not_set_manually() {
function update_json_content_type_if_set_manually (line 453) | fn update_json_content_type_if_set_manually() {
function test_tls_info (line 467) | async fn test_tls_info() {
function close_connection_after_idle_timeout (line 496) | async fn close_connection_after_idle_timeout() {
function http1_reason_phrase (line 517) | async fn http1_reason_phrase() {
function error_has_url (line 545) | async fn error_has_url() {
FILE: tests/connector_layers.rs
function non_op_layer (line 16) | async fn non_op_layer() {
function non_op_layer_with_timeout (line 36) | async fn non_op_layer_with_timeout() {
function with_connect_timeout_layer_never_returning (line 58) | async fn with_connect_timeout_layer_never_returning() {
function with_connect_timeout_layer_slow (line 79) | async fn with_connect_timeout_layer_slow() {
function multiple_timeout_layers_under_threshold (line 102) | async fn multiple_timeout_layers_under_threshold() {
function multiple_timeout_layers_over_threshold (line 126) | async fn multiple_timeout_layers_over_threshold() {
function with_concurrency_limit_layer_timeout (line 152) | async fn with_concurrency_limit_layer_timeout() {
function with_concurrency_limit_layer_success (line 189) | async fn with_concurrency_limit_layer_success() {
function non_op_layer_blocking_client (line 229) | fn non_op_layer_blocking_client() {
function timeout_layer_blocking_client (line 248) | fn timeout_layer_blocking_client() {
function concurrency_layer_blocking_client_timeout (line 270) | fn concurrency_layer_blocking_client_timeout() {
function concurrency_layer_blocking_client_success (line 307) | fn concurrency_layer_blocking_client_success() {
function no_generic_bounds_required_for_client_new (line 348) | async fn no_generic_bounds_required_for_client_new() {
function no_generic_bounds_required_for_client_new_blocking (line 363) | fn no_generic_bounds_required_for_client_new_blocking() {
FILE: tests/cookie.rs
function cookie_response_accessor (line 5) | async fn cookie_response_accessor() {
function cookie_store_simple (line 75) | async fn cookie_store_simple() {
function cookie_store_overwrite_existing (line 99) | async fn cookie_store_overwrite_existing() {
function cookie_store_max_age (line 135) | async fn cookie_store_max_age() {
function cookie_store_expires (line 154) | async fn cookie_store_expires() {
function cookie_store_path (line 177) | async fn cookie_store_path() {
FILE: tests/deflate.rs
function deflate_response (line 9) | async fn deflate_response() {
function deflate_single_byte_chunks (line 14) | async fn deflate_single_byte_chunks() {
function test_deflate_empty_body (line 19) | async fn test_deflate_empty_body() {
function test_accept_header_is_not_changed_if_set (line 42) | async fn test_accept_header_is_not_changed_if_set() {
function test_accept_encoding_header_is_not_changed_if_set (line 68) | async fn test_accept_encoding_header_is_not_changed_if_set() {
function deflate_case (line 90) | async fn deflate_case(response_size: usize, chunk_size: usize) {
constant COMPRESSED_RESPONSE_HEADERS (line 152) | const COMPRESSED_RESPONSE_HEADERS: &[u8] = b"HTTP/1.1 200 OK\x0d\x0a\
constant RESPONSE_CONTENT (line 157) | const RESPONSE_CONTENT: &str = "some message here";
function deflate_compress (line 159) | fn deflate_compress(input: &[u8]) -> Vec<u8> {
function test_non_chunked_non_fragmented_response (line 166) | async fn test_non_chunked_non_fragmented_response() {
function test_chunked_fragmented_response_1 (line 197) | async fn test_chunked_fragmented_response_1() {
function test_chunked_fragmented_response_2 (line 251) | async fn test_chunked_fragmented_response_2() {
function test_chunked_fragmented_response_with_extra_bytes (line 306) | async fn test_chunked_fragmented_response_with_extra_bytes() {
FILE: tests/gzip.rs
function gzip_response (line 11) | async fn gzip_response() {
function gzip_single_byte_chunks (line 16) | async fn gzip_single_byte_chunks() {
function test_gzip_empty_body (line 21) | async fn test_gzip_empty_body() {
function test_accept_header_is_not_changed_if_set (line 44) | async fn test_accept_header_is_not_changed_if_set() {
function test_accept_encoding_header_is_not_changed_if_set (line 70) | async fn test_accept_encoding_header_is_not_changed_if_set() {
function gzip_case (line 92) | async fn gzip_case(response_size: usize, chunk_size: usize) {
constant COMPRESSED_RESPONSE_HEADERS (line 154) | const COMPRESSED_RESPONSE_HEADERS: &[u8] = b"HTTP/1.1 200 OK\x0d\x0a\
constant RESPONSE_CONTENT (line 159) | const RESPONSE_CONTENT: &str = "some message here";
function gzip_compress (line 161) | fn gzip_compress(input: &[u8]) -> Vec<u8> {
function test_non_chunked_non_fragmented_response (line 168) | async fn test_non_chunked_non_fragmented_response() {
function test_chunked_fragmented_response_1 (line 199) | async fn test_chunked_fragmented_response_1() {
function test_chunked_fragmented_response_2 (line 252) | async fn test_chunked_fragmented_response_2() {
function test_chunked_fragmented_response_with_extra_bytes (line 306) | async fn test_chunked_fragmented_response_with_extra_bytes() {
FILE: tests/http3.rs
function assert_send_sync (line 10) | fn assert_send_sync<T: Send + Sync>(_: &T) {}
function http3_request_full (line 13) | async fn http3_request_full() {
function find_free_tcp_addr (line 41) | async fn find_free_tcp_addr() -> std::net::SocketAddr {
function http3_test_failed_connection (line 48) | async fn http3_test_failed_connection() {
function http3_test_concurrent_request (line 111) | async fn http3_test_concurrent_request() {
function http3_test_h3_stop_sending_before_response_no_error (line 158) | async fn http3_test_h3_stop_sending_before_response_no_error() {
function http3_test_h3_stop_sending_before_response_no_error_request_body (line 251) | async fn http3_test_h3_stop_sending_before_response_no_error_request_bod...
function http3_test_h3_stop_sending_before_response_internal_error (line 347) | async fn http3_test_h3_stop_sending_before_response_internal_error() {
function http3_test_reconnection (line 447) | async fn http3_test_reconnection() {
function http3_request_stream (line 516) | async fn http3_request_stream() {
function http3_request_stream_error (line 550) | async fn http3_request_stream_error() {
FILE: tests/multipart.rs
function text_part (line 7) | async fn text_part() {
function stream_part (line 61) | async fn stream_part() {
function blocking_file_part (line 125) | fn blocking_file_part() {
function async_impl_file_part (line 182) | async fn async_impl_file_part() {
FILE: tests/not_tcp.rs
function unix_socket_works (line 8) | async fn unix_socket_works() {
function unix_socket_ignores_proxies (line 24) | async fn unix_socket_ignores_proxies() {
function unix_socket_uses_tls (line 43) | async fn unix_socket_uses_tls() {
FILE: tests/proxy.rs
function http_proxy (line 15) | async fn http_proxy() {
function http_proxy_basic_auth (line 41) | async fn http_proxy_basic_auth() {
function http_proxy_basic_auth_parsed (line 75) | async fn http_proxy_basic_auth_parsed() {
function system_http_proxy_basic_auth_parsed (line 105) | async fn system_http_proxy_basic_auth_parsed() {
function test_no_proxy (line 150) | async fn test_no_proxy() {
function test_custom_headers (line 176) | async fn test_custom_headers() {
function test_using_system_proxy (line 211) | async fn test_using_system_proxy() {
function http_over_http (line 243) | async fn http_over_http() {
function tunnel_detects_auth_required (line 271) | async fn tunnel_detects_auth_required() {
function tunnel_includes_proxy_auth (line 309) | async fn tunnel_includes_proxy_auth() {
function tunnel_includes_user_agent (line 349) | async fn tunnel_includes_user_agent() {
function tunnel_includes_proxy_auth_with_multiple_proxies (line 386) | async fn tunnel_includes_proxy_auth_with_multiple_proxies() {
FILE: tests/redirect.rs
function test_redirect_301_and_302_and_303_changes_post_to_get (line 9) | async fn test_redirect_301_and_302_and_303_changes_post_to_get() {
function test_redirect_307_and_308_tries_to_get_again (line 46) | async fn test_redirect_307_and_308_tries_to_get_again() {
function test_redirect_307_and_308_tries_to_post_again (line 82) | async fn test_redirect_307_and_308_tries_to_post_again() {
function test_redirect_307_does_not_try_if_reader_cannot_reset (line 132) | fn test_redirect_307_does_not_try_if_reader_cannot_reset() {
function test_redirect_removes_sensitive_headers (line 171) | async fn test_redirect_removes_sensitive_headers() {
function test_redirect_policy_can_return_errors (line 218) | async fn test_redirect_policy_can_return_errors() {
function test_redirect_policy_can_stop_redirects_without_an_error (line 234) | async fn test_redirect_policy_can_stop_redirects_without_an_error() {
function test_referer_is_not_set_if_disabled (line 260) | async fn test_referer_is_not_set_if_disabled() {
function test_invalid_location_stops_redirect_gh484 (line 287) | async fn test_invalid_location_stops_redirect_gh484() {
function test_invalid_scheme_is_rejected (line 305) | async fn test_invalid_scheme_is_rejected() {
function test_redirect_302_with_set_cookies (line 322) | async fn test_redirect_302_with_set_cookies() {
function test_redirect_https_only_enforced_gh1312 (line 355) | async fn test_redirect_https_only_enforced_gh1312() {
function test_redirect_limit_to_1 (line 381) | async fn test_redirect_limit_to_1() {
function test_redirect_custom (line 415) | async fn test_redirect_custom() {
function test_scheme_only_check_after_policy_return_follow (line 447) | async fn test_scheme_only_check_after_policy_return_follow() {
function test_redirect_301_302_303_empty_payload_headers (line 483) | async fn test_redirect_301_302_303_empty_payload_headers() {
FILE: tests/retry.rs
function retries_apply_in_scope (line 10) | async fn retries_apply_in_scope() {
function default_retries_have_a_limit (line 52) | async fn default_retries_have_a_limit() {
function highly_concurrent_requests_to_http2_server_with_low_max_concurrent_streams (line 80) | async fn highly_concurrent_requests_to_http2_server_with_low_max_concurr...
function highly_concurrent_requests_to_slow_http2_server_with_low_max_concurrent_streams (line 111) | async fn highly_concurrent_requests_to_slow_http2_server_with_low_max_co...
FILE: tests/support/delay_layer.rs
type DelayLayer (line 14) | pub struct DelayLayer {
method new (line 19) | pub const fn new(delay: Duration) -> Self {
type Service (line 25) | type Service = Delay<S>;
method layer (line 26) | fn layer(&self, service: S) -> Self::Service {
method fmt (line 32) | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
type Delay (line 41) | pub struct Delay<S> {
function new (line 46) | pub fn new(inner: S, delay: Duration) -> Self {
type Response (line 56) | type Response = S::Response;
type Error (line 58) | type Error = BoxError;
type Future (line 60) | type Future = ResponseFuture<S::Future>;
type Output (line 102) | type Output = Result<S, BoxError>;
method poll (line 104) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Outp...
function poll_ready (line 62) | fn poll_ready(
function call (line 72) | fn call(&mut self, req: Request) -> Self::Future {
function new (line 92) | pub(crate) fn new(response: S, sleep: Sleep) -> Self {
FILE: tests/support/delay_server.rs
type Server (line 25) | pub struct Server {
method new (line 34) | pub async fn new<F1, Fut, F2, Bu>(func: F1, apply_config: F2, delay: D...
method shutdown (line 112) | pub async fn shutdown(mut self) {
method addr (line 120) | pub fn addr(&self) -> net::SocketAddr {
type Builder (line 31) | type Builder = hyper_util::server::conn::auto::Builder<hyper_util::rt::T...
FILE: tests/support/error.rs
function inspect (line 3) | pub fn inspect<E>(err: E) -> Vec<String>
FILE: tests/support/not_tcp.rs
type Server (line 13) | pub struct Server {
method path (line 26) | pub fn path(&self) -> &std::path::Path {
method events (line 30) | pub fn events(&mut self) -> Vec<Event> {
type Event (line 21) | pub enum Event {
method drop (line 40) | fn drop(&mut self) {
function uds (line 53) | pub fn uds<F, Fut>(func: F) -> Server
type Builder (line 61) | type Builder = hyper_util::server::conn::auto::Builder<hyper_util::rt::T...
function uds_with_config (line 63) | pub fn uds_with_config<F1, Fut, F2, Bu>(func: F1, apply_config: F2) -> S...
function random_tmp_path (line 137) | fn random_tmp_path() -> std::path::PathBuf {
FILE: tests/support/server.rs
type Server (line 17) | pub struct Server {
method addr (line 30) | pub fn addr(&self) -> net::SocketAddr {
method events (line 34) | pub fn events(&mut self) -> Vec<Event> {
type Event (line 25) | pub enum Event {
method drop (line 44) | fn drop(&mut self) {
function http (line 57) | pub fn http<F, Fut>(func: F) -> Server
type Builder (line 69) | type Builder = hyper_util::server::conn::auto::Builder<hyper_util::rt::T...
function http_with_config (line 71) | pub fn http_with_config<F1, Fut, E, F2, Bu>(func: F1, apply_config: F2) ...
type Http3 (line 157) | pub struct Http3 {
method new (line 163) | pub fn new() -> Self {
method with_addr (line 167) | pub fn with_addr(mut self, addr: std::net::SocketAddr) -> Self {
method build (line 172) | pub fn build<F1, Fut>(self, func: F1) -> Server
method build_with_stop_sending_before_response (line 187) | pub fn build_with_stop_sending_before_response<F1, Fut>(
method build_server (line 206) | fn build_server<F1, Fut>(
function install_default_crypto_provider (line 335) | fn install_default_crypto_provider() -> bool {
function low_level_with_response (line 352) | pub fn low_level_with_response<F>(do_response: F) -> Server
function low_level_server_client (line 412) | async fn low_level_server_client<F>(mut client_socket: TcpStream, do_res...
function low_level_read_http_request (line 429) | async fn low_level_read_http_request(
FILE: tests/timeouts.rs
function client_timeout (line 9) | async fn client_timeout() {
function request_timeout (line 37) | async fn request_timeout() {
function connect_timeout (line 69) | async fn connect_timeout() {
function connect_many_timeout_succeeds (line 93) | async fn connect_many_timeout_succeeds() {
function connect_many_timeout (line 121) | async fn connect_many_timeout() {
function response_timeout (line 152) | async fn response_timeout() {
function read_timeout_applies_to_headers (line 183) | async fn read_timeout_applies_to_headers() {
function read_timeout_applies_to_body (line 212) | async fn read_timeout_applies_to_body() {
function read_timeout_allows_slow_response_body (line 244) | async fn read_timeout_allows_slow_response_body() {
function timeout_closes_connection (line 286) | fn timeout_closes_connection() {
function timeout_blocking_request (line 313) | fn timeout_blocking_request() {
function connect_timeout_blocking_request (line 341) | fn connect_timeout_blocking_request() {
function blocking_request_timeout_body (line 360) | fn blocking_request_timeout_body() {
function write_timeout_large_body (line 397) | fn write_timeout_large_body() {
function response_body_timeout_forwards_size_hint (line 430) | async fn response_body_timeout_forwards_size_hint() {
FILE: tests/upgrade.rs
function http_upgrade (line 8) | async fn http_upgrade() {
FILE: tests/wasm_simple.rs
function log (line 13) | fn log(s: &str);
function simple_example (line 17) | async fn simple_example() {
function request_with_timeout (line 28) | async fn request_with_timeout() {
function preserve_content_type_if_set_manually (line 43) | fn preserve_content_type_if_set_manually() {
function add_default_json_content_type_if_not_set_manually (line 63) | fn add_default_json_content_type_if_not_set_manually() {
FILE: tests/zstd.rs
function zstd_response (line 6) | async fn zstd_response() {
function zstd_single_byte_chunks (line 11) | async fn zstd_single_byte_chunks() {
function test_zstd_empty_body (line 16) | async fn test_zstd_empty_body() {
function test_accept_header_is_not_changed_if_set (line 39) | async fn test_accept_header_is_not_changed_if_set() {
function test_accept_encoding_header_is_not_changed_if_set (line 65) | async fn test_accept_encoding_header_is_not_changed_if_set() {
function zstd_case (line 87) | async fn zstd_case(response_size: usize, chunk_size: usize) {
constant COMPRESSED_RESPONSE_HEADERS (line 147) | const COMPRESSED_RESPONSE_HEADERS: &[u8] = b"HTTP/1.1 200 OK\x0d\x0a\
constant RESPONSE_CONTENT (line 152) | const RESPONSE_CONTENT: &str = "some message here";
function zstd_compress (line 154) | fn zstd_compress(input: &[u8]) -> Vec<u8> {
function test_non_chunked_non_fragmented_response (line 159) | async fn test_non_chunked_non_fragmented_response() {
function test_non_chunked_non_fragmented_multiple_frames_response (line 191) | async fn test_non_chunked_non_fragmented_multiple_frames_response() {
function test_chunked_fragmented_multiple_frames_in_one_chunk (line 231) | async fn test_chunked_fragmented_multiple_frames_in_one_chunk() {
function test_connection_reuse_with_chunked_fragmented_multiple_frames_in_one_chunk (line 300) | async fn test_connection_reuse_with_chunked_fragmented_multiple_frames_i...
function test_chunked_fragmented_response_1 (line 407) | async fn test_chunked_fragmented_response_1() {
function test_chunked_fragmented_response_2 (line 461) | async fn test_chunked_fragmented_response_2() {
function test_chunked_fragmented_response_with_extra_bytes (line 516) | async fn test_chunked_fragmented_response_with_extra_bytes() {
Condensed preview — 93 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (982K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 22,
"preview": "github: [seanmonstar]\n"
},
{
"path": ".github/dependabot.yml",
"chars": 660,
"preview": "version: 2\n\n# Only enable cargo, turn off npm from wasm example\nupdates:\n - package-ecosystem: \"github-actions\"\n # W"
},
{
"path": ".github/workflows/ci.yml",
"chars": 12726,
"preview": "name: CI\n\non:\n pull_request:\n push:\n branches:\n - master\n\nenv:\n REQWEST_TEST_BODY_FULL: 1\n RUST_BACKTRACE: 1"
},
{
"path": ".gitignore",
"chars": 29,
"preview": "target\nCargo.lock\n*.swp\n.idea"
},
{
"path": "CHANGELOG.md",
"chars": 38721,
"preview": "## v0.13.2\n\n- Fix HTTP/2 and native-tls ALPN feature combinations.\n- Fix HTTP/3 to send h3 ALPN.\n- (wasm) fix `RequestBu"
},
{
"path": "Cargo.toml",
"chars": 8762,
"preview": "[package]\nname = \"reqwest\"\nversion = \"0.13.2\"\ndescription = \"higher level HTTP client library\"\nkeywords = [\"http\", \"requ"
},
{
"path": "LICENSE-APACHE",
"chars": 10833,
"preview": " Apache License\n Version 2.0, January 2004\n http"
},
{
"path": "LICENSE-MIT",
"chars": 1063,
"preview": "Copyright (c) 2016-2026 Sean McArthur\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
},
{
"path": "README.md",
"chars": 2456,
"preview": "# reqwest\n\n[](https://crates.io/crates/reqwest)\n[![Documentatio"
},
{
"path": "examples/blocking.rs",
"chars": 882,
"preview": "//! `cargo run --example blocking --features=blocking`\n#![deny(warnings)]\n\nfn main() -> Result<(), Box<dyn std::error::E"
},
{
"path": "examples/connect_via_lower_priority_tokio_runtime.rs",
"chars": 10015,
"preview": "#![deny(warnings)]\n// This example demonstrates how to delegate the connect calls, which contain TLS handshakes,\n// to a"
},
{
"path": "examples/form.rs",
"chars": 843,
"preview": "// Short example of a POST request with form data.\n//\n// This is using the `tokio` runtime. You'll need the following de"
},
{
"path": "examples/h3_simple.rs",
"chars": 1341,
"preview": "#![deny(warnings)]\n\n// This is using the `tokio` runtime. You'll need the following dependency:\n//\n// `tokio = { version"
},
{
"path": "examples/json_dynamic.rs",
"chars": 1208,
"preview": "//! This example illustrates the way to send and receive arbitrary JSON.\n//!\n//! This is useful for some ad-hoc experime"
},
{
"path": "examples/json_typed.rs",
"chars": 1269,
"preview": "//! This example illustrates the way to send and receive statically typed JSON.\n//!\n//! In contrast to the arbitrary JSO"
},
{
"path": "examples/simple.rs",
"chars": 1269,
"preview": "#![deny(warnings)]\n\n// This is using the `tokio` runtime. You'll need the following dependency:\n//\n// `tokio = { version"
},
{
"path": "examples/tor_socks.rs",
"chars": 832,
"preview": "#![deny(warnings)]\n\n// This is using the `tokio` runtime. You'll need the following dependency:\n//\n// `tokio = { version"
},
{
"path": "examples/wasm_github_fetch/.gitignore",
"chars": 41,
"preview": "node_modules\npkg\ntarget\nCargo.lock\n*.swp\n"
},
{
"path": "examples/wasm_github_fetch/Cargo.toml",
"chars": 510,
"preview": "[package]\nname = \"wasm\"\nversion = \"0.1.0\"\nauthors = [\"John Gallagher <john.willis.gallagher@gmail.com>\"]\nedition = \"2021"
},
{
"path": "examples/wasm_github_fetch/README.md",
"chars": 406,
"preview": "## Example usage of Reqwest from WASM\n\nInstall wasm-pack with\n\n npm install\n\nThen you can build the example locally w"
},
{
"path": "examples/wasm_github_fetch/index.js",
"chars": 394,
"preview": "const rust = import('./pkg');\n\nrust\n .then(m => {\n return m.run().then((data) => {\n console.log(dat"
},
{
"path": "examples/wasm_github_fetch/osv-scanner.toml",
"chars": 53,
"preview": "[[PackageOverrides]]\necosystem = \"npm\"\nignore = true\n"
},
{
"path": "examples/wasm_github_fetch/package.json",
"chars": 351,
"preview": "{\n \"scripts\": {\n \"build\": \"webpack\",\n \"serve\": \"webpack-dev-server\"\n },\n \"devDependencies\": {\n "
},
{
"path": "examples/wasm_github_fetch/src/lib.rs",
"chars": 1312,
"preview": "use serde::{Deserialize, Serialize};\nuse wasm_bindgen::prelude::*;\n\n// NOTE: This test is a clone of https://github.com/"
},
{
"path": "examples/wasm_github_fetch/webpack.config.js",
"chars": 790,
"preview": "const path = require('path');\nconst HtmlWebpackPlugin = require('html-webpack-plugin');\nconst webpack = require('webpack"
},
{
"path": "src/async_impl/body.rs",
"chars": 12631,
"preview": "use std::fmt;\nuse std::future::Future;\nuse std::pin::Pin;\nuse std::task::{ready, Context, Poll};\nuse std::time::Duration"
},
{
"path": "src/async_impl/client.rs",
"chars": 113856,
"preview": "#[cfg(any(feature = \"__native-tls\", feature = \"__rustls\",))]\nuse std::any::Any;\nuse std::future::Future;\nuse std::net::I"
},
{
"path": "src/async_impl/h3_client/connect.rs",
"chars": 4928,
"preview": "use crate::async_impl::h3_client::dns::resolve;\nuse crate::dns::DynResolver;\nuse crate::error::BoxError;\nuse bytes::Byte"
},
{
"path": "src/async_impl/h3_client/dns.rs",
"chars": 1279,
"preview": "use core::task;\nuse hyper_util::client::legacy::connect::dns::Name;\nuse std::future::Future;\nuse std::net::SocketAddr;\nu"
},
{
"path": "src/async_impl/h3_client/mod.rs",
"chars": 3554,
"preview": "#![cfg(feature = \"http3\")]\n\npub(crate) mod connect;\npub(crate) mod dns;\nmod pool;\n\nuse crate::async_impl::body::Response"
},
{
"path": "src/async_impl/h3_client/pool.rs",
"chars": 12257,
"preview": "use bytes::Bytes;\nuse std::collections::HashMap;\nuse std::future;\nuse std::pin::Pin;\nuse std::sync::mpsc::{Receiver, Try"
},
{
"path": "src/async_impl/mod.rs",
"chars": 340,
"preview": "pub use self::body::Body;\npub use self::client::{Client, ClientBuilder};\npub use self::request::{Request, RequestBuilder"
},
{
"path": "src/async_impl/multipart.rs",
"chars": 23518,
"preview": "//! multipart/form-data\nuse std::borrow::Cow;\nuse std::fmt;\nuse std::pin::Pin;\n\n#[cfg(feature = \"stream\")]\nuse std::io;\n"
},
{
"path": "src/async_impl/request.rs",
"chars": 34681,
"preview": "use std::convert::TryFrom;\nuse std::fmt;\nuse std::future::Future;\nuse std::time::Duration;\n\n#[cfg(any(feature = \"query\","
},
{
"path": "src/async_impl/response.rs",
"chars": 15482,
"preview": "use std::fmt;\nuse std::net::SocketAddr;\nuse std::pin::Pin;\nuse std::time::Duration;\n\nuse bytes::Bytes;\nuse http_body_uti"
},
{
"path": "src/async_impl/upgrade.rs",
"chars": 2018,
"preview": "use std::pin::Pin;\nuse std::task::{self, Poll};\nuse std::{fmt, io};\n\nuse hyper_util::rt::TokioIo;\nuse tokio::io::{AsyncR"
},
{
"path": "src/blocking/body.rs",
"chars": 11009,
"preview": "use std::fmt;\nuse std::fs::File;\nuse std::future::Future;\n#[cfg(feature = \"multipart\")]\nuse std::io::Cursor;\nuse std::io"
},
{
"path": "src/blocking/client.rs",
"chars": 55079,
"preview": "#[cfg(any(feature = \"__native-tls\", feature = \"__rustls\",))]\nuse std::any::Any;\nuse std::convert::TryInto;\nuse std::fmt;"
},
{
"path": "src/blocking/mod.rs",
"chars": 3545,
"preview": "//! A blocking Client API.\n//!\n//! The blocking `Client` will block the current thread to execute, instead\n//! of return"
},
{
"path": "src/blocking/multipart.rs",
"chars": 15146,
"preview": "//! multipart/form-data\n//!\n//! To send a `multipart/form-data` body, a [`Form`] is built up, adding\n//! fields or custo"
},
{
"path": "src/blocking/request.rs",
"chars": 34575,
"preview": "use std::convert::TryFrom;\nuse std::fmt;\nuse std::time::Duration;\n\nuse http::{request::Parts, Request as HttpRequest, Ve"
},
{
"path": "src/blocking/response.rs",
"chars": 14237,
"preview": "use std::fmt;\nuse std::io::{self, Read};\nuse std::mem;\nuse std::net::SocketAddr;\nuse std::pin::Pin;\nuse std::time::Durat"
},
{
"path": "src/blocking/wait.rs",
"chars": 2128,
"preview": "use std::future::Future;\nuse std::sync::Arc;\nuse std::task::{Context, Poll, Wake, Waker};\nuse std::thread::{self, Thread"
},
{
"path": "src/config.rs",
"chars": 3815,
"preview": "//! The `config` module provides a generic mechanism for loading and managing\n//! request-scoped configuration.\n//!\n//! "
},
{
"path": "src/connect.rs",
"chars": 70040,
"preview": "#[cfg(feature = \"__tls\")]\nuse http::header::HeaderValue;\n#[cfg(feature = \"__tls\")]\nuse http::uri::Scheme;\nuse http::Uri;"
},
{
"path": "src/cookie.rs",
"chars": 9048,
"preview": "//! HTTP Cookies\n\nuse crate::header::{HeaderValue, SET_COOKIE};\nuse bytes::Bytes;\nuse std::convert::TryInto;\nuse std::fm"
},
{
"path": "src/dns/gai.rs",
"chars": 769,
"preview": "use hyper_util::client::legacy::connect::dns::GaiResolver as HyperGaiResolver;\nuse tower_service::Service;\n\nuse crate::d"
},
{
"path": "src/dns/hickory.rs",
"chars": 2270,
"preview": "//! DNS resolution via the [hickory-resolver](https://github.com/hickory-dns/hickory-dns) crate\n\nuse hickory_resolver::{"
},
{
"path": "src/dns/mod.rs",
"chars": 284,
"preview": "//! DNS resolution\n\npub use resolve::{Addrs, Name, Resolve, Resolving};\npub(crate) use resolve::{DnsResolverWithOverride"
},
{
"path": "src/dns/resolve.rs",
"chars": 5370,
"preview": "use hyper_util::client::legacy::connect::dns::Name as HyperName;\nuse tower_service::Service;\n\nuse std::collections::Hash"
},
{
"path": "src/error.rs",
"chars": 12871,
"preview": "#![cfg_attr(target_arch = \"wasm32\", allow(unused))]\nuse std::error::Error as StdError;\nuse std::fmt;\nuse std::io;\n\nuse c"
},
{
"path": "src/into_url.rs",
"chars": 2880,
"preview": "use url::Url;\n\n/// A trait to try to convert some type into a `Url`.\n///\n/// This trait is \"sealed\", such that only type"
},
{
"path": "src/lib.rs",
"chars": 12559,
"preview": "#![deny(missing_docs)]\n#![deny(missing_debug_implementations)]\n#![cfg_attr(docsrs, feature(doc_cfg))]\n#![cfg_attr(not(te"
},
{
"path": "src/proxy.rs",
"chars": 31142,
"preview": "use std::error::Error;\nuse std::fmt;\nuse std::sync::Arc;\n\nuse http::uri::Scheme;\nuse http::{header::HeaderValue, HeaderM"
},
{
"path": "src/redirect.rs",
"chars": 13191,
"preview": "//! Redirect Handling\n//!\n//! By default, a `Client` will automatically handle HTTP redirects, having a\n//! maximum redi"
},
{
"path": "src/response.rs",
"chars": 1058,
"preview": "use url::Url;\n\n#[derive(Debug, Clone, PartialEq)]\npub(crate) struct ResponseUrl(pub Url);\n\n/// Extension trait for http:"
},
{
"path": "src/retry.rs",
"chars": 15170,
"preview": "//! Retry requests\n//!\n//! A `Client` has the ability to retry requests, by sending additional copies\n//! to the server "
},
{
"path": "src/tls.rs",
"chars": 29242,
"preview": "//! TLS configuration and types\n//!\n//! A `Client` will use transport layer security (TLS) by default to connect to\n//! "
},
{
"path": "src/util.rs",
"chars": 3790,
"preview": "use crate::header::{Entry, HeaderMap, HeaderValue, OccupiedEntry};\nuse std::fmt;\n\npub fn basic_auth<U, P>(username: U, p"
},
{
"path": "src/wasm/body.rs",
"chars": 9152,
"preview": "#[cfg(feature = \"multipart\")]\nuse super::multipart::Form;\n/// dox\nuse bytes::Bytes;\nuse js_sys::Uint8Array;\nuse std::{bo"
},
{
"path": "src/wasm/client.rs",
"chars": 14124,
"preview": "use http::header::USER_AGENT;\nuse http::{HeaderMap, HeaderValue, Method};\nuse js_sys::Promise;\nuse std::convert::TryInto"
},
{
"path": "src/wasm/mod.rs",
"chars": 2219,
"preview": "use std::convert::TryInto;\nuse std::time::Duration;\n\nuse js_sys::Function;\nuse wasm_bindgen::prelude::{wasm_bindgen, Clo"
},
{
"path": "src/wasm/multipart.rs",
"chars": 11410,
"preview": "//! multipart/form-data\nuse std::borrow::Cow;\nuse std::fmt;\n\nuse http::HeaderMap;\nuse mime_guess::Mime;\nuse web_sys::For"
},
{
"path": "src/wasm/request.rs",
"chars": 19061,
"preview": "use std::convert::TryFrom;\nuse std::fmt;\nuse std::time::Duration;\n\nuse bytes::Bytes;\nuse http::{request::Parts, Method, "
},
{
"path": "src/wasm/response.rs",
"chars": 5827,
"preview": "use std::fmt;\n\nuse bytes::Bytes;\nuse http::{HeaderMap, StatusCode};\nuse js_sys::Uint8Array;\nuse url::Url;\n\nuse crate::wa"
},
{
"path": "tests/badssl.rs",
"chars": 2010,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(not(feature = \"rustls-no-provider\"))]\n\n#[cfg(all(feature = \"__tls\"))]\n#[toki"
},
{
"path": "tests/blocking.rs",
"chars": 12283,
"preview": "mod support;\n\nuse http::header::{CONTENT_LENGTH, CONTENT_TYPE, TRANSFER_ENCODING};\nuse http_body_util::BodyExt;\n#[cfg(fe"
},
{
"path": "tests/brotli.rs",
"chars": 11334,
"preview": "mod support;\nuse std::io::Read;\nuse support::server;\nuse tokio::io::AsyncWriteExt;\n\n#[tokio::test]\nasync fn brotli_respo"
},
{
"path": "tests/ci.rs",
"chars": 386,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(not(feature = \"rustls-no-provider\"))]\nmod support;\nuse support::server;\n\n#[t"
},
{
"path": "tests/client.rs",
"chars": 16013,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(not(feature = \"rustls-no-provider\"))]\nmod support;\n\nuse support::server;\n\nus"
},
{
"path": "tests/connector_layers.rs",
"chars": 11235,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(not(feature = \"rustls-no-provider\"))]\nmod support;\n\nuse std::time::Duration;"
},
{
"path": "tests/cookie.rs",
"chars": 6123,
"preview": "mod support;\nuse support::server;\n\n#[tokio::test]\nasync fn cookie_response_accessor() {\n let server = server::http(mo"
},
{
"path": "tests/deflate.rs",
"chars": 11370,
"preview": "mod support;\nuse flate2::write::ZlibEncoder;\nuse flate2::Compression;\nuse std::io::Write;\nuse support::server;\nuse tokio"
},
{
"path": "tests/gzip.rs",
"chars": 11131,
"preview": "mod support;\nuse flate2::write::GzEncoder;\nuse flate2::Compression;\nuse support::server;\n\nuse std::io::Write;\nuse std::t"
},
{
"path": "tests/http3.rs",
"chars": 18087,
"preview": "#![cfg(feature = \"http3\")]\n#![cfg(not(target_arch = \"wasm32\"))]\n\nmod support;\n\nuse http::header::CONTENT_LENGTH;\nuse std"
},
{
"path": "tests/multipart.rs",
"chars": 6419,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\nmod support;\nuse http_body_util::BodyExt;\nuse support::server;\n\n#[tokio::test]\nasyn"
},
{
"path": "tests/not_tcp.rs",
"chars": 1427,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(not(feature = \"rustls-no-provider\"))]\n#![cfg(unix)]\n\nmod support;\n\n#[tokio::"
},
{
"path": "tests/proxy.rs",
"chars": 12914,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(not(feature = \"rustls-no-provider\"))]\nmod support;\nuse support::server;\n\nuse"
},
{
"path": "tests/redirect.rs",
"chars": 16853,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(not(feature = \"rustls-no-provider\"))]\nmod support;\nuse http_body_util::BodyE"
},
{
"path": "tests/retry.rs",
"chars": 4225,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(not(feature = \"rustls-no-provider\"))]\nmod support;\nuse support::server;\n\nuse"
},
{
"path": "tests/support/crl.pem",
"chars": 617,
"preview": "-----BEGIN X509 CRL-----\nMIIBnjCBhwIBATANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJjYRcNMjQwOTI2\nMDA0MjU1WhcNMjQxMDI2MDA0MjU1Wj"
},
{
"path": "tests/support/delay_layer.rs",
"chars": 2798,
"preview": "use std::{\n future::Future,\n pin::Pin,\n task::{Context, Poll},\n time::Duration,\n};\n\nuse pin_project_lite::pi"
},
{
"path": "tests/support/delay_server.rs",
"chars": 4741,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![allow(unused)]\nuse std::convert::Infallible;\nuse std::future::Future;\nuse std::n"
},
{
"path": "tests/support/error.rs",
"chars": 357,
"preview": "use std::error::Error as StdError;\n\npub fn inspect<E>(err: E) -> Vec<String>\nwhere\n E: Into<Box<dyn StdError + Send +"
},
{
"path": "tests/support/mod.rs",
"chars": 298,
"preview": "#![allow(dead_code)]\n\npub mod delay_layer;\npub mod delay_server;\npub mod error;\npub mod not_tcp;\npub mod server;\n\n// TOD"
},
{
"path": "tests/support/not_tcp.rs",
"chars": 4720,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(unix)]\n\nuse std::convert::Infallible;\nuse std::future::Future;\nuse std::sync"
},
{
"path": "tests/support/server.rs",
"chars": 16943,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\nuse std::convert::Infallible;\nuse std::future::Future;\nuse std::net;\nuse std::sync:"
},
{
"path": "tests/timeouts.rs",
"chars": 11930,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(not(feature = \"rustls-no-provider\"))]\nmod support;\nuse support::server;\n\nuse"
},
{
"path": "tests/upgrade.rs",
"chars": 1645,
"preview": "#![cfg(not(target_arch = \"wasm32\"))]\n#![cfg(not(feature = \"rustls-no-provider\"))]\nmod support;\nuse support::server;\nuse "
},
{
"path": "tests/wasm_simple.rs",
"chars": 2131,
"preview": "#![cfg(target_arch = \"wasm32\")]\nuse std::time::Duration;\n\nuse wasm_bindgen::prelude::*;\nuse wasm_bindgen_test::*;\nwasm_b"
},
{
"path": "tests/zstd.rs",
"chars": 19656,
"preview": "mod support;\nuse support::server;\nuse tokio::io::AsyncWriteExt;\n\n#[tokio::test]\nasync fn zstd_response() {\n zstd_case"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the seanmonstar/reqwest GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 93 files (918.0 KB), approximately 227.0k tokens, and a symbol index with 1606 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.