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 全绿;二进制端到端冒烟通过
6.0 KiB
分片上传
大文件分片上传:客户端把文件切成固定大小的分片逐个上传,服务端按索引合并并做 SHA256 校验。
支持断点续传(相同 file_hash + 大小 + 文件名的未完成会话自动续传)。
需站点开启 enableChunk(公共配置 enableChunk 返回 true)。
分片会话保留 24 小时。全部端点经审计中间件落库(action=upload)。
上传流程
POST /chunk/upload/init → upload_id, total_chunks
POST /chunk/upload/{id}/{index} → 逐片上传(0 起,可并发)
GET /chunk/upload/status/{id} → 断点续传时查进度
POST /chunk/upload/complete/{id} → 合并 + SHA256 → 取件码
DELETE /chunk/upload/{id} → 取消(可选)
初始化:POST /chunk/upload/init
请求体(JSON,亦兼容表单):
| 参数 | 类型 | 必需 | 默认 | 说明 |
|---|---|---|---|---|
file_name |
string | ✅ | - | 文件名(会做清理与白名单校验) |
file_size |
int | ✅ | - | 文件总字节数(>0;服务端按分片数校验上限) |
chunk_size |
int | ❌ | 5242880(5MB) |
每片大小(字节),硬上限 32MiB(超出 400「chunk_size 过大」) |
file_hash |
string | ❌ | - | 整文件 SHA256(断点续传的匹配键) |
curl 示例:
curl -s -X POST http://localhost:8466/chunk/upload/init \
-H 'Content-Type: application/json' \
-d '{"file_name":"movie.mp4","file_size":15728640,"chunk_size":5242880,"file_hash":"<sha256>"}'
成功响应(200,新建会话):
{
"code": 200, "msg": "ok",
"data": {
"existed": false,
"upload_id": "3f6b8c2a4d5e6f708192a3b4c5d6e7f8",
"chunk_size": 5242880,
"total_chunks": 3,
"uploaded_chunks": []
}
}
断点续传响应(200,命中未完成会话):返回既有会话,uploaded_chunks 为已传分片索引列表,
客户端只需补传缺失分片(注意:existed 字段恒为 false,是否续传以 upload_id 复用且
uploaded_chunks 非空为准):
{
"code": 200, "msg": "ok",
"data": {
"existed": false,
"upload_id": "3f6b8c2a4d5e6f708192a3b4c5d6e7f8",
"chunk_size": 5242880,
"total_chunks": 3,
"uploaded_chunks": [0, 1]
}
}
错误响应:
{ "code": 400, "msg": "file_size 必须大于 0" }
{ "code": 403, "msg": "大小超过限制,最大为10.00 MB" }
{ "code": 403, "msg": "分片上传未启用" }
上传分片:POST /chunk/upload/{uploadID}/{chunkIndex}
主路径(与参考实现语义一致)。chunkIndex 从 0 起。
multipart 字段:chunk(必需,该分片的二进制数据)。
curl 示例:
split -b 5242880 movie.mp4 part- # 本地分片
curl -s -X POST http://localhost:8466/chunk/upload/3f6b8c2a4d5e6f708192a3b4c5d6e7f8/0 \
-F 'chunk=@./part-aa'
成功响应(200):
{ "code": 200, "msg": "ok", "data": { "chunk_hash": "9af1…", "chunk_index": 0 } }
重复上传已完成的分片(幂等跳过):
{ "code": 200, "msg": "ok", "data": { "chunk_hash": "9af1…", "chunk_index": 0, "skipped": true } }
错误响应:
{ "code": 404, "msg": "上传会话不存在" }
{ "code": 400, "msg": "无效的分片索引" }
{ "code": 400, "msg": "分片大小超过声明值: 最大 5242880, 实际 5300000" }
{ "code": 400, "msg": "缺少分片文件字段 chunk" }
{ "code": 403, "msg": "大小超过限制,最大为10.00 MB" }
约束:单分片 ≤
chunk_size(init 声明值)且 ≤ 32MiB 硬上限(init 时chunk_size>33554432直接 400「chunk_size 过大」); 总大小(init 按分片数上限、上传/合并按累计)受动态策略上限约束——max_file_size>0时为其, 否则回落uploadSize(v2 需求 ④⑩,管理端改后立即生效,超限清理会话);首个分片做 magic bytes 防伪校验(403「文件内容校验失败:…」)。分片哈希由服务端计算;合并时与分片记录交叉校验,不一致报 400。enableChunk 开关:管理端关闭分片上传后,
/chunk/upload/*全部端点返回 403「分片上传未启用」(后端强制,前端仅隐藏入口)。
查询进度:GET /chunk/upload/status/{uploadID}
curl -s http://localhost:8466/chunk/upload/status/3f6b8c2a4d5e6f708192a3b4c5d6e7f8
成功响应(200):
{
"code": 200, "msg": "ok",
"data": {
"upload_id": "3f6b8c2a4d5e6f708192a3b4c5d6e7f8",
"file_name": "movie.mp4",
"file_size": 15728640,
"chunk_size": 5242880,
"total_chunks": 3,
"uploaded_chunks": [0, 1],
"progress": 66.66666666666667
}
}
完成合并:POST /chunk/upload/complete/{uploadID}
全部分片到齐后调用。服务端按索引有序合并 + SHA256 校验,成功后创建分享并清理分片。
请求体(JSON,亦兼容表单):
| 参数 | 类型 | 必需 | 默认 | 说明 |
|---|---|---|---|---|
expire_value |
int | ❌ | 1 |
过期值 |
expire_style |
string | ❌ | day |
过期方式(同文件分享) |
curl -s -X POST http://localhost:8466/chunk/upload/complete/3f6b8c2a4d5e6f708192a3b4c5d6e7f8 \
-H 'Content-Type: application/json' \
-d '{"expire_value":1,"expire_style":"day"}'
成功响应(200):
{ "code": 200, "msg": "ok", "data": { "code": "R7T2K", "name": "movie.mp4" } }
错误响应:
{ "code": 400, "msg": "分片不完整" }
{ "code": 400, "msg": "分片哈希校验失败,请重新上传" }
{ "code": 403, "msg": "大小超过限制,最大为10.00 MB" }
取消上传:DELETE /chunk/upload/{uploadID}
清理分片文件与上传记录,释放容量预留。
curl -s -X DELETE http://localhost:8466/chunk/upload/3f6b8c2a4d5e6f708192a3b4c5d6e7f8
{ "code": 200, "msg": "ok", "data": { "message": "上传已取消" } }
{ "code": 404, "msg": "上传会话不存在" }