@@ -6,6 +6,7 @@ package storage
6
6
import (
7
7
"context"
8
8
"crypto/tls"
9
+ "fmt"
9
10
"io"
10
11
"net/http"
11
12
"net/url"
@@ -52,10 +53,12 @@ type MinioStorageConfig struct {
52
53
BasePath string `ini:"MINIO_BASE_PATH"`
53
54
UseSSL bool `ini:"MINIO_USE_SSL"`
54
55
InsecureSkipVerify bool `ini:"MINIO_INSECURE_SKIP_VERIFY"`
56
+ ChecksumAlgorithm string `ini:"MINIO_CHECKSUM_ALGORITHM"`
55
57
}
56
58
57
59
// MinioStorage returns a minio bucket storage
58
60
type MinioStorage struct {
61
+ cfg * MinioStorageConfig
59
62
ctx context.Context
60
63
client * minio.Client
61
64
bucket string
@@ -90,6 +93,10 @@ func NewMinioStorage(ctx context.Context, cfg interface{}) (ObjectStorage, error
90
93
}
91
94
config := configInterface .(MinioStorageConfig )
92
95
96
+ if config .ChecksumAlgorithm != "" && config .ChecksumAlgorithm != "default" && config .ChecksumAlgorithm != "md5" {
97
+ return nil , fmt .Errorf ("invalid minio checksum algorithm: %s" , config .ChecksumAlgorithm )
98
+ }
99
+
93
100
log .Info ("Creating Minio storage at %s:%s with base path %s" , config .Endpoint , config .Bucket , config .BasePath )
94
101
95
102
minioClient , err := minio .New (config .Endpoint , & minio.Options {
@@ -112,6 +119,7 @@ func NewMinioStorage(ctx context.Context, cfg interface{}) (ObjectStorage, error
112
119
}
113
120
114
121
return & MinioStorage {
122
+ cfg : & config ,
115
123
ctx : ctx ,
116
124
client : minioClient ,
117
125
bucket : config .Bucket ,
@@ -123,7 +131,7 @@ func (m *MinioStorage) buildMinioPath(p string) string {
123
131
return strings .TrimPrefix (path .Join (m .basePath , path .Clean ("/" + strings .ReplaceAll (p , "\\ " , "/" ))[1 :]), "/" )
124
132
}
125
133
126
- // Open open a file
134
+ // Open opens a file
127
135
func (m * MinioStorage ) Open (path string ) (Object , error ) {
128
136
opts := minio.GetObjectOptions {}
129
137
object , err := m .client .GetObject (m .ctx , m .bucket , m .buildMinioPath (path ), opts )
@@ -133,15 +141,22 @@ func (m *MinioStorage) Open(path string) (Object, error) {
133
141
return & minioObject {object }, nil
134
142
}
135
143
136
- // Save save a file to minio
144
+ // Save saves a file to minio
137
145
func (m * MinioStorage ) Save (path string , r io.Reader , size int64 ) (int64 , error ) {
138
146
uploadInfo , err := m .client .PutObject (
139
147
m .ctx ,
140
148
m .bucket ,
141
149
m .buildMinioPath (path ),
142
150
r ,
143
151
size ,
144
- minio.PutObjectOptions {ContentType : "application/octet-stream" },
152
+ minio.PutObjectOptions {
153
+ ContentType : "application/octet-stream" ,
154
+ // some storages like:
155
+ // * https://developers.cloudflare.com/r2/api/s3/api/
156
+ // * https://www.backblaze.com/b2/docs/s3_compatible_api.html
157
+ // do not support "x-amz-checksum-algorithm" header, so use legacy MD5 checksum
158
+ SendContentMd5 : m .cfg .ChecksumAlgorithm == "md5" ,
159
+ },
145
160
)
146
161
if err != nil {
147
162
return 0 , convertMinioErr (err )
0 commit comments