附录:数据结构(Manifest/Chunk/State)最小建议
本附录提供面向“分片并发 + 断点续传 + 幂等重试”的最小数据结构建议。 目标是让实现既能高吞吐并发,又能在失败后可靠恢复,而不需要复杂事务。
总体原则
- 大对象与小状态分层:chunks/manifest 属于大对象,进入对象存储;state 属于小状态,进入状态存储。
- 唯一键与幂等:chunk MUST 可通过 (transferId, fileId, chunkIndex) 唯一定位,以支持幂等重传。
- 可恢复性:state MUST 能表达“已完成集合”,以便恢复时跳过已完成的部分。
- 不泄露敏感信息:对象键与状态 SHOULD 避免嵌入 email、原始文件名等敏感字段(这些字段是否加密取决于你的隐私策略)。
A.1 Manifest(清单)最小字段
Manifest 是接收方下载与组装的“唯一入口”。最小建议如下:
- manifestVersion:MUST。用于兼容升级(例如
1)。 - transferId:MUST。传输会话唯一标识。
- createdAt / expiresAt:SHOULD。用于生命周期与 UI 提示。
- policy:SHOULD。包含下载次数限制、是否需要密码、是否允许未完成分享等策略摘要。
- files[]:MUST。文件集合描述(至少包含文件大小与分片范围)。
- chunking:MUST。包含 chunkSize、chunkCount 计算方式或每文件的 chunkCount。
- objectKeyRule:MUST。根据 (transferId, fileId, chunkIndex) 推导对象键,或提供明确的映射表。
A.1.1 files[] 最小字段建议
- fileId:MUST。文件唯一标识(不使用文件名作为唯一键)。
- size:MUST。字节数。
- mime:MAY。用于展示与下载建议。
- name:MAY。若要做到严格的零知识/最小泄露,请省略
name或存储加密后的名称。 - chunkCount:MUST。该文件分片数。
- chunkOffset:MAY。若多个文件共享全局
chunkIndex,则需要偏移量;否则可省略。
A.1.2 完整性与校验字段(可选但推荐)
- chunkHashes[]:SHOULD。每个 chunk 的校验(hash/长度/etag 之一或组合)。
- fileHash:MAY。整文件校验(下载后验证)。
- ciphertextLength:MAY。用于密文级别的长度一致性检查(不需要明文)。
A.2 Chunk(分片对象)最小约束
- 唯一定位:chunk MUST 可由 (transferId, fileId, chunkIndex) 唯一定位。
- 幂等上传:重复上传同一 chunk MUST NOT 破坏最终状态(可以覆盖,也可以拒绝,但行为必须一致)。
- 最小元信息:服务端 MAY 仅记录密文长度、写入时间、etag/版本等,用于可观测与问题定位。
A.2.1 对象键规则(示例)
/transfers/{transferId}/chunks/{fileId}/{chunkIndex}/transfers/{transferId}/manifest
约束:对象键 MUST 支持按 transferId 前缀批量清理;对象键 SHOULD 避免携带敏感业务信息。
A.3 State(状态记录)最小字段
State 用于回答“上传/下载进度与恢复”,应该尽量小、可快速读写。
- transferId:MUST。
- status:MUST。建议:
UPLOADING/READY/DELETED/EXPIRED。 - uploadedSet:MUST。已完成 chunk 集合;SHOULD 用 bitmap / range-set 压缩表示。
- uploadedBytes:SHOULD。用于展示进度与限额判断(可由 chunks 推导但实时维护更快)。
- downloadCount:MAY。若你有下载次数限制,必须记录并原子更新(实现细节依赖你的存储)。
- expiresAt:SHOULD。用于过期拒绝与后台清理。
A.3.1 恢复接口的最小输出
为了断点续传,服务端 SHOULD 能返回:
- transfer 状态(UPLOADING/READY/DELETED/EXPIRED)
- uploadedSet(已完成 chunk 集合)
- 策略摘要(例如是否超出配额、是否已过期、是否允许继续上传)
附注:与安全白皮书的边界
- 本附录仅描述传输/存储所需的“结构与约束”。
- 加密字段、密钥材料如何携带/派生、认证失败的失败关闭等边界,请以《安全与隐私白皮书》为准。