mirror of
https://github.com/versity/versitygw.git
synced 2026-09-23 00:14:15 +00:00
Merge pull request #2324 from mu-adnan/fix/post-object-default-content-type
fix: apply default Content-Type in POSTObject
This commit is contained in:
@@ -118,6 +118,9 @@ func (c S3ApiController) POSTObject(ctx fiber.Ctx) (*Response, error) {
|
||||
parsed := utils.ContextKeyObjectPostResult.Get(ctx).(middlewares.PostObjectResult)
|
||||
bucket := ctx.Params("bucket")
|
||||
contentType := parsed.Fields["content-type"]
|
||||
if contentType == "" {
|
||||
contentType = defaultContentType
|
||||
}
|
||||
contentEncoding := parsed.Fields["content-encoding"]
|
||||
contentDisposition := parsed.Fields["content-disposition"]
|
||||
contentLanguage := parsed.Fields["content-language"]
|
||||
|
||||
@@ -620,6 +620,47 @@ func TestS3ApiController_POSTObject(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "default content type when field is omitted",
|
||||
input: testInput{
|
||||
beRes: s3response.PutObjectOutput{
|
||||
ETag: "etag-123",
|
||||
},
|
||||
locals: postObjectLocalsForTest(middlewares.PostObjectResult{
|
||||
Fields: baseFields,
|
||||
FileRdr: newMockFileReader("payload"),
|
||||
ContentLength: int64(len("payload")),
|
||||
}),
|
||||
},
|
||||
output: testOutput{
|
||||
response: &Response{
|
||||
Headers: map[string]*string{
|
||||
"Etag": utils.GetStringPtr("etag-123"),
|
||||
"Location": &location,
|
||||
"x-amz-checksum-crc32": nil,
|
||||
"x-amz-checksum-crc32c": nil,
|
||||
"x-amz-checksum-crc64nvme": nil,
|
||||
"x-amz-checksum-sha1": nil,
|
||||
"x-amz-checksum-sha256": nil,
|
||||
"x-amz-checksum-sha512": nil,
|
||||
"x-amz-checksum-md5": nil,
|
||||
"x-amz-checksum-xxhash64": nil,
|
||||
"x-amz-checksum-xxhash3": nil,
|
||||
"x-amz-checksum-xxhash128": nil,
|
||||
"x-amz-checksum-type": nil,
|
||||
"x-amz-version-id": nil,
|
||||
},
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: "root",
|
||||
ContentLength: int64(len("payload")),
|
||||
ObjectETag: utils.GetStringPtr("etag-123"),
|
||||
ObjectSize: int64(len("payload")),
|
||||
EventName: s3event.EventObjectCreatedPost,
|
||||
Status: http.StatusNoContent,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "anonymous upload with policy is evaluated",
|
||||
input: testInput{
|
||||
@@ -665,6 +706,10 @@ func TestS3ApiController_POSTObject(t *testing.T) {
|
||||
assert.Equal(t, "anon-payload", string(body))
|
||||
}
|
||||
|
||||
if tt.name == "default content type when field is omitted" {
|
||||
assert.Equal(t, defaultContentType, *putObjectInput.ContentType)
|
||||
}
|
||||
|
||||
if tt.name == "successful created response" {
|
||||
assert.Equal(t, "bucket", *putObjectInput.Bucket)
|
||||
assert.Equal(t, "uploads/photo.jpg", *putObjectInput.Key)
|
||||
|
||||
@@ -976,6 +976,64 @@ func PostObject_success_with_meta_properties(s *S3Conf) error {
|
||||
})
|
||||
}
|
||||
|
||||
func PostObject_default_content_type(s *S3Conf) error {
|
||||
testName := "PostObject_default_content_type"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
for _, tt := range []struct {
|
||||
key string
|
||||
policyConditions []any
|
||||
extraFields map[string]string
|
||||
}{
|
||||
{
|
||||
key: "omitted-content-type",
|
||||
},
|
||||
{
|
||||
key: "empty-content-type",
|
||||
policyConditions: []any{
|
||||
[]any{"starts-with", "$Content-Type", ""},
|
||||
},
|
||||
extraFields: map[string]string{
|
||||
"Content-Type": "",
|
||||
},
|
||||
},
|
||||
} {
|
||||
resp, err := sendPostObject(PostRequestConfig{
|
||||
bucket: bucket,
|
||||
key: tt.key,
|
||||
s3Conf: s,
|
||||
fileContent: []byte("dummy data"),
|
||||
policyConditions: tt.policyConditions,
|
||||
extraFields: tt.extraFields,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusNoContent {
|
||||
return fmt.Errorf("%s: expected status code to be 204, instead got %d",
|
||||
tt.key, resp.StatusCode)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
out, err := s3client.HeadObject(ctx, &s3.HeadObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: &tt.key,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if getString(out.ContentType) != defaultContentType {
|
||||
return fmt.Errorf("%s: expected default %s Content-Type, instead got %s",
|
||||
tt.key, defaultContentType, getString(out.ContentType))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func PostObject_invalid_website_redirect_location(s *S3Conf) error {
|
||||
testName := "PostObject_invalid_website_redirect_location"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
|
||||
@@ -2033,6 +2033,7 @@ func TestPostObject(ts *TestState) {
|
||||
ts.Run(PostObject_success_status_201)
|
||||
ts.Run(PostObject_should_ignore_anything_after_file)
|
||||
ts.Run(PostObject_success_with_meta_properties)
|
||||
ts.Run(PostObject_default_content_type)
|
||||
ts.Run(PostObject_invalid_website_redirect_location)
|
||||
ts.Run(PostObject_invalid_tagging)
|
||||
ts.Run(PostObject_success_with_tagging)
|
||||
@@ -3494,6 +3495,7 @@ func GetIntTests() IntTests {
|
||||
"PostObject_success_status_201": PostObject_success_status_201,
|
||||
"PostObject_should_ignore_anything_after_file": PostObject_should_ignore_anything_after_file,
|
||||
"PostObject_success_with_meta_properties": PostObject_success_with_meta_properties,
|
||||
"PostObject_default_content_type": PostObject_default_content_type,
|
||||
"PostObject_invalid_website_redirect_location": PostObject_invalid_website_redirect_location,
|
||||
"PostObject_invalid_tagging": PostObject_invalid_tagging,
|
||||
"PostObject_success_with_tagging": PostObject_success_with_tagging,
|
||||
|
||||
Reference in New Issue
Block a user