Unverified Commit cb67432c authored by Kefu Chai's avatar Kefu Chai Committed by GitHub
Browse files

sig_v4: Fix status code for invalid x-amz-content-sha256 header (#430)



The extract_amz_content_sha256() function was using S3ErrorCode::Custom()
to create a SignatureDoesNotMatch error. This caused the error to return
HTTP status 500 (Internal Server Error) instead of the correct 403 (Forbidden).

Problem:
When the Mint test suite's aws-sdk-go-v2 test sent an invalid
x-amz-content-sha256 header value, the server returned a 500 status code.
Some HTTP clients (including the test's HTTP client) don't read the response
body for 5xx errors, resulting in EOF when trying to unmarshal the error XML.

Root Cause:
Using S3ErrorCode::Custom() creates an error without a proper status code
mapping, defaulting to 500. The proper SignatureDoesNotMatch variant exists
in the S3ErrorCode enum and is mapped to HTTP 403 (Forbidden).

Solution:
Changed from:
  S3ErrorCode::Custom(ByteString::from_static("SignatureDoesNotMatch")).into()
To:
  S3Error::new(S3ErrorCode::SignatureDoesNotMatch)

This ensures the error returns the correct HTTP 403 status code, allowing
clients to properly read and parse the error response body.

Impact:
- Mint test suite aws-sdk-go-v2 testPresignedPutInvalidHash now passes
- Error responses are now standards-compliant with AWS S3 behavior
- Clients can properly handle signature validation errors

Testing:
- Verified with Mint test suite that testPresignedPutInvalidHash passes
- Confirmed error returns HTTP 403 instead of HTTP 500
- Response body is properly read and parsed by clients

Signed-off-by: default avatarKefu Chai <tchaikov@gmail.com>
parent 0d6fe98f
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ use crate::utils::is_base64_encoded;
use std::mem;
use std::ops::Not;

use bytestring::ByteString;
use hyper::Method;
use hyper::Uri;
use mime::Mime;
@@ -34,7 +33,7 @@ fn extract_amz_content_sha256<'a>(hs: &'_ OrderedHeaders<'a>) -> S3Result<Option
        Ok(x) => Ok(Some(x)),
        Err(e) => {
            // https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-troubleshooting.html
            let mut err: S3Error = S3ErrorCode::Custom(ByteString::from_static("SignatureDoesNotMatch")).into();
            let mut err = S3Error::new(S3ErrorCode::SignatureDoesNotMatch);
            err.set_message("invalid header: x-amz-content-sha256");
            err.set_source(Box::new(e));
            Err(err)