hello, I would like to receive pre-computed sha256 hash of file upload from client and generate presigned url for client to upload the file to s3.
here is the code to generate the presigned_url
size = 123
mime_type = "image/jpg"
storage_class = "STANDARD_IA"
key = "some/path/0723faba-72b5-45bf-9373-ad37dbcf6a80.jpg"
hash = "output:{openssl dgst -sha256 /path/to/test/file.jpg}"
:s3
|> ExAws.Config.new()
|> ExAws.S3.presigned_url(
:put,
bucket_name(),
key,
[
expires_in: @upload_expiry,
query_params: [
{"x-amz-acl", "private"},
{"x-amz-storage-class", storage_class},
{"x-amz-server-side-encryption", "AES256"}
],
headers: [
{"content-length", size},
{"content-type", mime_type},
{"x-amz-content-sha256", hash}
]
]
)
I took the url generated from the above code and upload give me this error
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
<AWSAccessKeyId>AKXXXXXXXXXXXXXXX</AWSAccessKeyId>
<StringToSign>AWS4-HMAC-SHA256
20220118T095403Z
20220118/ap-southeast-1/s3/aws4_request
abc123</StringToSign>
<SignatureProvided>abc456</SignatureProvided>
<StringToSignBytes>41 57 XX XX</StringToSignBytes>
<CanonicalRequest>PUT
some/path/0723faba-72b5-45bf-9373-ad37dbcf6a80.jpg
X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKXXXXXXXXXXXXXXX%2F20220118%2Fap-southeast-1%2Fs3%2Faws4_request&X-Amz-Date=20220118T095403Z&X-Amz-Expires=16&X-Amz-SignedHeaders=content-length%3Bcontent-type%3Bhost%3Bx-amz-content-sha256&x-amz-acl=private&x-amz-server-side-encryption=AES256&x-amz-storage-class=STANDARD_IA
content-length:123
content-type:image/jpg
host:s3.ap-southeast-1.amazonaws.com
x-amz-content-sha256:
content-length;content-type;host;x-amz-content-sha256
UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>50 55 XX XX</CanonicalRequestBytes>
<RequestId>9DXXXXXXXXXX</RequestId>
<HostId>DZ7XXXXXX</HostId>
</Error>
When I remove the x-amz-content-sha256
from headers, the request upload the file as expected, and I could test around providing wrong content-type
or content-length
so the request would fail(as expected) meaning the presigned_url
does work when providing headers
value.