@@ -6,6 +6,7 @@ package storage
66import (
77 "context"
88 "crypto/tls"
9+ "fmt"
910 "io"
1011 "net/http"
1112 "net/url"
@@ -53,10 +54,12 @@ type MinioStorageConfig struct {
5354 BasePath string `ini:"MINIO_BASE_PATH"`
5455 UseSSL bool `ini:"MINIO_USE_SSL"`
5556 InsecureSkipVerify bool `ini:"MINIO_INSECURE_SKIP_VERIFY"`
57+ ChecksumAlgorithm string `ini:"MINIO_CHECKSUM_ALGORITHM"`
5658}
5759
5860// MinioStorage returns a minio bucket storage
5961type MinioStorage struct {
62+ cfg * MinioStorageConfig
6063 ctx context.Context
6164 client * minio.Client
6265 bucket string
@@ -91,6 +94,10 @@ func NewMinioStorage(ctx context.Context, cfg interface{}) (ObjectStorage, error
9194 }
9295 config := configInterface .(MinioStorageConfig )
9396
97+ if config .ChecksumAlgorithm != "" && config .ChecksumAlgorithm != "default" && config .ChecksumAlgorithm != "md5" {
98+ return nil , fmt .Errorf ("invalid minio checksum algorithm: %s" , config .ChecksumAlgorithm )
99+ }
100+
94101 log .Info ("Creating Minio storage at %s:%s with base path %s" , config .Endpoint , config .Bucket , config .BasePath )
95102
96103 minioClient , err := minio .New (config .Endpoint , & minio.Options {
@@ -113,6 +120,7 @@ func NewMinioStorage(ctx context.Context, cfg interface{}) (ObjectStorage, error
113120 }
114121
115122 return & MinioStorage {
123+ cfg : & config ,
116124 ctx : ctx ,
117125 client : minioClient ,
118126 bucket : config .Bucket ,
@@ -124,7 +132,7 @@ func (m *MinioStorage) buildMinioPath(p string) string {
124132 return util .PathJoinRelX (m .basePath , p )
125133}
126134
127- // Open open a file
135+ // Open opens a file
128136func (m * MinioStorage ) Open (path string ) (Object , error ) {
129137 opts := minio.GetObjectOptions {}
130138 object , err := m .client .GetObject (m .ctx , m .bucket , m .buildMinioPath (path ), opts )
@@ -134,15 +142,22 @@ func (m *MinioStorage) Open(path string) (Object, error) {
134142 return & minioObject {object }, nil
135143}
136144
137- // Save save a file to minio
145+ // Save saves a file to minio
138146func (m * MinioStorage ) Save (path string , r io.Reader , size int64 ) (int64 , error ) {
139147 uploadInfo , err := m .client .PutObject (
140148 m .ctx ,
141149 m .bucket ,
142150 m .buildMinioPath (path ),
143151 r ,
144152 size ,
145- minio.PutObjectOptions {ContentType : "application/octet-stream" },
153+ minio.PutObjectOptions {
154+ ContentType : "application/octet-stream" ,
155+ // some storages like:
156+ // * https://developers.cloudflare.com/r2/api/s3/api/
157+ // * https://www.backblaze.com/b2/docs/s3_compatible_api.html
158+ // do not support "x-amz-checksum-algorithm" header, so use legacy MD5 checksum
159+ SendContentMd5 : m .cfg .ChecksumAlgorithm == "md5" ,
160+ },
146161 )
147162 if err != nil {
148163 return 0 , convertMinioErr (err )
0 commit comments