HTTP.FetchOptions (http_fetch v0.21.19)

Copy Markdown View Source

Options processing for HTTP.fetch/2 requests.

HTTP.fetch/2 accepts a flat init keyword list or map, mirroring the browser fetch(input, init) shape. Supported fetch-style options are:

  • method - nonempty ASCII HTTP method token, defaulting to GET. Common methods normalize to their conventional atoms; other binary methods retain their case, and atom methods are uppercased on the wire. DAV methods such as :propfind and :report carry bodies normally. Invalid token bytes reject before network I/O; extension strings are never converted into new atoms.
  • headers - request headers as a list, map, or HTTP.Headers
  • body - request body
  • duplex - request streaming mode; :half or "half" for streaming bodies
  • signal - HTTP.AbortController PID
  • redirect - :follow, :manual, or :error; defaults to :follow

The socket transport also accepts Elixir-specific extensions:

  • telemetry - emit request and stream telemetry; defaults to true. Shared pool/connection counters require the global opt-out in HTTP.Telemetry.

  • decode_body - decode response Content-Encoding; defaults to true. Set false to preserve stored entity bytes for buffered and streamed HTTP/1, HTTP/2, and HTTP/3 responses without changing headers.

  • stream_response - set true to resolve at final response headers and expose an acknowledged body stream, even for small Content-Length bodies. Defaults to false (automatic size/framing policy). HEAD and bodyless statuses remain buffered empty responses. The request timeout still bounds the entire response; callers can observe headers before applying a body deadline.

  • request_mode - :fetch (default) or :proxy; proxy mode retains request entities for all admitted methods, including GET, DELETE, and HEAD

  • content_type - convenience Content-Type value for request bodies

  • timeout - request timeout in milliseconds or :infinity for HTTP/1

  • error_mode - :raw (default) or :structured; structured failures return HTTP.RequestError with conservative pre-send evidence. No automatic retry.

  • read_idle_timeout - positive milliseconds (1..4,294,967,295), or nil to disable (default). Bounds each pending HTTP/1 transport read, including headers; nonempty transport data resets the clock. Consumer acknowledgement backpressure pauses reads and this clock. Writes do not reset it.

  • write_idle_timeout - positive milliseconds (same range), or nil to disable (default). Bounds each at-most-16KiB HTTP/1 transport write; each successful nonempty send starts a fresh write budget. This is transport acceptance, not peer acknowledgement or a partial-syscall progress guarantee. Waiting for an upload source does not consume a write budget. Shorter existing socket_opts[:send_timeout] and overall request limits still apply. Both idle options support ordinary HTTP/1 TCP, OTP TLS and ExSSL, including HTTP/1 reuse. They require http_version: :http1 (the default); automatic/H2/H3 protocols and managed transport_scope are rejected. Timeouts report :read_idle_timeout / :write_idle_timeout (or HTTP.RequestError in structured mode before response headers). Neither changes connection or overall request deadlines or the cleanup completion contract.

  • connect_timeout - connection timeout in milliseconds or :infinity

  • response_stream_idle_timeout - ordinary HTTP/1 response-stream inactivity in positive milliseconds (1..4,294,967,295), or :infinity to disable the network-wait clock. nil (default) retains the global streaming timeout. Consumer acknowledgement waits use the separate ACK policy below. Convenience body readers use the same stream policy. Other protocols and managed transport_scope reject explicit policies.

  • response_stream_ack_timeout - ordinary HTTP/1 response chunk delivery and consumer acknowledgement budget in positive milliseconds (1..4,294,967,295), or :infinity. nil (default) retains the global streaming timeout. This covers a buffered chunk awaiting a reader and a delivered chunk awaiting acknowledgement. It does not change network idle, overall request deadlines, cancellation or reader-death cleanup. Other protocols and managed transport_scope reject explicit policies.

  • transport_scope - opaque HTTP.ManagedTransport generation selecting private reusable HTTP/1 or HTTP/2 transports. Requires raw streamed responses, manual/error redirects, and the origin/policy frozen by open/1.

  • connect_address - caller-validated literal IPv4/IPv6 tuple to dial instead of resolving the URL hostname. Keeps original HTTP authority, TLS SNI and certificate hostname verification. No DNS/address fallback or request replay. Requires redirect: :manual or :error; validate every permitted redirect hop independently and provide that hop's pin. HTTP/3, Unix sockets and proxies are unsupported. Pools isolate each pin from DNS and other targets. Cancellation and request/connect deadlines cover establishment. Conflicting TLS SNI rejects before I/O; native verification and trust defaults remain. With :ex_ssl, a literal-IP HTTPS URL must match the pin, since a distinct original IP verification identity is currently unsupported.

  • http_version - protocol selection, one of :http1, :http2, :http3, :h2c, or :auto; defaults to :http1

  • prefer_ipv6 - Prefer IPv6 with IPv4 fallback only during TCP establishment. Explicit connect_address pins and :inet/:inet6 socket options remain strict. For a proxy route this policy selects the proxy endpoint address family.

  • response_header_limits - Request-local HTTP/1 and CONNECT budgets; see HTTP.ResponseHeaderLimits. Also applies to informational and redirect heads.

  • tls_backend - TLS implementation, :ssl or :ex_ssl; defaults to the shared :http_core, :tls_backend configuration

  • ssl - TLS options passed to the selected TLS backend

  • socket_opts - socket options passed to the underlying transport

  • unix_socket - Unix Domain Socket path

  • http1_reuse - opt in to HTTP/1 keep-alive; requires http_version: :http1. Only fully consumed, self-delimited responses are reusable. Failed or cancelled requests are closed, and requests are never retried on stale peers.

  • http1_scope - optional atom or string separating caller routes sharing an origin.

  • http1_pool_size - retained idle sockets per route/policy, 1..16 (default 2).

  • http1_idle_timeout - idle retention in milliseconds, 1..60,000 (default 30,000). All callers share a maximum of 256 idle sockets. TLS identities, socket options, isolation scope and route policies are part of the reuse key; opaque callbacks disable reuse. HTTP/1 reuse defaults to false.

  • proxy - explicit proxy {:http, host, port, opts} or {:https, host, port, opts}. Options are headers: [{"Proxy-Authorization", value}] and a finite positive timeout. HTTP/1 cleartext uses absolute-form forwarding; HTTPS uses CONNECT and then origin TLS/ALPN. H2 over HTTPS and ExSSL IP-origin tunnels are supported; H2c, HTTP/3 and Unix socket proxy routes are rejected explicitly. Environment/NO_PROXY selection belongs to the caller. HTTPS proxies support HTTP origins only, using TLS to the proxy and absolute-form HTTP/1 forwarding. ssl and tls_backend apply to the proxy; its hostname is the certificate/SNI identity. TLS-over-TLS origins are rejected. Proxy scheme, endpoint, credentials, and TLS policy isolate pools.

  • http2_profile - versioned HTTP/2 wire profile (only used by HTTP/2)

  • http2_reuse - whether an HTTP/2 connection may be reused; defaults to true

  • http3_profile - QUIC wire profile; defaults to :ordered

  • http3_reuse - whether an HTTP/3 connection may be reused; defaults to true

  • http2_scope - non-sensitive caller isolation scope

  • http2_priority - per-request HTTP/2 priority metadata

