Closed jie closed 10 months ago
HI @jie,
The current behavior you outlined is the expected behavior. The SDK doesn't add headers like Cache-Control (and others) directly as query parameters in the presigned URL. Instead, it signifies which headers will be required when the presigned URL is used, evident by the &X-Amz-SignedHeaders=cache-control%3Bhost
in the URL.
When you, or anyone else with the presigned URL, wants to upload an object, the Cache-Control header needs to be set to max-age=60 in the HTTP request. The presigned URL "reserves" the right for you to set this header, and S3 expects and validates it based on the signature in the URL.
You can inspect the signing by enabling the signing logger on the presigner:
input := &s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String("hey.txt"),
Body: data,
CacheControl: aws.String("max-age=60"),
}
signedRequest, err := presigner.PresignPutObject(context.TODO(), input, func(options *s3.PresignOptions) {
options.ClientOptions = append(options.ClientOptions, func(op2 *s3.Options) {
op2.ClientLogMode = aws.LogSigning | op2.ClientLogMode
})
})
In the following logs you can see the signed canonical string and that it does include the cache control key and value:
SDK 2023/11/04 20:55:19 DEBUG Request Signature:
---[ CANONICAL STRING ]-----------------------------
PUT
/hey.txt
X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=REDACTED%2F20231105%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20231105T035519Z&X-Amz-Expires=900&X-Amz-SignedHeaders=cache-control%3Bcontent-length%3Bcontent-type%3Bhost&x-id=PutObject
cache-control:max-age=60
content-length:29036
content-type:application/octet-stream
host:REDACTED.s3.us-east-1.amazonaws.com
cache-control;content-length;content-type;host
UNSIGNED-PAYLOAD
---[ STRING TO SIGN ]--------------------------------
AWS4-HMAC-SHA256
20231105T035519Z
20231105/us-east-1/s3/aws4_request
b02cb080979e4520f9156ed70b699c67566b47dd481e7f0e471e671ae1REDACTED
---[ SIGNED URL ]------------------------------------
https://REDACTED.s3.us-east-1.amazonaws.com/hey.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=REDACTED%2F20231105%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20231105T035519Z&X-Amz-Expires=900&X-Amz-SignedHeaders=cache-control%3Bcontent-length%3Bcontent-type%3Bhost&x-id=PutObject&X-Amz-Signature=REDACTED
In the case on my signed URL, the SDK signed content-length
, content-type
, host
and cache-control
. This means that when I use this presigned URL, my request must have those headers sent with the same values so that when the S3 service receives my request, and signs it itself, the signature calculated by the SDK client and the signature calculated by the S3 service would match.
Embedding headers like Cache-Control directly into the URL would risk exposing them to anyone who sees the URL. By keeping them as required signed headers, it ensures that the client making the request explicitly sets these headers, providing a clearer understanding of the request's intention and making certain that the headers aren't tampered with during transit.
I hope this clears things up. All the best, Ran~
@RanVaknin You answered my question and solved my problem. Thank you!
Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.
Describe the bug
Set the cachecontrol=max-age=60, but get:X-Amz-SignedHeaders=cache-control%3Bhost The return url looks like:
Expected Behavior
cachecontrol=max-age=60
Current Behavior
&X-Amz-SignedHeaders=cache-control%3Bhost
Reproduction Steps
run the PutObject method
Possible Solution
No response
Additional Information/Context
No response
AWS Go SDK V2 Module Versions Used
Compiler and Version used
v1.18.0
Operating System and version
MacOS 14