From 89ee147961623b2515e29aa8a3e1b1c912c1e337 Mon Sep 17 00:00:00 2001 From: Aaron Liu <912394456@qq.com> Date: Thu, 25 May 2023 19:51:51 +0800 Subject: [PATCH] feat(upload): detect and specify mime type for files uploaded to S3 and OSS (fix#1681) --- pkg/filesystem/driver/s3/handler.go | 7 ++++--- pkg/filesystem/fsctx/stream.go | 16 +++++++++++++--- pkg/webdav/webdav.go | 2 +- service/explorer/file.go | 2 +- service/explorer/upload.go | 4 +++- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/pkg/filesystem/driver/s3/handler.go b/pkg/filesystem/driver/s3/handler.go index 819058d..56a7aaa 100644 --- a/pkg/filesystem/driver/s3/handler.go +++ b/pkg/filesystem/driver/s3/handler.go @@ -326,9 +326,10 @@ func (handler *Driver) Token(ctx context.Context, ttl int64, uploadSession *seri // 创建分片上传 expires := time.Now().Add(time.Duration(ttl) * time.Second) res, err := handler.svc.CreateMultipartUpload(&s3.CreateMultipartUploadInput{ - Bucket: &handler.Policy.BucketName, - Key: &fileInfo.SavePath, - Expires: &expires, + Bucket: &handler.Policy.BucketName, + Key: &fileInfo.SavePath, + Expires: &expires, + ContentType: aws.String(fileInfo.DetectMimeType()), }) if err != nil { return nil, fmt.Errorf("failed to create multipart upload: %w", err) diff --git a/pkg/filesystem/fsctx/stream.go b/pkg/filesystem/fsctx/stream.go index 4cf48e3..512270b 100644 --- a/pkg/filesystem/fsctx/stream.go +++ b/pkg/filesystem/fsctx/stream.go @@ -2,6 +2,7 @@ package fsctx import ( "errors" + "github.com/HFO4/aliyun-oss-go-sdk/oss" "io" "time" ) @@ -17,7 +18,7 @@ const ( type UploadTaskInfo struct { Size uint64 - MIMEType string + MimeType string FileName string VirtualPath string Mode WriteMode @@ -30,6 +31,15 @@ type UploadTaskInfo struct { Src string } +// Get mimetype of uploaded file, if it's not defined, detect it from file name +func (u *UploadTaskInfo) DetectMimeType() string { + if u.MimeType != "" { + return u.MimeType + } + + return oss.TypeByExtension(u.FileName) +} + // FileHeader 上传来的文件数据处理器 type FileHeader interface { io.Reader @@ -51,7 +61,7 @@ type FileStream struct { Size uint64 VirtualPath string Name string - MIMEType string + MimeType string SavePath string UploadSessionID *string AppendStart uint64 @@ -90,7 +100,7 @@ func (file *FileStream) Seekable() bool { func (file *FileStream) Info() *UploadTaskInfo { return &UploadTaskInfo{ Size: file.Size, - MIMEType: file.MIMEType, + MimeType: file.MimeType, FileName: file.Name, VirtualPath: file.VirtualPath, Mode: file.Mode, diff --git a/pkg/webdav/webdav.go b/pkg/webdav/webdav.go index 054bced..9b2ff1b 100644 --- a/pkg/webdav/webdav.go +++ b/pkg/webdav/webdav.go @@ -345,7 +345,7 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request, fs *filesyst fileName := path.Base(reqPath) filePath := path.Dir(reqPath) fileData := fsctx.FileStream{ - MIMEType: r.Header.Get("Content-Type"), + MimeType: r.Header.Get("Content-Type"), File: r.Body, Size: fileSize, Name: fileName, diff --git a/service/explorer/file.go b/service/explorer/file.go index 287a582..0fa1b8e 100644 --- a/service/explorer/file.go +++ b/service/explorer/file.go @@ -408,7 +408,7 @@ func (service *FileIDService) PutContent(ctx context.Context, c *gin.Context) se } fileData := fsctx.FileStream{ - MIMEType: c.Request.Header.Get("Content-Type"), + MimeType: c.Request.Header.Get("Content-Type"), File: c.Request.Body, Size: fileSize, Mode: fsctx.Overwrite, diff --git a/service/explorer/upload.go b/service/explorer/upload.go index d14f328..0c26c26 100644 --- a/service/explorer/upload.go +++ b/service/explorer/upload.go @@ -26,6 +26,7 @@ type CreateUploadSessionService struct { Name string `json:"name" binding:"required"` PolicyID string `json:"policy_id" binding:"required"` LastModified int64 `json:"last_modified"` + MimeType string `json:"mime_type"` } // Create 创建新的上传会话 @@ -51,6 +52,7 @@ func (service *CreateUploadSessionService) Create(ctx context.Context, c *gin.Co Name: service.Name, VirtualPath: service.Path, File: ioutil.NopCloser(strings.NewReader("")), + MimeType: service.MimeType, } if service.LastModified > 0 { lastModified := time.UnixMilli(service.LastModified) @@ -174,7 +176,7 @@ func processChunkUpload(ctx context.Context, c *gin.Context, fs *filesystem.File } fileData := fsctx.FileStream{ - MIMEType: c.Request.Header.Get("Content-Type"), + MimeType: c.Request.Header.Get("Content-Type"), File: c.Request.Body, Size: fileSize, Name: session.Name,