aws/internal/codec/rest

Shared runtime helpers for the rest-protocol emitters (restJson1, restXml). Holds the URI / query / header glue that generated build_*_request functions call into for each @httpLabel, @httpQuery, @httpHeader member.

Types

Checksum algorithm picked by the aws.protocols#httpChecksum trait. Each variant maps to one of the AWS x-amz-checksum-* request headers; the codegen / runtime middleware writes the base64-encoded digest of the request body into that header before signing.

pub type ChecksumAlgorithm {
  ChecksumSha256
  ChecksumSha1
  ChecksumCrc32
  ChecksumCrc32C
}

Constructors

  • ChecksumSha256
  • ChecksumSha1
  • ChecksumCrc32
  • ChecksumCrc32C

Values

pub fn add_prefix_headers(
  headers: dict.Dict(String, String),
  prefix: String,
  entries: dict.Dict(String, String),
) -> dict.Dict(String, String)

Iterate @httpPrefixHeaders map members: for each entry, emit a header <prefix><key>: <value>.

pub fn add_query(
  existing: String,
  name: String,
  value: String,
) -> String

Append a query parameter pair. Returns the resulting query string (without the leading ?); call sites prepend it themselves.

pub fn add_query_params(
  query: String,
  entries: dict.Dict(String, String),
) -> String

Iterate @httpQueryParams map members (Map<String, String>).

pub fn add_query_params_list(
  query: String,
  entries: dict.Dict(String, List(String)),
) -> String

Iterate @httpQueryParams map members (Map<String, List>). Each list value emits one query param per element.

pub fn append_content_encoding(
  headers: dict.Dict(String, String),
  encoding: String,
) -> dict.Dict(String, String)

Append a @requestCompression encoding to the Content-Encoding header. Existing encodings (e.g. caller-set Content-Encoding: custom) are preserved with the new value appended after a comma: custom + gzipcustom, gzip.

pub fn bool_header(
  headers: dict.Dict(String, String),
  name: String,
) -> option.Option(Bool)
pub fn bool_to_query(b: Bool) -> String

Bool → query value: “true” / “false”.

pub fn build_path(uri_path: String, query: String) -> String

Build the full path: substitute labels, then append query (with ?) if non-empty. Merge a path that may already carry a static query string (from the @http URI template, e.g. /Foo?bar=baz) with the dynamically built query string from @httpQuery members. Either or both can be empty. The static-query side wins on key order; dynamic params are appended.

pub fn checksum_algorithm_from_wire(
  wire: String,
) -> ChecksumAlgorithm

Translate a Smithy ChecksumAlgorithm enum’s wire value (e.g. "SHA256", "CRC32C") to the runtime ChecksumAlgorithm variant, falling back to ChecksumSha256 when the wire value doesn’t match a supported algorithm. Used by the codegen’s algorithm-member dispatch for aws.protocols#httpChecksum so generated request builders can read the caller’s typed enum choice without needing a per-service jump table.

pub fn checksum_header(
  algorithm: ChecksumAlgorithm,
  body: BitArray,
) -> #(String, String)

(header_name, base64_digest) pair for a body checksum. The header name follows the AWS convention x-amz-checksum-<algo> (lowercase). The digest is base64 of the raw bytes — same padding rules as Content-MD5. Pure function; the aws.protocols#httpChecksum middleware in the codegen layer calls this and inserts the result into the request headers.

pub fn enum_header(
  headers: dict.Dict(String, String),
  name: String,
  from_wire: fn(String) -> Result(t, String),
) -> option.Option(t)

Enum header — looks up a string header, then runs the supplied <enum>_from_wire decoder. Falls through to None if the header is missing or the wire value doesn’t match a known variant (forgiving contract — unknown variants don’t crash the response parse). The codegen passes the generated <enum>_from_wire function directly so this stays enum-agnostic.

pub fn enum_wire_value(j: json.Json) -> String

Extract the raw wire string from a JSON-encoded enum value. The generated encode_<enum>_enum(v) returns a json.Json like json.string("VALUE"); URI / query / header position wants just VALUE. We render to JSON text and strip the surrounding quotes.

pub fn epoch_seconds_header(
  headers: dict.Dict(String, String),
  name: String,
) -> option.Option(json_timestamp.Timestamp)

Epoch-seconds timestamp header (@timestampFormat("epoch-seconds"), integer seconds since 1970 in the header value).

pub fn float_header(
  headers: dict.Dict(String, String),
  name: String,
) -> option.Option(Float)

Float header — used for shapes that bind a Float member to a response header. Falls through to None if the value can’t be parsed; same forgiving contract as int_header / bool_header.

pub fn float_to_query(f: Float) -> String

Float → query / header / URI-label value. Uses Erlang’s short formatter so 1.1 round-trips as the literal "1.1" — the AWS SimpleScalarProperties protocol-test corpus rejects scientific notation in these positions.

pub fn glacier_tree_hash(body: BitArray) -> BitArray

Compute the Glacier tree hash of body as raw bytes (caller hex-encodes for the wire). Empty body degenerates to SHA-256("") so the function is total. Matches glacier_interceptors::compute_hash_tree in the Rust SDK.

pub fn http_date_header(
  headers: dict.Dict(String, String),
  name: String,
) -> option.Option(json_timestamp.Timestamp)

