SyncClipboard S3 同步协议规范
April 15, 2026 · View on GitHub
本文档描述 SyncClipboard 使用 S3 兼容对象存储作为同步后端的存储布局约定以及相关开发指南。
1. S3 专有配置项
以下配置项为 S3 服务器依赖。
| 参数 | 说明 | 必填 | 默认值 |
|---|---|---|---|
ServiceURL | S3 兼容端点 URL。使用 AWS 原生服务时留空 | 否 | 空 |
Region | AWS 区域标识(如 us-east-1、ap-northeast-1) | 否 | us-east-1 |
BucketName | 存储桶名称 | 是 | — |
ObjectPrefix | 所有对象 key 的统一前缀,用于隔离多客户端或多用途 | 否 | 空 |
ForcePathStyle | 是否使用路径风格寻址(endpoint/bucket/key),大多数 S3 兼容服务需要开启 | 否 | false |
AccessKeyId | 访问密钥 ID | 是 | — |
SecretAccessKey | 访问密钥 Secret | 是 | — |
端点选择规则
- AWS 原生:
ServiceURL留空,SDK 根据Region自动解析标准 AWS S3 端点。 - S3 兼容服务(MinIO / Cloudflare R2 / 阿里云 OSS 等):填写
ServiceURL(如https://s3.example.com),一般同时启用ForcePathStyle = true。
认证方式
使用 AWS Signature V4 签名。
2. 对象存储布局
所有对象 key 的格式为 {ObjectPrefix}/{相对路径}。前缀的首尾 / 会被 trim。
{BucketName}/
└── {ObjectPrefix}/ # 为空时没有此级
├── SyncClipboard.json # 剪贴板 Profile 元数据文件
└── file/ # 附件目录(零或多个数据文件)
├── {dataName1} # 例如 "Text_2025-04-15_08-45-23_abc12345.tmp.txt"
└── {dataName2} # 例如 "screenshot.png"
3. Profile 元数据格式(SyncClipboard.json)
参照 API 说明。
4. S3 API 调用约定
以下按操作列出具体的 S3 API 调用。所有操作均使用 AWS Signature V4 认证。
4.1 连接测试
| S3 操作 | ListObjectsV2 |
|---|---|
| Bucket | {BucketName} |
| Prefix | {ObjectPrefix} |
| MaxKeys | 1 |
成功返回即说明凭据和桶可用。
4.2 初始化(确保目录结构)
检查 file/ 目录标记是否存在:
| S3 操作 | HeadObject(GetObjectMetadata) |
|---|---|
| Key | {prefix}/file/ |
如果返回 404 / NoSuchKey,则创建目录标记:
| S3 操作 | PutObject |
|---|---|
| Key | {prefix}/file/ |
| Body | 空字符串 |
| Content-Type | application/x-directory |
4.3 读取 Profile
| S3 操作 | GetObject |
|---|---|
| Key | {prefix}/SyncClipboard.json |
- 成功:读取响应体 → JSON 反序列化为 ProfileDto
- 404 / NoSuchKey:返回空(首次使用,尚无 Profile)
4.4 写入 Profile
| S3 操作 | PutObject |
|---|---|
| Key | {prefix}/SyncClipboard.json |
| Body | JSON 序列化的 ProfileDto |
| Content-Type | application/json; charset=utf-8 |
4.5 上传数据文件
| S3 操作 | PutObject |
|---|---|
| Key | {prefix}/file/{fileName} |
| Body | 文件二进制内容 |
fileName 即 ProfileDto 中的 dataName 字段值。
4.6 下载数据文件
| S3 操作 | GetObject |
|---|---|
| Key | {prefix}/file/{dataName} |
dataName 来自 ProfileDto 的 dataName 字段。
4.7 清理旧文件
分页列出 file/ 目录下所有对象并批量删除:
第一步:列出对象
| S3 操作 | ListObjectsV2 |
|---|---|
| Prefix | {prefix}/file/ |
| MaxKeys | 1000 |
使用 ContinuationToken 分页直到全部列出。
第二步:批量删除
| S3 操作 | DeleteObjects |
|---|---|
| Objects | 上一步列出的所有 key |
5. S3 兼容服务注意事项
5.1 签名与编码
对于非 AWS 的 S3 兼容服务,在 PUT 请求时应注意:
| 设置 | 说明 |
|---|---|
| 禁用 Chunked Transfer Encoding | 不使用 Transfer-Encoding: chunked |
| 禁用 Payload Signing | 不在请求体上计算 SHA-256 签名(使用 UNSIGNED-PAYLOAD) |
| 禁用 Trailer Checksum | 不追加 x-amz-checksum-* trailer |
许多 S3 兼容网关(R2、MinIO、OSS gateway 等)不支持 AWS SDK v3+ 默认启用的流式 Trailer 签名。
5.2 路径风格 vs 虚拟主机风格
- AWS 标准:虚拟主机风格
{bucket}.s3.{region}.amazonaws.com/{key} - 兼容服务:通常需要路径风格
{endpoint}/{bucket}/{key}(开启ForcePathStyle)
5.3 协议选择
- 如果
ServiceURL以http://开头,使用 HTTP;否则使用 HTTPS - AWS 原生始终使用 HTTPS