-module(aws@internal@http_streaming). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/aws/internal/http_streaming.gleam"). -export([default_send/1, default_send_http2/1, with_timeout_and_tls/2, with_timeout_tls_http2/2]). -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( " Streaming HTTP send for the SDK runtime. Sits between the\n" " generated service code and the Erlang FFI in `aws_streaming_ffi`:\n" " translates a Gleam `Request(BitArray)` into the parameters\n" " `httpc:request/4` expects, dispatches via the streaming FFI,\n" " then wraps the response back into a `Response(StreamingBody)`\n" " so call sites read identically to the buffered transport.\n" "\n" " This is the foundational piece for `S3.GetObject` on multi-GB\n" " objects, event-stream operations (Transcribe, Kinesis), and any\n" " future S3 transfer manager — none of those can pre-buffer the\n" " full response into memory.\n" ). -file("src/aws/internal/http_streaming.gleam", 125). -spec translate_error(gleam@erlang@atom:atom_()) -> aws@internal@http_send:http_error(). translate_error(Reason) -> case erlang:atom_to_binary(Reason) of <<"failed_to_connect"/utf8>> -> {connect_failed, <<"could not connect to host"/utf8>>}; <<"response_timeout"/utf8>> -> timeout; <<"timeout"/utf8>> -> timeout; <<"invalid_utf8_response"/utf8>> -> {invalid_body, <<"response body was not valid UTF-8"/utf8>>}; Other -> {other, Other} end. -file("src/aws/internal/http_streaming.gleam", 118). -spec to_string_or_empty(bitstring()) -> binary(). to_string_or_empty(B) -> case gleam@bit_array:to_string(B) of {ok, S} -> S; {error, _} -> <<""/utf8>> end. -file("src/aws/internal/http_streaming.gleam", 110). -spec list_decode_headers(list({bitstring(), bitstring()})) -> list({binary(), binary()}). list_decode_headers(Raw) -> gleam@list:map( Raw, fun(Pair) -> {to_string_or_empty(erlang:element(1, Pair)), to_string_or_empty(erlang:element(2, Pair))} end ). -file("src/aws/internal/http_streaming.gleam", 78). -spec send_with( gleam@http@request:request(bitstring()), integer(), boolean(), boolean() ) -> {ok, gleam@http@response:response(aws@streaming:streaming_body())} | {error, aws@internal@http_send:http_error()}. send_with(Req, Timeout_ms, Verify_tls, Http2) -> Url = begin _pipe = Req, _pipe@1 = gleam@http@request:to_uri(_pipe), gleam@uri:to_string(_pipe@1) end, case aws_streaming_ffi:streaming_send( erlang:element(2, Req), Url, erlang:element(3, Req), erlang:element(4, Req), Timeout_ms, Verify_tls, Http2 ) of {ok, {Status, Headers, Chunks}} -> {ok, {response, Status, list_decode_headers(Headers), aws@streaming:from_chunks(Chunks)}}; {error, Reason} -> {error, translate_error(Reason)} end. -file("src/aws/internal/http_streaming.gleam", 31). ?DOC( " Default streaming sender. Same TLS / timeout defaults as\n" " `http_send.default_send`; the response body is a `StreamingBody`\n" " carrying chunks as they arrived on the wire. Pass this as\n" " `ClientConfig.streaming_http_send` for the SDK runtime, or call\n" " it directly when wiring custom callers.\n" ). -spec default_send(gleam@http@request:request(bitstring())) -> {ok, gleam@http@response:response(aws@streaming:streaming_body())} | {error, aws@internal@http_send:http_error()}. default_send(Req) -> send_with(Req, 30 * 1000, true, false). -file("src/aws/internal/http_streaming.gleam", 47). ?DOC( " HTTP/2 variant of `default_send`. Adds `{http_version, \"HTTP/2\"}`\n" " to the httpc option list; servers that don't speak HTTP/2 negotiate\n" " down to HTTP/1.1 via ALPN. Use this for endpoints known to benefit:\n" " S3 multipart uploads, Bedrock streaming responses, Transcribe.\n" " Caller-facing knob lives at `runtime.with_http2`.\n" ). -spec default_send_http2(gleam@http@request:request(bitstring())) -> {ok, gleam@http@response:response(aws@streaming:streaming_body())} | {error, aws@internal@http_send:http_error()}. default_send_http2(Req) -> send_with(Req, 30 * 1000, true, true). -file("src/aws/internal/http_streaming.gleam", 62). ?DOC( " Send a `StreamingSend` configurable on timeout and TLS verification.\n" " Use this for live-tested object-streaming GETs that need either\n" " fast-fail (IMDS-style 2s timeouts) or extra patience (multi-GB\n" " downloads).\n" ). -spec with_timeout_and_tls(integer(), boolean()) -> fun((gleam@http@request:request(bitstring())) -> {ok, gleam@http@response:response(aws@streaming:streaming_body())} | {error, aws@internal@http_send:http_error()}). with_timeout_and_tls(Timeout_ms, Verify_tls) -> fun(Req) -> send_with(Req, Timeout_ms, Verify_tls, false) end. -file("src/aws/internal/http_streaming.gleam", 71). ?DOC( " HTTP/2 + custom timeout / TLS builder. Same as `with_timeout_and_tls`\n" " but adds the HTTP/2 option to the httpc call.\n" ). -spec with_timeout_tls_http2(integer(), boolean()) -> fun((gleam@http@request:request(bitstring())) -> {ok, gleam@http@response:response(aws@streaming:streaming_body())} | {error, aws@internal@http_send:http_error()}). with_timeout_tls_http2(Timeout_ms, Verify_tls) -> fun(Req) -> send_with(Req, Timeout_ms, Verify_tls, true) end.