Skip to content

can't create presigned url with canned acl, can't limit content type #1692

Closed as not planned
@congbaoyangrou

Description

Describe the bug

  1. don't know how to set canned ACL in presigned url.
  2. even if I set content type in PutObjectInput, the SignedHeaders doesn't contain it.
  3. 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions