-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).