From ec931c6183d5a610f193299b4da7d87d29f3abb2 Mon Sep 17 00:00:00 2001 From: Michael Li Date: Tue, 2 Jan 2024 21:22:16 +0800 Subject: [PATCH] optimize upload attachment logic --- internal/servants/web/priv.go | 7 ++++++- pkg/types/io.go | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 pkg/types/io.go diff --git a/internal/servants/web/priv.go b/internal/servants/web/priv.go index 5852dbcd..d426448a 100644 --- a/internal/servants/web/priv.go +++ b/internal/servants/web/priv.go @@ -22,6 +22,7 @@ import ( "github.com/rocboss/paopao-ce/internal/model/web" "github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/chain" + "github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/utils" "github.com/rocboss/paopao-ce/pkg/xerror" "github.com/sirupsen/logrus" @@ -141,7 +142,11 @@ func (s *privSrv) UploadAttachment(req *web.UploadAttachmentReq) (*web.UploadAtt // 生成随机路径 randomPath := uuid.Must(uuid.NewV4()).String() ossSavePath := req.UploadType + "/" + generatePath(randomPath[:8]) + "/" + randomPath[9:] + req.FileExt - objectUrl, err := s.oss.PutObject(ossSavePath, req.File, req.FileSize, req.ContentType, false) + // NOTE: 注意这里将req.File Wrap到一个io.Reader的实例对象中是为了避免下游接口去主动调Close,req.File本身是实现了 + // io.Closer接口的,有的下游接口会断言传参是否实现了io.Closer接口,如果实现了会主动去调,我们这里因为下文中可能还要继续 + // 使用req.File所以应避免下游Close,否则会出现潜在的bug,比如这里的场景就是传一个超大的图片(>10MB)可能就会触发bug了。 + data := types.PureReader(req.File) + objectUrl, err := s.oss.PutObject(ossSavePath, data, req.FileSize, req.ContentType, false) if err != nil { logrus.Errorf("oss.putObject err: %s", err) return nil, web.ErrFileUploadFailed diff --git a/pkg/types/io.go b/pkg/types/io.go new file mode 100644 index 00000000..c662e45e --- /dev/null +++ b/pkg/types/io.go @@ -0,0 +1,24 @@ +// Copyright 2024 ROC. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package types + +import ( + "io" +) + +type readerWrap struct { + r io.Reader +} + +func (rw *readerWrap) Read(p []byte) (n int, err error) { + return rw.r.Read(p) +} + +// PureReader wrap a pure io.Reader object +func PureReader(r io.Reader) io.Reader { + return &readerWrap{ + r: r, + } +}