Dowser. Client. HTTP
(Dowser.Client v0.3.0)
View Source
The HTTP transport: OTP's :httpc, and nothing else.
Given a method, an absolute URL, headers and an already-encoded body, it
performs the request and returns a normalized Dowser.Client.Response (or an
error). It never encodes or decodes bodies — that is the JSON/codec layer's
job.
:httpc ships with OTP, so dowser_client has no HTTP dependency at all.
Every request is HTTP/1.1 with keep-alive, sent through a dedicated
:httpc profile (see Dowser.Client.HTTP.Profile) rather than the shared
:default one.
Options
:http_opts, merged global → context → request, is passed here:
:connect_timeout— TCP connect timeout in milliseconds; default2_000.:timeout— whole-request timeout in milliseconds; default30_000.:ssl— TLS options for anhttps://endpoint; seeDowser.Client.HTTP.SSL. Verification is on by default.:profile/:profile_opts— the:httpcprofile to send through and its:httpc.set_options/2settings (max_sessions,max_keep_alive_length,keep_alive_timeout,pipeline_timeout,cookies, ...); seeDowser.Client.HTTP.Profile.:autoredirect,:proxy_auth,:relaxed— passed to:httpcasHTTPOptions.:full_result,:headers_as_is,:socket_opts,:ipv6_host_with_brackets— passed to:httpcasOptions.:http_options/:options— escape hatches merged last into:httpc's two option lists, for anything not named above.
An unrecognized key is an error ({:unknown_http_opts, keys}) rather than a
silently ignored setting.
version: ~c"HTTP/1.1" and body_format: :binary are always set: :httpc
never speaks HTTP/2, and the response body always comes back as a binary.
GET with a body
:httpc's request tuple has no body slot for :get, :head or :trace.
Since search backends do expect a body on GET (Elasticsearch's
GET /_search), a :get carrying a non-empty body is sent as a POST —
which every such backend accepts on the same path — and logged at debug
level. A body on :head/:trace is meaningless, so it returns
{:error, {:unsupported_body, method}} rather than being dropped silently.
Testing
Dowser.Client.HTTP.Stub.stub/1 intercepts requests in the calling process,
so tests exercise the whole pipeline without a server. Checked first on every
request, which costs one process-dictionary read in production.
Summary
Functions
Performs method against url, returning {:ok, %Dowser.Client.Response{}}
for any completed exchange (whatever the status), or {:error, reason} when
the transport fails.
Types
Functions
@spec request(method(), url(), headers(), body(), opts()) :: {:ok, Dowser.Client.Response.t()} | {:error, term()}
Performs method against url, returning {:ok, %Dowser.Client.Response{}}
for any completed exchange (whatever the status), or {:error, reason} when
the transport fails.
reason is :httpc's own term (:timeout, a {:failed_connect, _} tuple,
...) or one of this layer's: {:unsupported_body, method},
{:unknown_http_opts, keys}, {:no_cacerts, _}, {:profile_down, _}.
Dowser.Client wraps it in a Dowser.Client.HTTP.Error.