aws/internal/http_send

HTTP send abstraction used by all HTTP-based credential providers (and later by the request pipeline itself).

Every provider that talks to AWS endpoints takes a Send value so tests can drive it with a stub. Production code calls default_send, which dispatches via gleam_httpc (Erlang’s httpc).

Errors are normalised to a single HttpError sum type so the providers can pattern-match on category without depending on httpc’s shape directly.

Types

pub type HttpError {
  ConnectFailed(reason: String)
  Timeout
  InvalidBody(reason: String)
  Other(reason: String)
}

Constructors

  • ConnectFailed(reason: String)

    Could not reach the host (DNS, TCP, TLS).

  • Timeout

    Connection succeeded but no response came back in time.

  • InvalidBody(reason: String)

    Response body was not the expected encoding.

  • Other(reason: String)

    Anything else the transport surfaced.

A function that sends a request and returns a response (or an HTTP error). The body is BitArray so providers can deal in raw bytes without forcing UTF-8 decoding decisions on the transport.

pub type Send =
  fn(request.Request(BitArray)) -> Result(
    response.Response(BitArray),
    HttpError,
  )

Streaming variant of Send. The response body is a StreamingBody, which v1 carries as a single buffered chunk and the eventual chunked transport delivers as a true byte stream. Object-streaming GETs (S3 GetObject, MediaLive, etc.) take this shape so call sites can migrate today and pick up the real streaming path later without an API change.

pub type StreamingSend =
  fn(request.Request(BitArray)) -> Result(
    response.Response(streaming.StreamingBody),
    HttpError,
  )

Values

pub fn default_send(
  req: request.Request(BitArray),
) -> Result(response.Response(BitArray), HttpError)

Production sender — 30 second total timeout, TLS verification on.

pub const default_timeout_seconds: Int

Default total-request timeout for default_send. 30 seconds is the gleam_httpc default and a reasonable upper bound for control-plane and list operations. Object-streaming GETs that may take longer want a dedicated, more generous Send.

pub fn imds_send(
  req: request.Request(BitArray),
) -> Result(response.Response(BitArray), HttpError)

IMDS-tuned sender. Equivalent to with_timeout(seconds: imds_timeout_seconds), exported as a constant so call sites read meaningfully.

pub const imds_timeout_seconds: Int

IMDS gets a much shorter total timeout because its first call goes to a link-local address that doesn’t resolve at all on a non-EC2 host. Without this, the TCP retransmit window can stall the whole credential chain for tens of seconds — enough to trip the credentials cache actor’s 5-second call timeout.

pub fn lift_to_streaming(
  send: fn(request.Request(BitArray)) -> Result(
    response.Response(BitArray),
    HttpError,
  ),
) -> fn(request.Request(BitArray)) -> Result(
  response.Response(streaming.StreamingBody),
  HttpError,
)

Lift a buffered Send into a StreamingSend by wrapping its response body as a Buffered StreamingBody. Use this when a test wants to stub the streaming transport with a buffered fake, or when a caller has only a buffered sender available and wants it to satisfy a StreamingSend slot. Production code should take http_streaming.default_send for genuine chunked transfer.

pub fn with_timeout(
  seconds seconds: Int,
) -> fn(request.Request(BitArray)) -> Result(
  response.Response(BitArray),
  HttpError,
)

Build a Send with a custom total timeout. Use this for endpoints that need either fast-fail behaviour (IMDS) or extra patience (large object downloads). TLS verification and redirect-following match default_send’s defaults; if you need to tweak those, drop down to gleam_httpc directly.

Search Document