Repository: fsouza/fake-gcs-server
Pull request #1866 (2025-01-06 18:17:30)

build(deps): bump github.com/minio/minio-go/v7 from 7.0.82 to 7.0.83
Bumps [github.com/minio/minio-go/v7](https://github.com/minio/minio-go) from 7.0.82 to 7.0.83.
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/minio/minio-go/commit/0abbe92812de3c9e89054cf6ea2d33cf9899b675"><code>0abbe92</code></a> Use default STS endpoint (<a href="https://redirect.github.com/minio/minio-go/issues/2044">#2044</a>)</li>
<li><a href="https://github.com/minio/minio-go/commit/5757f2c8544a80e81a5648b50d63e8461056a9b3"><code>5757f2c</code></a> update golang.org/x/net security</li>
<li><a href="https://github.com/minio/minio-go/commit/7766336259a90f5b806e9c82fa048673f5e7ff1f"><code>7766336</code></a> Bring back Retrieve() interface to be compatible and not break clients</li>
<li><a href="https://github.com/minio/minio-go/commit/4a691e1603a5eaaf0ba478df00487f7c10a19b30"><code>4a691e1</code></a> Use proper HTTP client for fetching credentials (<a href="https://redirect.github.com/minio/minio-go/issues/2041">#2041</a>)</li>
<li><a href="https://github.com/minio/minio-go/commit/8dc4193c7bc08983feae3dbdc9c81c992c6c058d"><code>8dc4193</code></a> update dependent modules</li>
<li><a href="https://github.com/minio/minio-go/commit/ffefc7b31693a3dc76bd86f02e97b7446ce682c6"><code>ffefc7b</code></a> Bump golang.org/x/crypto from 0.28.0 to 0.31.0 (<a href="https://redirect.github.com/minio/minio-go/issues/2038">#2038</a>)</li>
<li><a href="https://github.com/minio/minio-go/commit/320a34c57bc19a2968da628ed0d802fd15180f96"><code>320a34c</code></a> Bump golang.org/x/crypto from 0.28.0 to 0.31.0 in /examples/minio (<a href="https://redirect.github.com/minio/minio-go/issues/2034">#2034</a>)</li>
<li><a href="https://github.com/minio/minio-go/commit/e9337080c543becf97e3ffe1e3ac1b35e0fe6268"><code>e933708</code></a> 408 Server Timeout should be a retryable status code (<a href="https://redirect.github.com/minio/minio-go/issues/2036">#2036</a>)</li>
<li><a href="https://github.com/minio/minio-go/commit/c1d67071f60e04eefcdce7499881f12ca0422a1c"><code>c1d6707</code></a> Update version to next release</li>
<li>See full diff in <a href="https://github.com/minio/minio-go/compare/v7.0.82...v7.0.83">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/minio/minio-go/v7&package-manager=go_modules&previous-version=7.0.82&new-version=7.0.83)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/fakestorage/object.go b/fakestorage/object.go
index 441c4ce..664751e 100644
--- a/fakestorage/object.go
+++ b/fakestorage/object.go
@@ -1262,7 +1262,7 @@ func (s *Server) composeObject(r *http.Request) jsonResponse {
 		sourceNames = append(sourceNames, n.Name)
 	}
 
-	backendObj, err := s.backend.ComposeObject(bucketName, sourceNames, destinationObject, composeRequest.Destination.Metadata, composeRequest.Destination.ContentType)
+	backendObj, err := s.backend.ComposeObject(bucketName, sourceNames, destinationObject, composeRequest.Destination.Metadata, composeRequest.Destination.ContentType, composeRequest.Destination.ContentDisposition, composeRequest.Destination.ContentLanguage)
 	if err != nil {
 		return jsonResponse{
 			status:       http.StatusInternalServerError,
diff --git a/go.mod b/go.mod
index 39e1883..3782012 100644
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@ require (
 	github.com/google/go-cmp v0.6.0
 	github.com/gorilla/handlers v1.5.2
 	github.com/gorilla/mux v1.8.1
-	github.com/minio/minio-go/v7 v7.0.82
+	github.com/minio/minio-go/v7 v7.0.83
 	github.com/pkg/xattr v0.4.10
 	github.com/stretchr/testify v1.10.0
 	golang.org/x/oauth2 v0.25.0
diff --git a/go.sum b/go.sum
index b5531a4..75b2aec 100644
--- a/go.sum
+++ b/go.sum
@@ -123,8 +123,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
 github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
-github.com/minio/minio-go/v7 v7.0.82 h1:tWfICLhmp2aFPXL8Tli0XDTHj2VB/fNf0PC1f/i1gRo=
-github.com/minio/minio-go/v7 v7.0.82/go.mod h1:84gmIilaX4zcvAWWzJ5Z1WI5axN+hAbM5w25xf8xvC0=
+github.com/minio/minio-go/v7 v7.0.83 h1:W4Kokksvlz3OKf3OqIlzDNKd4MERlC2oN8YptwJ0+GA=
+github.com/minio/minio-go/v7 v7.0.83/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY=
 github.com/pkg/xattr v0.4.10 h1:Qe0mtiNFHQZ296vRgUjRCoPHPqH7VdTOrZx3g0T+pGA=
 github.com/pkg/xattr v0.4.10/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU=
 github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
diff --git a/internal/backend/fs.go b/internal/backend/fs.go
index 52cbcd1..b8f226d 100644
--- a/internal/backend/fs.go
+++ b/internal/backend/fs.go
@@ -437,7 +437,7 @@ func concatObjectReaders(objects []StreamingObject) io.ReadSeekCloser {
 	return concatenatedContent{io.MultiReader(readers...)}
 }
 
-func (s *storageFS) ComposeObject(bucketName string, objectNames []string, destinationName string, metadata map[string]string, contentType string) (StreamingObject, error) {
+func (s *storageFS) ComposeObject(bucketName string, objectNames []string, destinationName string, metadata map[string]string, contentType string, contentDisposition string, contentLanguage string) (StreamingObject, error) {
 	var sourceObjects []StreamingObject
 	for _, n := range objectNames {
 		obj, err := s.GetObject(bucketName, n)
@@ -451,11 +451,13 @@ func (s *storageFS) ComposeObject(bucketName string, objectNames []string, desti
 	now := time.Now().Format(timestampFormat)
 	dest := StreamingObject{
 		ObjectAttrs: ObjectAttrs{
-			BucketName:  bucketName,
-			Name:        destinationName,
-			ContentType: contentType,
-			Created:     now,
-			Updated:     now,
+			BucketName:         bucketName,
+			Name:               destinationName,
+			ContentType:        contentType,
+			ContentDisposition: contentDisposition,
+			ContentLanguage:    contentLanguage,
+			Created:            now,
+			Updated:            now,
 		},
 	}
 
diff --git a/internal/backend/memory.go b/internal/backend/memory.go
index f202ff3..17b6480 100644
--- a/internal/backend/memory.go
+++ b/internal/backend/memory.go
@@ -344,7 +344,7 @@ func (s *storageMemory) UpdateObject(bucketName, objectName string, attrsToUpdat
 	return obj, nil
 }
 
-func (s *storageMemory) ComposeObject(bucketName string, objectNames []string, destinationName string, metadata map[string]string, contentType string) (StreamingObject, error) {
+func (s *storageMemory) ComposeObject(bucketName string, objectNames []string, destinationName string, metadata map[string]string, contentType string, contentDisposition string, contentLanguage string) (StreamingObject, error) {
 	var data []byte
 	for _, n := range objectNames {
 		obj, err := s.GetObject(bucketName, n)
@@ -364,11 +364,13 @@ func (s *storageMemory) ComposeObject(bucketName string, objectNames []string, d
 		now := time.Now().Format(timestampFormat)
 		dest = Object{
 			ObjectAttrs: ObjectAttrs{
-				BucketName:  bucketName,
-				Name:        destinationName,
-				ContentType: contentType,
-				Created:     now,
-				Updated:     now,
+				BucketName:         bucketName,
+				Name:               destinationName,
+				ContentType:        contentType,
+				ContentDisposition: contentDisposition,
+				ContentLanguage:    contentLanguage,
+				Created:            now,
+				Updated:            now,
 			},
 		}
 	} else {
diff --git a/internal/backend/storage.go b/internal/backend/storage.go
index fd382ae..c428fcc 100644
--- a/internal/backend/storage.go
+++ b/internal/backend/storage.go
@@ -30,7 +30,7 @@ type Storage interface {
 	DeleteObject(bucketName, objectName string) error
 	PatchObject(bucketName, objectName string, attrsToUpdate ObjectAttrs) (StreamingObject, error)
 	UpdateObject(bucketName, objectName string, attrsToUpdate ObjectAttrs) (StreamingObject, error)
-	ComposeObject(bucketName string, objectNames []string, destinationName string, metadata map[string]string, contentType string) (StreamingObject, error)
+	ComposeObject(bucketName string, objectNames []string, destinationName string, metadata map[string]string, contentType string, contentDisposition string, contentLanguage string) (StreamingObject, error)
 	DeleteAllFiles() error
 }
 
diff --git a/internal/grpc/server.go b/internal/grpc/server.go
index 9283445..42df543 100644
--- a/internal/grpc/server.go
+++ b/internal/grpc/server.go
@@ -144,13 +144,13 @@ func (g *Server) PatchObject(ctx context.Context, req *pb.PatchObjectRequest) (*
 	return makeObject(obj), err
 }
 
-// ComposeObject(bucketName string, objectNames []string, destinationName string, metadata map[string]string, contentType string)
+// ComposeObject(bucketName string, objectNames []string, destinationName string, metadata map[string]string, contentType string, contentDisposition string, contentLanguage string)
 func (g *Server) ComposeObject(ctx context.Context, req *pb.ComposeObjectRequest) (*pb.Object, error) {
 	sourceObjNames := make([]string, 2)
 	for i := 0; i < len(req.SourceObjects); i++ {
 		sourceObjNames[i] = req.SourceObjects[i].Name
 	}
-	obj, err := g.backend.ComposeObject(req.DestinationBucket, sourceObjNames, req.DestinationObject, map[string]string{}, "")
+	obj, err := g.backend.ComposeObject(req.DestinationBucket, sourceObjNames, req.DestinationObject, map[string]string{}, "", "", "")
 	return makeObject(obj), err
 }
 


Test patch:
diff --git a/fakestorage/object_test.go b/fakestorage/object_test.go
index 59f7a8a..60fcd44 100644
--- a/fakestorage/object_test.go
+++ b/fakestorage/object_test.go
@@ -2123,10 +2123,12 @@ func TestParseRangeRequest(t *testing.T) {
 
 func TestServiceClientComposeObject(t *testing.T) {
 	const (
-		source1Content = "some content"
-		source2Content = "other content"
-		source3Content = "third test"
-		contentType    = "text/plain; charset=utf-8"
+		source1Content     = "some content"
+		source2Content     = "other content"
+		source3Content     = "third test"
+		contentDisposition = "attachment; filename=\"replaced.txt\""
+		contentLanguage    = "fr"
+		contentType        = "text/plain; charset=utf-8"
 	)
 	u32Checksum := uint32Checksum([]byte(source1Content))
 	hash := checksum.MD5Hash([]byte(source1Content))
@@ -2135,45 +2137,53 @@ func TestServiceClientComposeObject(t *testing.T) {
 	objs := []Object{
 		{
 			ObjectAttrs: ObjectAttrs{
-				BucketName:  "first-bucket",
-				Name:        "files/source1.txt",
-				ContentType: contentType,
-				Crc32c:      checksum.EncodedChecksum(uint32ToBytes(u32Checksum)),
-				Md5Hash:     checksum.EncodedHash(hash),
-				Metadata:    map[string]string{"foo": "bar"},
+				BucketName:         "first-bucket",
+				Name:               "files/source1.txt",
+				ContentDisposition: contentDisposition,
+				ContentLanguage:    contentLanguage,
+				ContentType:        contentType,
+				Crc32c:             checksum.EncodedChecksum(uint32ToBytes(u32Checksum)),
+				Md5Hash:            checksum.EncodedHash(hash),
+				Metadata:           map[string]string{"foo": "bar"},
 			},
 			Content: []byte(source1Content),
 		},
 		{
 			ObjectAttrs: ObjectAttrs{
-				BucketName:  "first-bucket",
-				Name:        "files/source2.txt",
-				ContentType: contentType,
-				Crc32c:      checksum.EncodedChecksum(uint32ToBytes(u32Checksum)),
-				Md5Hash:     checksum.EncodedHash(hash),
-				Metadata:    map[string]string{"foo": "bar"},
+				BucketName:         "first-bucket",
+				Name:               "files/source2.txt",
+				ContentDisposition: contentDisposition,
+				ContentLanguage:    contentLanguage,
+				ContentType:        contentType,
+				Crc32c:             checksum.EncodedChecksum(uint32ToBytes(u32Checksum)),
+				Md5Hash:            checksum.EncodedHash(hash),
+				Metadata:           map[string]string{"foo": "bar"},
 			},
 			Content: []byte(source2Content),
 		},
 		{
 			ObjectAttrs: ObjectAttrs{
-				BucketName:  "first-bucket",
-				Name:        "files/source3.txt",
-				ContentType: contentType,
-				Crc32c:      checksum.EncodedChecksum(uint32ToBytes(u32Checksum)),
-				Md5Hash:     checksum.EncodedHash(hash),
-				Metadata:    map[string]string{"foo": "bar"},
+				BucketName:         "first-bucket",
+				Name:               "files/source3.txt",
+				ContentDisposition: contentDisposition,
+				ContentLanguage:    contentLanguage,
+				ContentType:        contentType,
+				Crc32c:             checksum.EncodedChecksum(uint32ToBytes(u32Checksum)),
+				Md5Hash:            checksum.EncodedHash(hash),
+				Metadata:           map[string]string{"foo": "bar"},
 			},
 			Content: []byte(source3Content),
 		},
 		{
 			ObjectAttrs: ObjectAttrs{
-				BucketName:  "first-bucket",
-				Name:        "files/destination.txt",
-				ContentType: contentType,
-				Crc32c:      checksum.EncodedChecksum(uint32ToBytes(u32Checksum)),
-				Md5Hash:     checksum.EncodedHash(hash),
-				Metadata:    map[string]string{"foo": "bar"},
+				BucketName:         "first-bucket",
+				Name:               "files/destination.txt",
+				ContentDisposition: contentDisposition,
+				ContentLanguage:    contentLanguage,
+				ContentType:        contentType,
+				Crc32c:             checksum.EncodedChecksum(uint32ToBytes(u32Checksum)),
+				Md5Hash:            checksum.EncodedHash(hash),
+				Metadata:           map[string]string{"foo": "bar"},
 			},
 			Content: []byte("test"),
 		},
@@ -2236,6 +2246,8 @@ func TestServiceClientComposeObject(t *testing.T) {
 				dstObject := client.Bucket(test.bucketName).Object(test.destObjectName)
 				composer := dstObject.ComposerFrom(sourceObjects...)
 
+				composer.ContentDisposition = contentDisposition
+				composer.ContentLanguage = contentLanguage
 				composer.ContentType = contentType
 				composer.Metadata = map[string]string{"baz": "qux"}
 				attrs, err := composer.Run(context.TODO())
@@ -2261,6 +2273,12 @@ func TestServiceClientComposeObject(t *testing.T) {
 				if attrs.CRC32C != expectedChecksum {
 					t.Errorf("wrong checksum in compose object attrs\nwant %d\ngot  %d", u32Checksum, attrs.CRC32C)
 				}
+				if attrs.ContentDisposition != contentDisposition {
+					t.Errorf("wrong content disposition\nwant %q\ngot  %q", contentDisposition, attrs.ContentDisposition)
+				}
+				if attrs.ContentLanguage != contentLanguage {
+					t.Errorf("wrong content language\nwant %q\ngot  %q", contentLanguage, attrs.ContentLanguage)
+				}
 				if attrs.ContentType != contentType {
 					t.Errorf("wrong content type\nwant %q\ngot  %q", contentType, attrs.ContentType)
 				}
@@ -2286,6 +2304,12 @@ func TestServiceClientComposeObject(t *testing.T) {
 				if expect := checksum.EncodedHash(expectedHash); expect != obj.Md5Hash {
 					t.Errorf("wrong hash on object\nwant %s\ngot  %s", expect, obj.Md5Hash)
 				}
+				if obj.ContentDisposition != contentDisposition {
+					t.Errorf("wrong content disposition\nwant %q\ngot  %q", contentDisposition, obj.ContentDisposition)
+				}
+				if obj.ContentLanguage != contentLanguage {
+					t.Errorf("wrong content language\nwant %q\ngot  %q", contentLanguage, obj.ContentLanguage)
+				}
 				if obj.ContentType != contentType {
 					t.Errorf("wrong content type\nwant %q\ngot  %q", contentType, obj.ContentType)
 				}