Hi there,
I am using presigned POST urls to upload files to Tigris buckets. To set the correct MIME type, I add the MIME type in the Content-Type header during the file upload request. This seems to work without explicitly specifying the content-type in the presigned url.
Does this work for any MIME type?
I am asking this because when I include the Content-Type in the signing process like X-Amz-SignedHeaders=content-type;host
with the MIME defined in the canonical part, then I get an Signature does not match
error during the upload request.
So my second question:
Is this a mistake on my part or is Tigris not yet compatiple with this S3 feature?
Thanks in advance.
jmj
June 17, 2025, 7:23pm
2
Hello @hakoptak
Can you share your client code that generates pre-signed URL accounting the Content-Type.
Thanks!
Jigar
Hi @jmj , thanks for following up. Just to let you know that I am preparing a detailed response, but that I’m a bit short on time at this moment. I’ll keep this thread open in the meanwhile.
By the way: I did spot a tiny mistake/ambiguity in the documentation about presigning . It says:
… and generated URL would look like:
https://t3.storage.dev/mybucket.mydomain.com/hello.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=tid_
This should be:
https://fly.storage.tigris.dev/mybucket.mydomain.com/hello.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=tid_
I’ll try to answer this tomorrow.
Hi @jmj , I’m using the same code as shared in this post , except that:
// Add parameters in the correct order
canonicalQueryString.WriteString(fmt.Sprintf("X-Amz-Algorithm=%s", algorithm))
canonicalQueryString.WriteString(fmt.Sprintf("&X-Amz-Credential=%s", credential.String()))
canonicalQueryString.WriteString(fmt.Sprintf("&X-Amz-Date=%s", dateTime))
canonicalQueryString.WriteString(fmt.Sprintf("&X-Amz-Expires=%d", int(p.Expiration.Seconds())))
canonicalQueryString.WriteString("&X-Amz-SignedHeaders=content-type;host")
// Build host and canonical headers
var canonicalHeaders strings.Builder
canonicalHeaders.WriteString(fmt.Sprintf("content-type:%s", mime))
canonicalHeaders.WriteByte('\n')
canonicalHeaders.WriteString(fmt.Sprintf("host:%s", p.Endpoint))
canonicalHeaders.WriteByte('\n')
// Build canonical request
var canonicalRequest strings.Builder
canonicalRequest.WriteString(p.Method)
canonicalRequest.WriteByte('\n')
canonicalRequest.WriteString(canonicalURI.String())
canonicalRequest.WriteByte('\n')
canonicalRequest.WriteString(canonicalQueryString.String())
canonicalRequest.WriteByte('\n')
canonicalRequest.WriteString(canonicalHeaders.String())
canonicalRequest.WriteByte('\n')
canonicalRequest.WriteString("content-type;host")
canonicalRequest.WriteByte('\n')
canonicalRequest.WriteString("UNSIGNED-PAYLOAD")
The client then generates the following url:
https://test.sessions.pinggg.cloud/7s8g5fgphySq7gc07POSts74eDDfoO77q61BcJUQOCCA/shares/1.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=tid_mNpmYFuMLHfstgsbJEnjDXQLjRSgqXlznLCJdlY_ZIhereWHco%2F20250627%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20250627T180046Z&X-Amz-Expires=15&X-Amz-SignedHeaders=content-type;host&X-Amz-Signature=e58ac8dc263db97f06795cc46ac5fa0bb1aaeb2952b1eb66f8beb7ef7a5139fc
But during upload I get the message (400 Bad Request
):
<Error>
<Code>AuthorizationQueryParametersError</Code>
<Message>Query-string authentication version 4 requires the X-Amz-Algorithm, X-Amz-Credential, X-Amz-Signature, X-Amz-Date, X-Amz-SignedHeaders, and X-Amz-Expires parameters.</Message>
<Resource>/7s8g5fgphySq7gc07POSts74eDDfoO77q61BcJUQOCCA/shares/1.png</Resource>
<RequestId>1751047264049587309</RequestId>
<Key>7s8g5fgphySq7gc07POSts74eDDfoO77q61BcJUQOCCA/shares/1.png</Key>
<BucketName>test.sessions.pinggg.cloud</BucketName>
</Error>
When I don’t include the content type in the signing process then it works fine.
For now I leave out the content type… and put my focus back on building my product
system
Closed
July 4, 2025, 7:32pm
6
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.