@@ -23,7 +23,7 @@ import (
2323 "github.com/OpenListTeam/OpenList/v4/internal/stream"
2424 "github.com/OpenListTeam/OpenList/v4/pkg/http_range"
2525 "github.com/OpenListTeam/OpenList/v4/pkg/utils"
26- "github.com/itsHenry35 /gofakes3"
26+ "github.com/OpenListTeam /gofakes3"
2727 "github.com/ncw/swift/v2"
2828 log "github.com/sirupsen/logrus"
2929)
@@ -33,19 +33,25 @@ var (
3333 timeFormat = "Mon, 2 Jan 2006 15:04:05 GMT"
3434)
3535
36- // s3Backend implements the gofacess3.Backend interface to make an S3
37- // backend for gofakes3
36+ // s3Backend implements the gofakes3.Backend interface to make an S3
37+ // backend for gofakes3. It also implements gofakes3.MultipartBackend so that
38+ // multipart uploads are streamed to local temp files part-by-part and
39+ // assembled into storage on completion, instead of being buffered in memory.
3840type s3Backend struct {
3941 meta * sync.Map
4042 listDir func (context.Context , string ) ([]model.Obj , error )
43+ uploads * sync.Map // map[gofakes3.UploadID]*multipartState
4144}
4245
4346// newBackend creates a new SimpleBucketBackend.
4447func newBackend () gofakes3.Backend {
45- return & s3Backend {
48+ b := & s3Backend {
4649 meta : new (sync.Map ),
50+ uploads : new (sync.Map ),
4751 listDir : getDirEntries ,
4852 }
53+ b .startReaper ()
54+ return b
4955}
5056
5157// ListBuckets always returns the default bucket.
@@ -233,9 +239,20 @@ func (b *s3Backend) PutObject(
233239 meta map [string ]string ,
234240 input io.Reader , size int64 ,
235241) (result gofakes3.PutObjectResult , err error ) {
242+ return result , b .putStream (ctx , bucketName , objectName , meta , input , size )
243+ }
244+
245+ // putStream stores the given object into the underlying storage. It is shared
246+ // by PutObject and the multipart-upload Complete step so both paths apply the
247+ // same directory creation, metadata and ignore rules.
248+ func (b * s3Backend ) putStream (
249+ ctx context.Context , bucketName , objectName string ,
250+ meta map [string ]string ,
251+ input io.Reader , size int64 ,
252+ ) error {
236253 bucket , err := getBucketByName (bucketName )
237254 if err != nil {
238- return result , err
255+ return err
239256 }
240257 bucketPath := bucket .Path
241258
@@ -261,15 +278,15 @@ func (b *s3Backend) PutObject(
261278 log .Debugf ("reqPath: %s not found and objectName contains /, need to makeDir" , reqPath )
262279 err = fs .MakeDir (ctx , reqPath )
263280 if err != nil {
264- return result , errors .WithMessagef (err , "failed to makeDir, reqPath: %s" , reqPath )
281+ return errors .WithMessagef (err , "failed to makeDir, reqPath: %s" , reqPath )
265282 }
266283 } else {
267- return result , gofakes3 .KeyNotFound (objectName )
284+ return gofakes3 .KeyNotFound (objectName )
268285 }
269286 }
270287
271288 if isDir {
272- return result , nil
289+ return nil
273290 }
274291
275292 var ti time.Time
@@ -295,7 +312,7 @@ func (b *s3Backend) PutObject(
295312 }
296313 // Check if system file should be ignored
297314 if setting .GetBool (conf .IgnoreSystemFiles ) && utils .IsSystemFile (obj .Name ) {
298- return result , errs .IgnoredSystemFile
315+ return errs .IgnoredSystemFile
299316 }
300317 stream := & stream.FileStream {
301318 Obj : & obj ,
@@ -305,18 +322,12 @@ func (b *s3Backend) PutObject(
305322
306323 err = fs .PutDirectly (ctx , reqPath , stream )
307324 if err != nil {
308- return result , err
325+ return err
309326 }
310327
311- // if err := stream.Close(); err != nil {
312- // // remove file when close error occurred (FsPutErr)
313- // _ = fs.Remove(ctx, fp)
314- // return result, err
315- // }
316-
317328 b .meta .Store (fp , meta )
318329
319- return result , nil
330+ return nil
320331}
321332
322333// DeleteMulti deletes multiple objects in a single request.
0 commit comments