Description
Describe the bug
- don't know how to set canned ACL in presigned url.
- even if I set content type in PutObjectInput, the SignedHeaders doesn't contain it.
- misleading error and different results in different clients.
Expected Behavior
when using the presigned url, a file should be uploaded successfully.
Current Behavior
1.when I set acl:types.ObjectCannedACLPublicRead
in PutObjectInput,the client should set x-amz-acl in header,which is not expected. it should be one of presigned url's query params.(I found this issue aws/aws-sdk-java-v2#1849 exactly the same as my confusion, but I don't know how to override it in go)
2. set content type="image/png" in PutObjectInput that limit didn't appear in signedheaders, so the client can successfully upload a txt file with content type text/plain(it returns HTTP status 200)
3. got NotImplemented error, I found that I didn't set the content length. the "NotImplemented error" is misleading.
the same presigned URL can be used in go client, but in PostMan, it returns the SignatureDoesNotMatch error. Copy the curl code exported by postman,it works too. why?
Reproduction Steps
server-side code:
generate upload URL
preReq, err := s.presvc.PresignPutObject(context.Background(), &s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
ContentType: aws.String("image/png"),
}, s3.WithPresignExpires(time.Hour))
client-side 1:
stats, _ := os.Stat(path)
f, _ := os.Open(path)
req, err := http.NewRequest("PUT", uploadURL, f)
// we can't change this 2 lines ,as client are not under our control, they got resigned URL from java server before.
req.Header.Set("Content-Type", "image/png")
req.Header.Set("Cache-Control", "public, max-age=31536000")
req.ContentLength = stats.Size()
response, err := http.DefaultClient.Do(req)
it works.
client-side 2:
use Postman
I copy that URL in postman, set the method to PUT, in the body, I choose binary and upload a file, then I get a SignatureDoesNotMatch error.
(when i set acl in putObjectInput and generate a presigned URL, i can use postman to upload a file with header X-Amz-acl)
client-side 3:
just use the curl code exported by postMan in client-side 2, it works. why?it both works with or without Content-Type header.
curl --location --request PUT 'https://<my-bucket>.s3.us-east-1.amazonaws.com/<my-key>?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<xxx>%2F20220430%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220430T103611Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=PutObject&X-Amz-Signature=7f9a9a6fd1652ad483aadbe87fe7d20c564ddbb209bfccf8aaa92a2e5a4cb8fa ' \ --header 'Content-Type: image/png' \ --data-binary '@path/redis.png'
BTW: I don't know how to set that object's ACL in presigned URL, the options just contain a few like WithPresignExpires.
I searched in test.go, go examples, document in AWS, but they just told me how to generate a resigned URL, never told me how to use it.I see this issue: #1134 it seems not to work(if that means I should inclued headers that X-Amz-SignedHeaders provided when I use that presinged URL), that can't explain the failure in postman.
Possible Solution
No response
Additional Information/Context
No response
AWS Go SDK V2 Module Versions Used
github.com/aws/aws-sdk-go-v2 v1.16.3
github.com/aws/aws-sdk-go-v2/credentials v1.12.0
github.com/aws/aws-sdk-go-v2/service/s3 v1.26.7
Compiler and Version used
1.18
Operating System and version
macOs monterey
Activity