# 应用服务器 API

`cipherfs serve` 构建启用 `sync`。以下路由位于 `/api/v1` 或配置的仓库别名之下，使用现有 Bearer/私有归属会话；S3 应用密钥不能访问 JSON 管理接口。

| 请求 | 行为 |
| --- | --- |
| `PUT /server/file?path=attachments/a&level=store&timeout_ms=30000` | 流式替换完整正文，本机提交后等待至少一个存放点确认正文 |
| `PUT /server/file?file_id=<id>&level=full_devices&full_devices_count=2` | 替换已有身份，等待两台有资格的 Full 设备确认完整正文 |
| `GET /server/file?file_id=<id>` | 按身份读取，支持现有单 Range |
| `GET /server/durability?version=<id>` | 查询指定版本已接受的正文持有位置 |
| `POST /server/durability` | 对已有版本继续等待确认，不产生另一次写入 |
| `GET` / `PUT /server/cache` | 读取或替换本设备的单文件固定及热度预取配置 |
| `PUT` / `DELETE /server/pins?file_id=<id>` | 固定或取消固定一个准确的文件身份 |

写入只接受 `path`、`file_id` 二者之一。`level` 默认 `local`；另有 `store`、`full_devices`，后者必须给出 1–128 的 `full_devices_count`。确认超时为 1–3,600,000 毫秒，默认 30,000，从本机提交之后开始。非法参数及本地专属文件的复制确认请求在消费正文之前拒绝；正文缓冲、明确 EOF、内容类型和取消复用原文件适配器。

成功响应的 `receipt` 包含提交事务直接返回的准确 `file`、`version`、`local_only`。存放点/Full 确认必须覆盖该版本的完整正文；只有索引、Partial 设备和已撤销设备不计为 Full 副本。本机为 Full 且持有正文时计入台数。位置来自认证记录，不保证持有者此后始终在线。

确认超时返回 HTTP 504 和已提交回执，不撤销本机写入；其他确认失败也保留已知回执。会话撤销时，已接纳的服务器写入会排空工作者，可以返回错误回执，不能返回成功或正文。客户端断开仍可能收不到响应；重试上传会产生新的写入。

继续等待的 JSON：

```json
{
  "version": "<准确版本号>",
  "requirement": {"level": "full_devices", "count": 2},
  "timeout_ms": 30000
}
```

FileId 入口跟随移动，不会改成原路径后来出现的另一个文件；准备期间的并发移动可能返回冲突，需要重试。历史正文继续通过既有版本 API 读取。

缓存配置仅在本设备生效，并密封保存在 metadata：

```json
{
  "pinned_files": [],
  "prefetch_max_files": 32,
  "prefetch_max_bytes": 67108864,
  "heat_ttl_ms": 3600000
}
```

固定项是排序去重的已有 FileId，最多 4,096 个，随移动和新写入保持该文件当前正文，不固定子项或原路径的新文件。删除后可以留下失效的固定项，随后取消即可；目录固定仍单独保留。

热度在内存跟踪最多 1,024 个访问过的文件身份，随时间衰减，密封或重启即清空；Partial 设备可预取近期热文件的新 head。每轮最多选择 `prefetch_max_files` 个（上限 1,024），缺失密文须同时装入 `prefetch_max_bytes`（上限 8 GiB）和读取缓存预算；单文件超过剩余预算则跳过。两个限制都为零时关闭，默认关闭。热度不会永久固定数据，仍遵循正常驱逐；`heat_ttl_ms` 必须为正且不超过七天。

短保留通过 `PUT /retention` 的可选 `application` 对象配置，普通按天字段保留。例如：

```json
{
  "version_max_age_days": 365,
  "trash_max_age_days": 365,
  "min_versions_per_file": 1,
  "grace_days": 30,
  "application": {
    "version_max_age_ms": 60000,
    "trash_max_age_ms": 60000,
    "grace_ms": 10000,
    "local_drop_margin_ms": 10000,
    "store_gc_delay_ms": 10000
  }
}
```

覆盖值作用于整个仓库，经认证后同步；零表示不等待，每项最多一百年。不提供 `application` 时按天行为不变。提案保存其因果历史中策略的期限，后续修改不改变该提案。当前/冲突 head 和未发布修改继续受保护。达到期限只表示具备回收资格，实际时间仍受维护调度、pack 内存活正文以及孤儿/重打包保护影响；不是实时删除承诺。桌面的按天编辑器会保留已存在的应用覆盖值。格式细节见 [FORMAT](FORMAT.md)。

Rust 可使用 Core 的 `WriteReceipt`、`open_file_id_handle`、`write_file_id_from_reader`、`pin_file`、`server_cache_policy`、`version_durability`；`SyncedVault` 另提供准确版本返回、FileId 流式读写、缓存控制和可取消的 `wait_for_durability`。超时错误保留版本及最后一次完成的位置观测，不回滚之前的写入。
