-module(aws@internal@http_send).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/aws/internal/http_send.gleam").
-export([lift_to_streaming/1, default_send/1, with_timeout/1, imds_send/1]).
-export_type([http_error/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" HTTP send abstraction used by all HTTP-based credential providers (and\n"
" later by the request pipeline itself).\n"
"\n"
" Every provider that talks to AWS endpoints takes a `Send` value so tests\n"
" can drive it with a stub. Production code calls `default_send`, which\n"
" dispatches via `gleam_httpc` (Erlang's `httpc`).\n"
"\n"
" Errors are normalised to a single `HttpError` sum type so the providers\n"
" can pattern-match on category without depending on `httpc`'s shape\n"
" directly.\n"
).
-type http_error() :: {connect_failed, binary()} |
timeout |
{invalid_body, binary()} |
{other, binary()}.
-file("src/aws/internal/http_send.gleam", 49).
?DOC(
" Lift a buffered `Send` into a `StreamingSend` by wrapping its\n"
" response body as a `Buffered` `StreamingBody`. Use this when a\n"
" test wants to stub the streaming transport with a buffered fake,\n"
" or when a caller has only a buffered sender available and wants\n"
" it to satisfy a `StreamingSend` slot. Production code should\n"
" take `http_streaming.default_send` for genuine chunked transfer.\n"
).
-spec lift_to_streaming(
fun((gleam@http@request:request(bitstring())) -> {ok,
gleam@http@response:response(bitstring())} |
{error, http_error()})
) -> fun((gleam@http@request:request(bitstring())) -> {ok,
gleam@http@response:response(aws@streaming:streaming_body())} |
{error, http_error()}).
lift_to_streaming(Send) ->
fun(Req) -> case Send(Req) of
{ok, Resp} ->
{ok,
{response,
erlang:element(2, Resp),
erlang:element(3, Resp),
aws@streaming:from_bit_array(erlang:element(4, Resp))}};
{error, E} ->
{error, E}
end end.
-file("src/aws/internal/http_send.gleam", 101).
-spec default_config() -> gleam@httpc:configuration().
default_config() ->
_pipe = gleam@httpc:configure(),
gleam@httpc:timeout(_pipe, 30 * 1000).
-file("src/aws/internal/http_send.gleam", 105).
-spec do_send(
gleam@httpc:configuration(),
gleam@http@request:request(bitstring())
) -> {ok, gleam@http@response:response(bitstring())} | {error, http_error()}.
do_send(Config, Req) ->
case gleam@httpc:dispatch_bits(Config, Req) of
{ok, Response} ->
{ok, Response};
{error, {failed_to_connect, _, _}} ->
{error, {connect_failed, <<"could not connect to host"/utf8>>}};
{error, response_timeout} ->
{error, timeout};
{error, invalid_utf8_response} ->
{error,
{invalid_body, <<"response body was not valid UTF-8"/utf8>>}}
end.
-file("src/aws/internal/http_send.gleam", 77).
?DOC(" Production sender — 30 second total timeout, TLS verification on.\n").
-spec default_send(gleam@http@request:request(bitstring())) -> {ok,
gleam@http@response:response(bitstring())} |
{error, http_error()}.
default_send(Req) ->
do_send(default_config(), Req).
-file("src/aws/internal/http_send.gleam", 88).
?DOC(
" Build a `Send` with a custom total timeout. Use this for endpoints that\n"
" need either fast-fail behaviour (IMDS) or extra patience (large object\n"
" downloads). TLS verification and redirect-following match\n"
" `default_send`'s defaults; if you need to tweak those, drop down to\n"
" `gleam_httpc` directly.\n"
).
-spec with_timeout(integer()) -> fun((gleam@http@request:request(bitstring())) -> {ok,
gleam@http@response:response(bitstring())} |
{error, http_error()}).
with_timeout(Seconds) ->
Config = begin
_pipe = gleam@httpc:configure(),
gleam@httpc:timeout(_pipe, Seconds * 1000)
end,
fun(Req) -> do_send(Config, Req) end.
-file("src/aws/internal/http_send.gleam", 95).
?DOC(
" IMDS-tuned sender. Equivalent to `with_timeout(seconds: imds_timeout_seconds)`,\n"
" exported as a constant so call sites read meaningfully.\n"
).
-spec imds_send(gleam@http@request:request(bitstring())) -> {ok,
gleam@http@response:response(bitstring())} |
{error, http_error()}.
imds_send(Req) ->
(with_timeout(2))(Req).