///|
pub(all) struct Credentials {
access_key_id : String
secret_access_key : String
session_token : String?
} derive(Eq)
///|
pub fn Credentials::Credentials(
access_key_id : String,
secret_access_key : String,
session_token? : String,
) -> Credentials {
{ access_key_id, secret_access_key, session_token, }
}
///|
/// An HTTP request to be signed. `meth` is the request method, `path` is the
/// request-target path as sent (URI-encoded once), `query` holds the query
/// parameters exactly as they will appear on the wire — names and values
/// already RFC 3986 component-encoded (see `encode_query_component`),
/// duplicates allowed, `None` for a bare parameter without `=` — `headers`
/// are name/value pairs in any order, and `body` holds the raw payload
/// bytes.
pub(all) struct HttpRequest {
meth : @http.RequestMethod
path : String
query : Array[(String, String?)]
headers : Array[(String, String)]
body : Bytes
} derive(Eq)
///|
/// How the payload line of the canonical request is produced:
///
/// - `Sha256` — hash `body` and use it as the payload line (generic services
/// that include the payload hash in the signature)
/// - `Empty` — the hash of the empty body as the payload line
/// - `Unsigned` — the literal `UNSIGNED-PAYLOAD` line (S3 streaming/chunked
/// uploads and shared download URLs)
/// - `Provided` — a caller-computed hash (hex, or `UNSIGNED-PAYLOAD`) as the
/// payload line
///
/// The payload line is independent of the `X-Amz-Content-Sha256` header —
/// whether that header is added is governed by `payload_checksum_kind`.
pub(all) enum PayloadHash {
Sha256
Empty
Unsigned
Provided(String)
} derive(Eq)
///|
/// Whether the `X-Amz-Content-Sha256` header is added to the signed request:
///
/// - `NoHeader` — "normal mode"; correct for every AWS service except S3
/// (the default)
/// - `XAmzSha256` — add the header carrying the resolved payload line;
/// required for S3
pub(all) enum PayloadChecksumKind {
XAmzSha256
NoHeader
} derive(Eq)
///|
/// How the canonical request's URI path is encoded. The request `path` is
/// assumed to be URI-encoded once, as sent:
///
/// - `Double` — re-encode `%` as `%25` (and any remaining reserved
/// characters); required by most services, which do not decode the path
/// before verifying the signature (the default)
/// - `Single` — take the path as-is; required by S3, which rejects
/// double-encoded paths
pub(all) enum PercentEncoding {
Double
Single
} derive(Eq)
///|
/// Request signing options: a SigV4 timestamp (`YYYYMMDDTHHMMSSZ`) and the
/// credential scope, plus behavioral switches. `normalize_path` removes
/// RFC 3986 dot segments before signing and defaults to true — correct for
/// every AWS service except S3, where object keys containing `.` / `..`
/// must survive. `omit_session_token` keeps a session token out of the
/// signature while still sending it as a request header (SigV4 conformance
/// scenarios). `excluded_headers` are excluded from the signature (matched
/// case-insensitively) but still sent with the request.
pub(all) struct SigningOptions {
timestamp : String
region : String
service : String
normalize_path : Bool
percent_encoding : PercentEncoding
payload_hash : PayloadHash
payload_checksum_kind : PayloadChecksumKind
omit_session_token : Bool
excluded_headers : Array[String]
} derive(Eq)
///|
/// Headers excluded from signing by default: calculated by the signer
/// itself, altered by proxies, or request-independent. Mirrors the
/// exclusion sets used by the Go, Java, JS and Rust AWS SDKs. Excluded
/// headers are still sent with the request.
fn default_excluded_headers() -> Array[String] {
[
"authorization", "user-agent", "x-amzn-trace-id", "expect", "transfer-encoding",
]
}
///|
pub fn SigningOptions::SigningOptions(
timestamp~ : String,
region~ : String,
service~ : String,
normalize_path? : Bool = true,
percent_encoding? : PercentEncoding = Double,
payload_hash? : PayloadHash = Sha256,
payload_checksum_kind? : PayloadChecksumKind = NoHeader,
omit_session_token? : Bool = false,
excluded_headers? : Array[String] = default_excluded_headers(),
) -> SigningOptions {
{
timestamp,
region,
service,
normalize_path,
percent_encoding,
payload_hash,
payload_checksum_kind,
omit_session_token,
excluded_headers,
}
}
///|
/// Signing options for S3 and S3-compatible providers (MinIO, Cloudflare
/// R2, Backblaze B2, Wasabi, DigitalOcean Spaces, ...): paths are taken
/// exactly as sent (no dot-segment normalization, no re-encoding) and the
/// `X-Amz-Content-Sha256` header is added, as the S3 API requires.
/// `service` defaults to `"s3"`, the signing name used by every
/// S3-compatible provider; `region` is provider-specific (e.g.
/// `"us-east-1"` for AWS, `"auto"` for R2, the server-configured region for
/// MinIO).
pub fn SigningOptions::for_s3(
timestamp~ : String,
region~ : String,
service? : String = "s3",
payload_hash? : PayloadHash = Sha256,
omit_session_token? : Bool = false,
excluded_headers? : Array[String] = default_excluded_headers(),
) -> SigningOptions {
SigningOptions::SigningOptions(
timestamp~,
region~,
service~,
normalize_path=false,
percent_encoding=Single,
payload_hash~,
payload_checksum_kind=XAmzSha256,
omit_session_token~,
excluded_headers~,
)
}
///|
/// The canonical-layer intermediates of a SigV4 signing operation, exposed
/// for debugging and for algorithms that share the canonical layer (e.g.
/// SigV4a). `canonical_request` is the `\n`-joined creq string,
/// `string_to_sign` the `AWS4-HMAC-SHA256` sts string built from it, and
/// `signed_headers` / `payload_hash` the `SignedHeaders=` value and resolved
/// canonical payload line. For header signing the creq is built from the
/// request's signing headers; for query signing, from the headers that will
/// ride in the URL.
pub(all) struct CanonicalParts {
canonical_request : String
string_to_sign : String
signed_headers : String
payload_hash : String
} derive(Eq)
///|
/// The result of signing a request with the SigV4 query-string auth variant.
/// `url` is the fully signed URL. `signed_headers` is the `SignedHeaders=`
/// value (semicolon-joined, lowercase header names): every header listed
/// there must be sent verbatim with the request for the signature to
/// verify.
pub(all) struct PresignedUrl {
url : String
signed_headers : String
} derive(Eq)