-
Notifications
You must be signed in to change notification settings - Fork 639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Presigned URL for PUT with ContentType but no ContentLength results in URL that doesn't include ContentType in the signed headers #2063
Comments
Hi @RanVaknin and @isaiahvita, Thanks for the response. Ignacio |
Hi @ieguinoa Thanks for the engagement. When it comes to presigned URLs we tend to bias towards removing potentially extraneous headers that would make it harder for customers to configure. Conceptually, presigned URLs are meant to be self-contained requests that will "just work" without need for modification. In the meantime, you can actually customize this behavior for your particular use case by providing a custom client option package main
import (
"bytes"
"context"
"log"
"net/http"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
smithyhttp "github.com/aws/smithy-go/transport/http"
)
func main() {
ctx := context.Background()
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-west-2"), config.WithClientLogMode(aws.LogRequest|aws.LogSigning))
if err != nil {
log.Fatalf("unable to load SDK config, %v", err)
}
s3Client := s3.NewFromConfig(cfg)
presignClient := s3.NewPresignClient(s3Client)
requestBody := []byte("foo")
presignResp, _ := presignClient.PresignPutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String("PLACEHOLDER_BUCKET"),
Key: aws.String("PLACEHOLDER_FILENAME"),
},
func(o *s3.PresignOptions) {
o.ClientOptions = append(o.ClientOptions, func(o *s3.Options) {
o.APIOptions = append(o.APIOptions, smithyhttp.AddHeaderValue("Content-Type", "text/plain"))
})
})
req, _ := http.NewRequest(http.MethodPut, presignResp.URL, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "text/plain")
client := &http.Client{}
client.Do(req)
} |
This issue has not received a response in 1 week. If you want to keep this issue open, please just leave a comment below and auto-close will be canceled. |
Thanks for the response @isaiahvita, that approach did the trick for now. |
|
Describe the bug
Signing a PUT URL with a ContentType value results in a signed URL without Content-Type included in the signed headers unless a ContentLength is also specified.
Expected Behavior
When signing a request with ContentType but no ContentLength I expect to have the signed URL containing content-type but no content-length in the
Current Behavior
There is no content-type in the signed headers (X-Amz-SignedHeaders). The type header is silently removed from the request.
Reproduction Steps
const contentType = "text/plain"
in := &s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
ContentType: aws.String(contentType),
}
p, _ := s3.NewPresignClient(client).PresignPutObject(ctx, in)
fmt.Println(p.URL)
Possible Solution
The problem is here, where it silently removes the content-type when content-length is == 0.
Ideally there should be a way to remove this RemoveContentTypeHeader middleware from the stack, or define a value of content-length that could escape that condition, may not be a clean solution but content-length=-1 could be a value that the user can specify to indicate they know the type but not the length of the content.
Additional Information/Context
This bug was reported before #1475 but no solution was given for the case when you don't know the length value, so you don't want to specify that header at all.
AWS Go SDK V2 Module Versions Used
v1.17.6
Compiler and Version used
1.20
Operating System and version
Ventura 13.2.1
The text was updated successfully, but these errors were encountered: