mirror of https://github.com/cloudreve/Cloudreve
				
				
				
			feat(upload): detect and specify mime type for files uploaded to S3 and OSS (fix#1681)
							parent
							
								
									4aafe1dc7a
								
							
						
					
					
						commit
						89ee147961
					
				| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue