10. HTTP Headers for Distributed Authoring (分布式创作的HTTP标头)
WebDAV定义了几个新的HTTP标头,并扩展了现有标头以支持分布式创作功能。
10.1 DAV Header (DAV标头)
目的: 指示WebDAV合规类和支持的功能。
语法:
DAV = "DAV" ":" #(compliance-class)
compliance-class = ("1" | "2" | "3" | extend)
示例:
DAV: 1, 2, 3, `http://example.com/my-features`
合规类 (Compliance Classes):
- 类1: 基本WebDAV支持 (PROPFIND, PROPPATCH, COPY, MOVE, MKCOL等)
- 类2: 类1 + 锁定支持 (LOCK, UNLOCK)
- 类3: 类1 + 有序集合
用法: 必须在OPTIONS响应中返回。可以在其他响应中返回。
10.2 Depth Header (深度标头)
目的: 为应用于集合的方法指定操作深度。
语法:
Depth = "Depth" ":" ("0" | "1" | "infinity")
值:
- 0: 仅应用于目标资源
- 1: 应用于目标及其直接子资源
- infinity: 递归应用于目标及所有后代
示例:
PROPFIND /collection/ HTTP/1.1
Depth: 1
默认行为:
- PROPFIND: 如果省略,视为
infinity - LOCK: 如果省略,视为
infinity - COPY/MOVE: 如果省略,视为
infinity
约束: 某些服务器可能会因资源限制而拒绝Depth: infinity。
10.3 Destination Header (目标标头)
目的: 为COPY和MOVE操作指定目标URI。
语法:
Destination = "Destination" ":" Simple-ref
示例:
COPY /source HTTP/1.1
Host: example.com
Destination: http://example.com/dest
要求:
- 必须是绝对URI
- 必须与Request-URI在同一主机上(对于大多数实现)
- 适用URI编码规则
10.4 If Header (If标头)
目的: 基于状态令牌(ETag或锁令牌)提供条件执行。
语法:
If = "If" ":" ( 1*No-tag-list | 1*Tagged-list )
No-tag-list = List
Tagged-list = Resource-Tag 1*List
List = "(" 1*Condition ")"
Condition = ["Not"] (State-token | "[" entity-tag "]")
State-token = Coded-URL
示例:
1. 简单锁令牌提交:
PUT /resource HTTP/1.1
If: (<opaquelocktoken:a515cfa4-5da4-22e1-f5b5-00a0451e6bf7>)
2. 多个条件 (OR):
DELETE /resource HTTP/1.1
If: (<locktoken1>) (<locktoken2>)
3. 多个条件 (AND):
MOVE /resource HTTP/1.1
If: (<locktoken>) (["etag123"])
4. 标记列表 (多个资源):
COPY /a HTTP/1.1
Destination: /b
If: </a> (<locktoken-a>) </b> (Not <locktoken-b>)
5. NOT条件:
PUT /resource HTTP/1.1
If: (Not <DAV:no-lock>)
求值:
()内的列表使用AND连接- 多个列表使用OR连接
Not对条件取反- If标头求值失败返回
412 Precondition Failed
10.5 Lock-Token Header (锁令牌标头)
目的: 为UNLOCK操作提供锁令牌。
语法:
Lock-Token = "Lock-Token" ":" Coded-URL
示例:
UNLOCK /resource HTTP/1.1
Lock-Token: <opaquelocktoken:a515cfa4-5da4-22e1-f5b5-00a0451e6bf7>
要求:
- 必须与UNLOCK方法一起使用
- 包含恰好一个锁令牌
- 锁令牌必须在尖括号
< >中
10.6 Overwrite Header (覆盖标头)
目的: 指定是否在COPY/MOVE中覆盖目标资源。
语法:
Overwrite = "Overwrite" ":" ("T" | "F")
值:
- T (True): 如果目标存在则覆盖(默认)
- F (False): 如果目标存在则失败(返回412)
示例:
COPY /source HTTP/1.1
Destination: http://example.com/dest
Overwrite: F
默认值: 如果省略,视为T。
行为:
- 使用
Overwrite: F时,如果目标存在则返回412 Precondition Failed - 使用
Overwrite: T时,目标被静默替换
10.7 Timeout Header (超时标头)
目的: 指定请求的锁超时持续时间。
语法:
Timeout = "Timeout" ":" 1#TimeType
TimeType = ("Second-" DAVTimeOutVal | "Infinite")
DAVTimeOutVal = 1*DIGIT
示例:
LOCK /resource HTTP/1.1
Timeout: Second-3600
LOCK /resource HTTP/1.1
Timeout: Infinite, Second-3600
语义:
- Second-n: 请求锁定n秒
- Infinite: 请求无超时的锁
- 多个值表示优先顺序
- 服务器从客户端列表中选择或使用自己的值
- 实际授予的超时在响应中返回
响应示例:
<D:timeout>Second-3600</D:timeout>
标头摘要表
| 标头 | 方法 | 是否必需 | 默认值 | 值 |
|---|---|---|---|---|
| DAV | OPTIONS | 必须 | - | 1, 2, 3, extend |
| Depth | PROPFIND, LOCK, COPY, MOVE | 可选 | infinity | 0, 1, infinity |
| Destination | COPY, MOVE | 必须 | - | 绝对URI |
| If | 全部 | 可选 | - | 状态令牌, ETag |
| Lock-Token | UNLOCK | 必须 | - | 锁令牌URI |
| Overwrite | COPY, MOVE | 可选 | T | T, F |
| Timeout | LOCK | 可选 | 服务器决定 | Second-n, Infinite |
使用模式
模式1: 使用锁的条件更新
PUT /file.txt HTTP/1.1
If: (<opaquelocktoken:...>)
Content-Type: text/plain
New content
模式2: 安全COPY (不覆盖)
COPY /source HTTP/1.1
Destination: /dest
Overwrite: F
Depth: infinity
模式3: 带超时偏好的锁定
LOCK /resource HTTP/1.1
Timeout: Infinite, Second-7200, Second-3600
Depth: 0
模式4: 复杂If条件
DELETE /locked-resource HTTP/1.1
If: (<locktoken>) (["current-etag"])
注意: 有关完整的标头规范(包括ABNF语法),请参见RFC 4918第10节。