Summary

Functions

Extracts body from options.

Extracts content type from options.

Extracts the request body streaming mode from options.

Extracts headers from options.

Extracts the HTTP method from options.

Creates a new FetchOptions struct from a flat map, keyword list, or existing FetchOptions struct.

Converts fetch init options to the internal socket transport option list.

Types

http_version()

@type http_version() :: :http1 | :http2 | :http3 | :h2c | :auto

redirect()

@type redirect() :: :follow | :manual | :error

t()

@type t() :: %HTTP.FetchOptions{
  body: any(),
  connect_address: :inet.ip_address() | nil,
  connect_timeout: timeout() | nil,
  content_type: String.t() | nil,
  decode_body: boolean(),
  duplex: :half | nil,
  error_mode: :raw | :structured,
  headers: HTTP.Headers.t(),
  http1_idle_timeout: pos_integer(),
  http1_pool_size: pos_integer(),
  http1_reuse: boolean(),
  http1_scope: atom() | String.t() | nil,
  http2_priority: map() | keyword() | nil,
  http2_profile: atom() | String.t() | map() | nil,
  http2_reuse: boolean(),
  http2_scope: atom() | String.t() | nil,
  http3_profile: atom() | map() | nil,
  http3_reuse: boolean(),
  http_version: http_version(),
  method: HTTP.Request.method(),
  prefer_ipv6: boolean(),
  proxy: {:http | :https, String.t(), :inet.port_number(), keyword()} | nil,
  read_idle_timeout: pos_integer() | nil,
  redirect: redirect(),
  request_mode: HTTP.Request.request_mode(),
  response_header_limits: map() | nil,
  response_stream_ack_timeout: pos_integer() | :infinity | nil,
  response_stream_idle_timeout: pos_integer() | :infinity | nil,
  signal: any() | nil,
  socket_opts: list() | nil,
  ssl: list() | nil,
  stream_response: boolean(),
  telemetry: boolean(),
  timeout: timeout() | nil,
  tls_backend: tls_backend(),
  transport_scope: term(),
  unix_socket: String.t() | nil,
  write_idle_timeout: pos_integer() | nil
}

tls_backend()

@type tls_backend() :: term()

Functions

get_body(fetch_options)

@spec get_body(t()) :: any()

Extracts body from options.

get_content_type(fetch_options)

@spec get_content_type(t()) :: String.t() | nil

Extracts content type from options.

get_duplex(fetch_options)

@spec get_duplex(t()) :: :half | nil

Extracts the request body streaming mode from options.

get_headers(fetch_options)

@spec get_headers(t()) :: HTTP.Headers.t()

Extracts headers from options.

get_method(fetch_options)

@spec get_method(t()) :: HTTP.Request.method()

Extracts the HTTP method from options.

new(options)

@spec new(map() | keyword() | t()) :: t()

Creates a new FetchOptions struct from a flat map, keyword list, or existing FetchOptions struct.

to_transport_options(options)

@spec to_transport_options(t()) :: keyword()

Converts fetch init options to the internal socket transport option list.