fix(drivers/s3): sign content-type for direct uploads - #3152
mumingluan wants to merge 2 commits into
Conversation
- 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>
|
@mumingluan Have you tested other S3 backends? |
Only Ceph encountered this issue. |
| return nil, errs.NotImplement | ||
| } | ||
| path := getKey(stdpath.Join(dstDir.GetPath(), fileName), false) | ||
| contentType := utils.GetMimeType(fileName) |
There was a problem hiding this comment.
I don't think getting Content-Type from the filename is a good idea. The browser's implementation may differ from the Go backend.
There was a problem hiding this comment.
Thanks for the feedback. Updated this PR to use the browser-provided MIME type, with the companion frontend change in OpenListTeam/OpenList-Frontend#692.
The frontend sends file.type || "application/octet-stream" as content_type. The backend validates and signs that value, then returns the matching upload header. Existing clients that omit the field use application/octet-stream.
I verified the revised driver against Rainyun/Ceph and Cloudflare R2 with supplied MIME types that differ from the filename extensions, including a successful 80 MiB Rainyun upload using the fallback. Object sizes were verified and the temporary objects were deleted.
- 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>
Summary / 摘要
S3 browser uploads can fail with
403 AccessDeniedon Ceph RGW when the request carries an unsignedContent-Type. The frontend sendsfile.type || "application/octet-stream"in a new optionalcontent_typefield on the direct-upload information request.The backend validates the supplied media type, passes it to the driver through a typed context key, signs it in the S3
PutObjectURL, and returns the same value in the existing upload headers. Missing types fall back toapplication/octet-stream, preserving compatibility with existing clients.Adds an optional request field and populates the existing optional response headers.
A companion frontend change supplies the browser's MIME type.
Related repository PRs / 关联仓库 PR:
Testing / 测试
go test ./drivers/s3 ./internal/conf -count=1passed.TestIsSearchNodeAccessible/outside_base_path. The same failure was reproduced at the original branch HEAD.git diff --checkpassed..apkcarryingtext/plainand a file with an empty type send the expectedcontent_typeand matching upload header..apkusing the client-suppliedtext/plainand a.jpgusingapplication/pdfuploaded successfully. Missing MIME type usedapplication/octet-stream, and an 80 MiB Rainyun upload succeeded. Object sizes were verified and temporary objects were deleted.Checklist / 检查清单
AI Disclosure / AI 使用声明
This revision includes AI-assisted content.
Tool: Codex.
Scope: implementation, validation, and PR wording.
The human collaborator requested this revision in response to maintainer feedback. Codex performed the checks described above; the human collaborator reviewed the proposed changes and approved submission.
AI-assisted commits include the required
Co-authored-byattribution.