HTTP-date header — RFC 7231 §7.1.1.1 form (Tue, 29 Apr 2014 18:30:38 GMT). The default @timestampFormat for header bindings per Smithy core — covers Last-Modified, Expires, Date, etc. Forgiving contract: missing header or unparseable string → None.

pub fn idempotency_token() -> String

Generated @idempotencyToken value, used when a request member with that trait is left as Option.None. Backed by the runtime FFI so tests can pin a deterministic UUID via application:set_env.

pub fn int_header(
  headers: dict.Dict(String, String),
  name: String,
) -> option.Option(Int)
pub fn int_to_query(n: Int) -> String

Int → query / header value as decimal.

pub fn iso8601_header(
  headers: dict.Dict(String, String),
  name: String,
) -> option.Option(json_timestamp.Timestamp)

ISO 8601 timestamp header (@timestampFormat("date-time"), 2024-01-02T03:04:05Z).

pub fn maybe_set_header(
  headers: dict.Dict(String, String),
  name: String,
  value: String,
) -> dict.Dict(String, String)

Set a header on the headers dict if the value is non-empty (Smithy @httpHeader typically omits the header when the value is None).

pub fn maybe_set_list_header(
  headers: dict.Dict(String, String),
  name: String,
  values: List(String),
) -> dict.Dict(String, String)

@httpHeader on a list member emits the values comma-joined, per HTTP/1.1 header-folding rules. Some(["a", "b"]) becomes Name: a, b. Empty lists drop the header entirely.

pub fn quote_list_string_entry(v: String) -> String

RFC 7230 list-header quoting for string elements. Smithy applies this only to string-typed entries — timestamp values use the raw Mon, 16 Dec ... GMT form even though it contains a comma.

pub fn set_default_header(
  headers: dict.Dict(String, String),
  name: String,
  value: String,
) -> dict.Dict(String, String)

Insert a service-level default header only when the caller hasn’t already provided one with the same name. Mirrors set_default_header in the Rust SDK and the contains_key guard inside Glacier’s add_checksum_treehash so caller @httpHeader-bound values win on collision.

pub fn string_header(
  headers: dict.Dict(String, String),
  name: String,
) -> option.Option(String)
pub fn substitute_label(
  template: String,
  name: String,
  value: String,
  greedy: Bool,
) -> String

Substitute a single @httpLabel member into the URI template. Templates use {Name} or {Name+} (the + marks a greedy label that may contain /). Values are percent-encoded; greedy labels preserve / in the value.

pub fn timestamp_to_header(epoch_seconds: Int) -> String

Format a timestamp for use in URI labels / query strings / headers. Smithy’s default @timestampFormat for date-time (the restJson1 + restXml default) is RFC 3339, e.g. 2019-12-16T23:48:18Z. We always emit Z-suffixed UTC; the wire form remains stable even if the input came from a system clock in a different zone.

pub fn with_checksum_header(
  headers: dict.Dict(String, String),
  algorithm: ChecksumAlgorithm,
  body: BitArray,
) -> dict.Dict(String, String)

Add an x-amz-checksum-<algo> header to the request. Convenience wrapper around checksum_header that lets call sites stay pipeline-style with the existing Dict(String, String) header shape — same ergonomics as with_content_md5_header.

pub fn with_checksum_header_for_wire(
  headers: dict.Dict(String, String),
  wire: String,
  body: BitArray,
) -> dict.Dict(String, String)

Add the x-amz-checksum-<algo> header using a wire-form algorithm name. Equivalent to with_checksum_header(headers, checksum_algorithm_from_wire(wire), body). Exists so the codegen can emit a single call that takes the generated enum’s wire-encoder output directly, without needing per-service algorithm-mapping helpers.

pub fn with_content_md5_header(
  headers: dict.Dict(String, String),
  body: BitArray,
) -> dict.Dict(String, String)

Set the Content-MD5 header to base64(md5(body)). Used by the Smithy smithy.api#httpChecksumRequired trait — the codegen emits a call to this helper at the tail of build_<op>_request for any operation that carries the trait.

Always overwrites a previous Content-MD5 entry: the SDK is responsible for the canonical value, and a stale caller-supplied one would surface as a 400 from the service. Other headers pass through unchanged.

MD5 is not a security primitive here. The wire contract requires it (S3-control + restJson1 protocol tests fix the exact bytes); SigV4 covers the actual auth on the request.

pub fn with_glacier_tree_hash_headers(
  headers: dict.Dict(String, String),
  body: BitArray,
) -> dict.Dict(String, String)

Glacier’s tree-hash + content-sha256 headers. Both end up as the Computed against the recursive 1 MiB chunk algorithm at https://docs.aws.amazon.com/amazonglacier/latest/dev/checksum- calculations.html: split the body into 1 MiB chunks, SHA-256 each, then pair-hash adjacent digests until one remains. Single-chunk bodies degenerate to plain SHA-256 (tree-hash == content-sha256), which is what every Glacier protocol-test fixture happens to use, but the recursive form is required for the > 1 MiB upload archive path used by real callers.

X-Amz-Sha256-Tree-Hash carries the tree-hash digest; X-Amz-Content-Sha256 carries the full-body SHA-256. The Rust SDK uses the same pair of headers in glacier_interceptors:: add_checksum_treehash. Both are skipped when already present so a caller-supplied value wins.

Search Document