Files
FileShare/docs/api/04-pickup.md
T
SKYMirror 7f060dd0e4 26.9(安全审计修复版)
Go 1.27.1 (Gin+GORM) + Vue 3 文件快传服务:

- 安全审计全部修复(docs/security-audit-2026-09-05.md):
  bcrypt 密码哈希与自动升级、presign 直传服务端大小/内容校验、
  全局请求体上限、依赖升级(govulncheck 0 命中)、janitor 后台清理、
  管理端审计动作落库、/admin CORS 收紧、通知内容白名单净化、
  会话默认 7 天、限流缓存故障降级、robots.txt 端点等
- 前端:取件链接复制修复(不再重复拼接提取码)、markdown 净化器加固
- Redis 支持库号(FCB_REDIS_DB / redis://…/db URL)
- 文档:docs/api/* 与 openapi.yaml 同步最新行为(robots.txt、
  提码 5 位起、chunk 32MiB 上限、admin 审计动作等)

验证:gofmt/go vet/go test 全绿;二进制端到端冒烟通过
2026-09-05 04:22:41 +08:00

4.6 KiB
Raw Blame History

分享查询与取件

查询分享元信息(不消耗次数)与真正取件(消耗次数)的完整接口。 除 metadata 每次 423 限流计数外,取件失败还会计入 error 限流。

元信息:GET /share/metadata

按取件码查询元信息,不消耗次数。每次访问即计入 metadata 限流。

参数codequery,必需)。

curl -s "http://localhost:8466/share/metadata?code=K3P9W"

成功响应200):

{
  "code": 200, "msg": "ok",
  "data": {
    "code": "K3P9W",
    "name": "report.pdf",
    "size": 1048576,
    "type": "file",
    "is_text": false,
    "created_at": "2025-06-01T12:00:00+08:00",
    "expired_at": "2025-06-08T12:00:00+08:00",
    "expires_at": "2025-06-08T12:00:00+08:00",
    "expired_count": -1,
    "used_count": 3,
    "remaining_downloads": null
  }
}

字段说明:

字段 说明
type text(文本分享)/ file(文件分享)
is_text 是否文本分享
size 字节数
expired_at / expires_at 过期时间(RFC 3339);永久分享为 null
expired_count -1 按时间/永久;>0 剩余可取次数(原始限额)
used_count 已取次数
remaining_downloads 剩余可取次数(仅次数型分享有值,否则 null

不返回存储路径等敏感字段。

错误响应

{ "code": 404, "msg": "文件不存在" }
{ "code": 404, "msg": "文件已过期" }

元信息(POST):POST /share/metadata

等价的 JSON 版本(code 放请求体):

curl -s -X POST http://localhost:8466/share/metadata \
  -H 'Content-Type: application/json' \
  -d '{"code":"K3P9W"}'

响应与 GET 版本一致。

取件(消耗次数):GET /share/select

每调用一次消耗 1 次取件(次数型分享扣减 expired_count;时间型扣减不计)。

  • 文本分享:返回 text/plain; charset=utf-8 正文(非 JSON 封装),Content-Disposition 携带文件名。
  • 文件分享:返回文件流(200 全量 / 206 区间),支持 Range
curl -s -OJ "http://localhost:8466/share/select?code=K3P9W"

次数耗尽或已过期:

{ "code": 404, "msg": "文件已过期" }

超限(计入 error 限流):

{ "code": 423, "msg": "请求次数过多,请稍后再试" }

取件详情:POST /share/select

返回元信息 + 文本内容/下载地址的 JSON 详情。消耗语义:次数型分享(expired_count >= 0 返回代理地址 download_url 且本次不消耗(消耗发生在访问代理地址时);时间型/永久/文本分享在本次消耗。

curl -s -X POST http://localhost:8466/share/select \
  -H 'Content-Type: application/json' \
  -d '{"code":"K3P9W"}'

文件分享响应200):

{
  "code": 200, "msg": "ok",
  "data": {
    "code": "K3P9W",
    "name": "report.pdf",
    "size": 1048576,
    "type": "file",
    "is_text": false,
    "created_at": "2025-06-01T12:00:00+08:00",
    "expired_at": "2025-06-08T12:00:00+08:00",
    "expires_at": "2025-06-08T12:00:00+08:00",
    "expired_count": -1,
    "used_count": 4,
    "remaining_downloads": null,
    "text": "/share/download?key=9f2c…&code=K3P9W",
    "download_url": "/share/download?key=9f2c…&code=K3P9W"
  }
}

S3 引擎下时间型/永久分享的 download_url 可能是预签名直链(1 小时有效)而非代理地址; 次数型分享恒为代理地址 "/share/download?key=…&code=…"

文本分享响应200):

{
  "code": 200, "msg": "ok",
  "data": {
    "code": "8XQ2M", "name": "Text.txt", "size": 24, "type": "text", "is_text": true,
    "created_at": "2025-06-01T12:00:00+08:00",
    "expired_at": "2025-06-02T12:00:00+08:00", "expires_at": "2025-06-02T12:00:00+08:00",
    "expired_count": -1, "used_count": 1, "remaining_downloads": null,
    "text": "你好,文件快传",
    "content": "你好,文件快传",
    "download_url": null
  }
}

代理下载:GET /share/download

POST /share/select 返回的代理地址,每次访问消耗 1 次,支持 Range。

参数 说明
key 窗口令牌(服务端下发,双窗口校验)
code 取件码
curl -s -OJ "http://localhost:8466/share/download?key=9f2c…&code=K3P9W"

错误响应

{ "code": 403, "msg": "下载鉴权失败" }
{ "code": 404, "msg": "文件已过期" }

key 鉴权失败会计入 error 限流;文本分享经该接口返回 JSON 封装 data 为文本内容。