Files
FileShare/docs/api/06-presign.md
T
SKYMirror 84df9996cb
CI 测试 / go vet + go test (push) Successful in 49s
26.9:版本号统一 + CI 精简 + 前端产物重建
- 全项目版本号统一:v3.x 迭代号(26.9/26.9/26.9/26.9 及裸 v2/v3)→ 26.9,
  覆盖 Go 注释 / 文档 / openapi.yaml / README×4 / 前端源码(80+ 处)
- v31_test.go 更名 custom_code_test.go;TestV2AccessorDefaults → TestKVAccessorDefaults
- docs/api/00-overview.md 更新日志合并为单条 26.9 条目(修复错位拼接)
- .goreleaser.yaml 头部注释与实际一致(Pro 2.18.1 / GITEA_TOKEN / semver tag 要求)
- CI:release-image.yml → ci.yml,仅保留 vet+test 门禁;
  镜像发布移交 GoReleaser Pro(原 build-push 的 tag 校验与 26.9 版本方案冲突,历史 9 次失败)
- 前端重建:server/web/dist 与 web-embed 同步(docs 文案嵌入更新)
2026-09-08 03:16:51 +08:00

5.9 KiB
Raw Blame History

预签名直传

服务端预生成上传地址,客户端直接向存储引擎(或服务端代理)上传文件,最后确认建分享。 两种模式:

模式 引擎 上传方式
direct S3(含 MinIO/R2 等 S3 兼容存储) 客户端 PUT 到预签名 URL,直连对象存储
proxy 本地 / WebDAV 客户端 PUT multipart 到服务端代理接口

本地 / WebDAV 引擎不支持预签名直链,init 返回正常 proxy 模式(仅当引擎预签名调用本身异常时才报错)。 会话有效期 900 秒(15 分钟)。proxy 模式响应另含 legacy_proxy_upload_url /api 前缀的兼容别名,已废弃,与 upload_url 等价)。 全部端点经审计中间件落库(action=upload)。

上传流程

direct 模式:
POST /presign/upload/init            → upload_urlS3 预签名 PUT
PUT  <upload_url>                    → 客户端直传 S3(无认证头)
POST /presign/upload/confirm/{id}    → 确认 → 取件码

proxy 模式:
POST /presign/upload/init            → upload_url = /presign/upload/proxy/{id}
PUT  /presign/upload/proxy/{id}      → multipart 上传,服务端转存并直接建分享

初始化:POST /presign/upload/init

请求体JSON,亦兼容表单):

参数 类型 必需 默认 说明
file_name string - 文件名(清理 + 白名单校验)
file_size int - 文件字节数(≤ 生效上限:max_file_size>0 时为其,否则 uploadSize
expire_value int 1 过期值(count 型受 max_save_count 约束)
expire_style string day 过期方式(须在 expireStyle 白名单内)

curl 示例

curl -s -X POST http://localhost:8466/presign/upload/init \
  -H 'Content-Type: application/json' \
  -d '{"file_name":"backup.zip","file_size":20971520,"expire_value":7,"expire_style":"day"}'

S3direct)成功响应200):

{
  "code": 200, "msg": "ok",
  "data": {
    "upload_id": "6a1e…",
    "upload_url": "https://minio:9000/fileshare/share/data/2025/06/01/6a1e…/backup.zip?X-Amz-…",
    "mode": "direct",
    "expires_in": 900,
    "file_path": "share/data/2025/06/01/6a1e…"
  }
}

local/WebDAVproxy)成功响应200):

{
  "code": 200, "msg": "ok",
  "data": {
    "upload_id": "6a1e…",
    "upload_url": "/presign/upload/proxy/6a1e…",
    "proxy_upload_url": "/presign/upload/proxy/6a1e…",
    "mode": "proxy",
    "expires_in": 900,
    "file_path": "share/data/2025/06/01/6a1e…"
  }
}

错误响应

{ "code": 403, "msg": "大小超过限制,最大为10.00 MB" }

大小上限为动态策略(26.9 需求 ④⑩):管理端改 max_file_size0=回落 uploadSize)后 立即按新上限校验 init 声明的 file_size

{ "code": 403, "msg": "不允许上传该类型文件" }
{ "code": 507, "msg": "存储空间已达到管理员设置的容量上限" }

直传确认:POST /presign/upload/confirm/{uploadID}

direct 模式专用:客户端向 S3 PUT 完成后调用。服务端会核对实际对象(多引擎一致):

  • 大小核对:实际大小与声明差 >1KB → 400「文件大小与声明不符」;超过策略上限(max_file_size)→ 删除对象、释放容量预留并 403
  • 内容校验:取对象前 64 字节做 magic bytes 白名单校验(失败删除对象并报错);
  • 全部通过后创建分享记录。
# 1) 直传 S3(注意:不要带 Authorization 头,预签名 URL 自带鉴权)
curl -X PUT "<data.upload_url>" --upload-file ./backup.zip
# 2) 确认
curl -s -X POST http://localhost:8466/presign/upload/confirm/6a1e…

成功响应200):

{ "code": 200, "msg": "ok", "data": { "code": "B4N8Q", "name": "backup.zip" } }

错误响应

{ "code": 404, "msg": "文件未上传或上传失败" }
{ "code": 400, "msg": "文件大小与声明不符" }
{ "code": 403, "msg": "文件大小超过限制" }
{ "code": 400, "msg": "此会话不支持direct模式" }

代理上传:PUT /presign/upload/proxy/{uploadID}

proxy 模式专用:multipart 上传到服务端,服务端流式转存到存储引擎后立即创建分享记录。

multipart 字段file(必需)。

curl 示例

curl -s -X PUT http://localhost:8466/presign/upload/proxy/6a1e… -F 'file=@./backup.zip'

成功响应200):

{ "code": 200, "msg": "ok", "data": { "code": "B4N8Q", "name": "backup.zip" } }

错误响应

{ "code": 400, "msg": "缺少上传文件 file 字段" }
{ "code": 400, "msg": "文件大小与声明不符" }
{ "code": 403, "msg": "大小超过限制,最大为10.00 MB" }

文件实际大小须与 init 声明的 file_size 一致(±1KB 容差);成功后会话即删除,不可重复使用。

查询会话:GET /presign/upload/status/{uploadID}

curl -s http://localhost:8466/presign/upload/status/6a1e…

成功响应200):

{
  "code": 200, "msg": "ok",
  "data": {
    "upload_id": "6a1e…",
    "file_name": "backup.zip",
    "file_size": 20971520,
    "mode": "proxy",
    "created_at": "2025-06-01T12:00:00+08:00",
    "expires_at": "2025-06-01T12:15:00+08:00",
    "is_expired": false
  }
}

取消会话:DELETE /presign/upload/{uploadID}

删除会话并释放容量预留;direct 模式会尽力清理已直传到 S3 的对象。

curl -s -X DELETE http://localhost:8466/presign/upload/6a1e…
{ "code": 200, "msg": "ok", "data": { "message": "上传会话已取消" } }
{ "code": 404, "msg": "上传会话不存在" }
{ "code": 404, "msg": "上传会话已过期" }