use http::HeaderMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum StreamingUpload {
Unsigned,
Signed,
}
pub(crate) fn streaming_upload(headers: &HeaderMap) -> Option<(StreamingUpload, &str)> {
let sentinel = headers.get("x-amz-content-sha256")?.to_str().ok()?;
let variant = sentinel.strip_prefix("STREAMING-")?;
let kind = if variant.contains("UNSIGNED") {
StreamingUpload::Unsigned
} else {
StreamingUpload::Signed
};
Some((kind, sentinel))
}
#[cfg(test)]
mod tests {
use super::*;
fn headers(content_sha256: &str) -> HeaderMap {
let mut h = HeaderMap::new();
if !content_sha256.is_empty() {
h.insert("x-amz-content-sha256", content_sha256.parse().unwrap());
}
h
}
#[test]
fn unsigned_streaming_is_unsigned() {
assert_eq!(
streaming_upload(&headers("STREAMING-UNSIGNED-PAYLOAD-TRAILER")),
Some((
StreamingUpload::Unsigned,
"STREAMING-UNSIGNED-PAYLOAD-TRAILER"
))
);
assert_eq!(
streaming_upload(&headers("STREAMING-UNSIGNED-PAYLOAD")),
Some((StreamingUpload::Unsigned, "STREAMING-UNSIGNED-PAYLOAD"))
);
}
#[test]
fn signed_streaming_is_signed() {
assert_eq!(
streaming_upload(&headers("STREAMING-AWS4-HMAC-SHA256-PAYLOAD")),
Some((
StreamingUpload::Signed,
"STREAMING-AWS4-HMAC-SHA256-PAYLOAD"
))
);
}
#[test]
fn non_streaming_is_none() {
assert_eq!(streaming_upload(&headers("UNSIGNED-PAYLOAD")), None);
assert_eq!(streaming_upload(&headers("")), None);
}
}