3. 范围请求 (Range Requests)
3.1 Range
GET 请求中的 "Range" 头字段修改了该方法的语义, 请求只传输所选表示数据的一个或多个子范围, 而不是整个所选表示数据.
Range = byte-ranges-specifier / other-ranges-specifier
other-ranges-specifier = other-range-unit "=" other-range-set
other-range-set = 1*VCHAR
服务器可以 (MAY) 忽略 Range 头字段. 但是, 源服务器和中间缓存应当在可能的情况下支持字节范围, 因为 Range 支持从部分失败的传输中高效恢复, 以及大表示的部分检索. 服务器必须 (MUST) 忽略随 GET 以外的请求方法一起收到的 Range 头字段.
源服务器必须 (MUST) 忽略包含其不理解的范围单位的 Range 头字段. 代理可以 (MAY) 丢弃包含其不理解的范围单位的 Range 头字段.
支持范围请求的服务器可以忽略或拒绝由两个以上重叠范围组成, 或由未按升序排列的许多小范围组成的集合的 Range 头字段, 因为这两者都表明客户端出现了故障, 或者这是一次蓄意的拒绝服务攻击 (第 6.1 节). 客户端不应 (SHOULD NOT) 请求多个在处理和传输上固有地不如单个覆盖相同数据的范围高效的范围.
请求多个范围的客户端应当 (SHOULD) 按升序列出这些范围 (即它们在完整表示中通常会被接收的顺序), 除非有特定需要提前请求较靠后的部分. 例如, 正在处理带有内部部件目录的大型表示的用户代理可能需要先请求靠后的部分, 特别是当该表示由以逆序存储的页面组成, 且用户代理希望一次传输一个页面时.
Range 头字段在对 [RFC7232] 中定义的前置条件头字段求值之后再进行求值, 并且只有当在没有 Range 头字段的情况下结果将是 200 (OK) 响应时才生效. 换句话说, 当条件 GET 的结果将是 304 (Not Modified) 响应时, Range 会被忽略.
If-Range 头字段 (第 3.2 节) 可以用作是否应用 Range 头字段的前置条件.
如果所有前置条件都为真, 服务器对目标资源支持 Range 头字段, 并且指定的范围有效且可满足 (如第 2.1 节所定义), 则服务器应当 (SHOULD) 发送一个 206 (Partial Content) 响应, 其有效载荷包含与所请求的可满足范围对应的一个或多个部分表示, 如第 4 节所定义.
如果所有前置条件都为真, 服务器对目标资源支持 Range 头字段, 并且指定的范围无效或不可满足, 则服务器应当 (SHOULD) 发送一个 416 (Range Not Satisfiable) 响应.
3.2 If-Range
如果客户端拥有某个表示的部分副本, 并希望获得整个表示的最新副本, 它可以将 Range 头字段与条件 GET 一起使用 (使用 If-Unmodified-Since 和/或 If-Match). 但是, 如果前置条件因表示已被修改而失败, 客户端将不得不发出第二个请求来获得整个当前表示.
"If-Range" 头字段允许客户端"短路"第二个请求. 非正式地说, 它的含义是: 如果该表示没有改变, 请把我请求的 Range 中的那些部分发给我; 否则, 请把整个表示发给我.
If-Range = entity-tag / HTTP-date
客户端禁止 (MUST NOT) 在不包含 Range 头字段的请求中生成 If-Range 头字段. 服务器必须 (MUST) 忽略在不包含 Range 头字段的请求中收到的 If-Range 头字段. 源服务器必须 (MUST) 忽略在对不支持范围请求的目标资源的请求中收到的 If-Range 头字段.
客户端禁止 (MUST NOT) 生成包含被标记为弱 (weak) 的实体标签 (entity-tag) 的 If-Range 头字段. 客户端禁止 (MUST NOT) 生成包含 HTTP 日期的 If-Range 头字段, 除非客户端没有对应表示的实体标签, 并且该日期是 [RFC7232] 第 2.2.2 节所定义意义上的强验证器 (strong validator).
对 If-Range 前置条件求值的服务器, 在比较实体标签时必须 (MUST) 使用强比较函数 ([RFC7232] 第 2.3.2 节), 并且在所提供的 HTTP 日期验证器不是 [RFC7232] 第 2.2.2 节所定义意义上的强验证器时, 必须 (MUST) 将该条件判定为假. 可以通过检查前两个字符是否为 DQUOTE (双引号) 来区分有效的实体标签与有效的 HTTP 日期.
如果 If-Range 头字段中给定的验证器与目标资源所选表示的当前验证器匹配, 则服务器应当 (SHOULD) 按请求处理 Range 头字段. 如果验证器不匹配, 服务器必须 (MUST) 忽略 Range 头字段. 注意, 这种按精确匹配进行的比较 (包括验证器为 HTTP 日期的情形) 不同于对 If-Unmodified-Since 条件求值时所使用的"早于或等于"比较.