Skip to content

Commit fa985b0

Browse files
russellbjhjaggars
authored andcommitted
fix(sandbox): handle streaming SigV4 payload modes from boto3
Boto3 put_object sends x-amz-content-sha256 with the value STREAMING-AWS4-HMAC-SHA256-PAYLOAD, which was rejected by detect_payload_mode() because per-chunk signing is not supported. Treat all streaming- variants as StreamingUnsignedTrailer: re-sign headers only and stream the body through. The proxy cannot reproduce per-chunk signatures, but AWS accepts unsigned streaming payloads over HTTPS. Refs #1576
1 parent 029e563 commit fa985b0

1 file changed

Lines changed: 7 additions & 6 deletions

File tree

  • crates/openshell-sandbox/src/l7

crates/openshell-sandbox/src/l7/rest.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,22 +1560,23 @@ impl fmt::Display for SigV4PayloadMode {
15601560
/// - `STREAMING-UNSIGNED-PAYLOAD-TRAILER` → `StreamingUnsignedTrailer`
15611561
/// - `UNSIGNED-PAYLOAD` → `UnsignedPayload`
15621562
/// - Hex hash → `SignBody` (buffer + hash, requires `Content-Length`)
1563-
/// - `STREAMING-AWS4-HMAC-SHA256-PAYLOAD` → rejected (per-chunk signing unsupported)
1563+
/// - `STREAMING-AWS4-HMAC-SHA256-PAYLOAD` → `StreamingUnsignedTrailer` (re-sign
1564+
/// headers only; the proxy cannot reproduce per-chunk signatures, but the
1565+
/// body streams through intact and AWS accepts unsigned streaming payloads)
15641566
/// - Absent → `SignBody` if `Content-Length` present, else `UnsignedPayload`
15651567
fn detect_payload_mode(headers: &str) -> Result<SigV4PayloadMode> {
15661568
for line in headers.lines().skip(1) {
15671569
let lower = line.to_ascii_lowercase();
15681570
if lower.starts_with("x-amz-content-sha256:") {
15691571
let val = lower.split_once(':').map_or("", |(_, v)| v.trim());
15701572
return match val {
1571-
"streaming-unsigned-payload-trailer" => {
1573+
"streaming-unsigned-payload-trailer" | "streaming-aws4-hmac-sha256-payload" => {
15721574
Ok(SigV4PayloadMode::StreamingUnsignedTrailer)
15731575
}
15741576
"unsigned-payload" => Ok(SigV4PayloadMode::UnsignedPayload),
1575-
v if v.starts_with("streaming-") => Err(miette!(
1576-
"SigV4 per-chunk streaming signing ({v}) is not supported; \
1577-
use credential_signing: sigv4 (auto-detect) or sigv4:no_body"
1578-
)),
1577+
v if v.starts_with("streaming-") => {
1578+
Ok(SigV4PayloadMode::StreamingUnsignedTrailer)
1579+
}
15791580
_ => Ok(SigV4PayloadMode::SignBody),
15801581
};
15811582
}

0 commit comments

Comments
 (0)