mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2026-10-10 13:03:09 +08:00
fix(drivers/s3): sign content-type for direct uploads (#3152)
* fix(s3): sign content type for direct uploads - Include the inferred MIME type in presigned PutObject requests - Return the signed Content-Type header for frontend uploads Co-authored-by: Codex <267193182+codex@users.noreply.github.com> * fix(drivers/s3): use client content type for direct uploads - Accept and validate the client-provided direct upload media type - Pass the type to the S3 signer through a typed context key - Default missing types to application/octet-stream Co-authored-by: Codex <267193182+codex@users.noreply.github.com> --------- Co-authored-by: Codex <267193182+codex@users.noreply.github.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/conf"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/driver"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/errs"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
@@ -229,9 +230,14 @@ func (d *S3) GetDirectUploadInfo(ctx context.Context, _ string, dstDir model.Obj
|
||||
return nil, errs.NotImplement
|
||||
}
|
||||
path := getKey(stdpath.Join(dstDir.GetPath(), fileName), false)
|
||||
contentType, _ := ctx.Value(conf.DirectUploadContentTypeKey).(string)
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
req, _ := d.directUploadClient.PutObjectRequest(&s3.PutObjectInput{
|
||||
Bucket: &d.Bucket,
|
||||
Key: &path,
|
||||
Bucket: &d.Bucket,
|
||||
Key: &path,
|
||||
ContentType: &contentType,
|
||||
})
|
||||
if req == nil {
|
||||
return nil, fmt.Errorf("failed to create PutObject request")
|
||||
@@ -243,6 +249,7 @@ func (d *S3) GetDirectUploadInfo(ctx context.Context, _ string, dstDir model.Obj
|
||||
return &model.HttpDirectUploadInfo{
|
||||
UploadURL: link,
|
||||
Method: "PUT",
|
||||
Headers: map[string]string{"Content-Type": contentType},
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -197,4 +197,5 @@ const (
|
||||
PathKey
|
||||
SharingIDKey
|
||||
SkipHookKey
|
||||
DirectUploadContentTypeKey
|
||||
)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package handles
|
||||
|
||||
import (
|
||||
"context"
|
||||
"mime"
|
||||
"net/url"
|
||||
stdpath "path"
|
||||
|
||||
@@ -15,10 +17,11 @@ import (
|
||||
)
|
||||
|
||||
type FsGetDirectUploadInfoReq struct {
|
||||
Path string `json:"path" form:"path"`
|
||||
FileName string `json:"file_name" form:"file_name"`
|
||||
FileSize int64 `json:"file_size" form:"file_size"`
|
||||
Tool string `json:"tool" form:"tool"`
|
||||
Path string `json:"path" form:"path"`
|
||||
FileName string `json:"file_name" form:"file_name"`
|
||||
FileSize int64 `json:"file_size" form:"file_size"`
|
||||
ContentType string `json:"content_type" form:"content_type"`
|
||||
Tool string `json:"tool" form:"tool"`
|
||||
}
|
||||
|
||||
// FsGetDirectUploadInfo returns the direct upload info if supported by the driver
|
||||
@@ -91,7 +94,14 @@ func FsGetDirectUploadInfo(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
directUploadInfo, err := fs.GetDirectUploadInfo(c, req.Tool, path, req.FileName, req.FileSize, overwrite)
|
||||
if req.ContentType != "" {
|
||||
if _, _, err := mime.ParseMediaType(req.ContentType); err != nil {
|
||||
common.ErrorResp(c, err, 400)
|
||||
return
|
||||
}
|
||||
}
|
||||
ctx := context.WithValue(c, conf.DirectUploadContentTypeKey, req.ContentType)
|
||||
directUploadInfo, err := fs.GetDirectUploadInfo(ctx, req.Tool, path, req.FileName, req.FileSize, overwrite)
|
||||
if err != nil {
|
||||
if !overwrite && errs.IsObjectAlreadyExists(err) {
|
||||
common.ErrorStrResp(c, "file exists", 403)
|
||||
|
||||
Reference in New Issue
Block a user