Skip to main content

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>

标头摘要表

标头方法是否必需默认值
DAVOPTIONS必须-1, 2, 3, extend
DepthPROPFIND, LOCK, COPY, MOVE可选infinity0, 1, infinity
DestinationCOPY, MOVE必须-绝对URI
If全部可选-状态令牌, ETag
Lock-TokenUNLOCK必须-锁令牌URI
OverwriteCOPY, MOVE可选TT, F
TimeoutLOCK可选服务器决定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节。