3. 协议参数 (Protocol Parameters)
3 协议参数
3.1 HTTP 版本
HTTP 使用 "<major>.<minor>" 编号方案来表示协议版本.
协议版本策略旨在让发送者指明 message 的格式及其理解后续 HTTP 通信的能力,
而不是指明通过该通信获得的功能. 对于不影响通信行为的 message component 增加,
或者只是向可扩展字段值添加内容的变化, 不改变版本号.
当协议变化增加了不改变通用 message 解析算法的功能, 但可能增加 message 语义并暗示发送者额外能力时,
<minor> 编号递增. 当协议中的 message 格式发生变化时, <major> 编号递增.
更完整说明见 RFC 2145 [36].
HTTP message 的版本由 message 第一行中的 HTTP-Version 字段表示.
HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
注意, major 和 minor 编号 MUST 作为独立整数处理, 且每个编号 MAY 增加到超过一位数字. 因此, HTTP/2.4 是低于 HTTP/2.13 的版本, 而 HTTP/2.13 又低于 HTTP/12.3. recipient MUST 忽略前导零, 且 MUST NOT 发送前导零.
发送包含 "HTTP/1.1" HTTP-Version 的 request 或 response message 的应用, MUST 至少有条件地符合本规范. 至少有条件符合本规范的应用 SHOULD 在其 message 中使用 "HTTP/1.1" HTTP-Version, 且对任何与 HTTP/1.0 不兼容的 message MUST 这样做. 关于何时发送特定 HTTP-Version 值的更多细节见 RFC 2145 [36].
应用的 HTTP 版本是该应用至少有条件合规的最高 HTTP 版本.
proxy 和 gateway 应用在转发协议版本不同于自身版本的 message 时需要小心. 由于协议版本表示发送者的协议能力, proxy/gateway MUST NOT 发送版本指示高于其实际版本的 message. 如果收到更高版本的 request, proxy/gateway MUST 降级 request version, 或返回错误, 或切换为 tunnel 行为.
由于 RFC 2068[33] 发布后发现了与 HTTP/1.0 proxy 的互操作问题, caching proxy MUST, gateway MAY, tunnel MUST NOT 将 request 升级到它们支持的最高版本. proxy/gateway 对该 request 的 response MUST 与 request 使用相同 major version.
注意: 在 HTTP 版本之间转换可能涉及修改相关版本要求或禁止的 header field.
3.2 统一资源标识符 (Uniform Resource Identifiers)
URI 曾有许多名称: WWW address, Universal Document Identifier, Universal Resource Identifier [3], 以及最后的 Uniform Resource Locator (URL) [4] 和 Name (URN) [20] 组合. 就 HTTP 而言, Uniform Resource Identifier 只是格式化字符串, 它们通过名称, 位置或任何其他特征来标识 resource.
3.2.1 通用语法
HTTP 中的 URI 可以根据使用上下文以绝对形式表示, 或相对于某个已知 base URI [11] 表示. 这两种形式的区别在于, 绝对 URI 总是以 scheme name 开头, 后跟冒号. 关于 URL 语法和语义的权威信息, 见 "Uniform Resource Identifiers (URI): Generic Syntax and Semantics," RFC 2396 [42] (它替代 RFC 1738 [4] 和 RFC 1808 [11]). 本规范采用该规范中 "URI-reference", "absoluteURI", "relativeURI", "port", "host", "abs_path", "rel_path" 和 "authority" 的定义.
HTTP 协议不对 URI 长度设置任何先验限制. server MUST 能够处理它所服务的任何 resource 的 URI, 并且如果提供可能生成此类 URI 的基于 GET 的表单, SHOULD 能够处理无界长度的 URI. 如果 URI 长于 server 能处理的长度, server SHOULD 返回 414 (Request-URI Too Long) status (见第 10.4.15 节).
注意: server 应谨慎依赖超过 255 字节的 URI 长度, 因为某些较旧 client 或 proxy 实现可能无法正确支持这些长度.
3.2.2 http URL
"http" scheme 用于通过 HTTP 协议定位网络 resource. 本节定义 http URL 的 scheme-specific 语法和语义.
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
如果 port 为空或未给出, 则假定为端口 80. 其语义是: 被标识 resource 位于在该 host 的该 port 上监听 TCP connection 的 server, 且该 resource 的 Request-URI 为 abs_path (第 5.1.2 节). URLs 中 SHOULD 尽可能避免使用 IP 地址 (见 RFC 1900 [24]). 如果 URL 中不存在 abs_path, 当它作为 resource 的 Request-URI 使用时, MUST 给出为 "/" (第 5.1.2 节). 如果 proxy 收到的 host name 不是 fully qualified domain name, 它 MAY 将自己的 domain 添加到收到的 host name. 如果 proxy 收到 fully qualified domain name, 该 proxy MUST NOT 改变 host name.
3.2.3 URI 比较
比较两个 URI 以决定它们是否匹配时, client SHOULD 对整个 URI 使用区分大小写的逐 octet 比较, 但有以下例外:
- 为空或未给出的 port 等价于该 URI-reference 的默认 port;
- host name 的比较 MUST 不区分大小写;
- scheme name 的比较 MUST 不区分大小写;
- 空 abs_path 等价于 "/" 的 abs_path.
除 "reserved" 和 "unsafe" 集合中的字符外 (见 RFC 2396 [42]), 其他字符等价于其 ""%" HEX HEX" 编码.
例如, 以下三个 URI 等价:
http://abc.com:80/~smith/home.html
http://ABC.com/%7Esmith/home.html
http://ABC.com:/%7esmith/home.html
3.3 日期/时间格式
3.3.1 完整日期
历史上, HTTP 应用允许使用三种不同格式表示 date/time stamp:
Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
第一种格式作为 Internet 标准是首选格式, 表示 RFC 1123 [8] (对 RFC 822 [9] 的更新) 所定义格式的固定长度子集. 第二种格式被广泛使用, 但基于已废弃的 RFC 850 [12] 日期格式, 且缺少四位年份. 解析日期值的 HTTP/1.1 client 和 server MUST 接受全部三种格式 (为兼容 HTTP/1.0), 但在 header field 中表示 HTTP-date 值时 MUST 只生成 RFC 1123 格式. 更多信息见第 19.3 节.
注意: 鼓励日期值 recipient 在接受可能由非 HTTP 应用发送的日期值时保持健壮,
例如有时通过到 SMTP 或 NNTP 的 proxy/gateway 检索或投递 message 时会出现这种情况.
所有 HTTP date/time stamp MUST 无例外地以 Greenwich Mean Time (GMT) 表示. 就 HTTP 而言, GMT 与 UTC (Coordinated Universal Time) 完全相等. 前两种格式通过包含 "GMT" 作为时区三字母缩写来表示这一点; 读取 asctime 格式时也 MUST 假定如此. HTTP-date 区分大小写, 且 MUST NOT 包含语法中作为 SP 明确包含之外的额外 LWS.
HTTP-date = rfc1123-date | rfc850-date | asctime-date
rfc1123-date = wkday "," SP date1 SP time SP "GMT"
rfc850-date = weekday "," SP date2 SP time SP "GMT"
asctime-date = wkday SP date3 SP time SP 4DIGIT
date1 = 2DIGIT SP month SP 4DIGIT
; day month year (e.g., 02 Jun 1982)
date2 = 2DIGIT "-" month "-" 2DIGIT
; day-month-year (e.g., 02-Jun-82)
date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
; month day (e.g., Jun 2)
time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
; 00:00:00 - 23:59:59
wkday = "Mon" | "Tue" | "Wed"
| "Thu" | "Fri" | "Sat" | "Sun"
weekday = "Monday" | "Tuesday" | "Wednesday"
| "Thursday" | "Friday" | "Saturday" | "Sunday"
month = "Jan" | "Feb" | "Mar" | "Apr"
| "May" | "Jun" | "Jul" | "Aug"
| "Sep" | "Oct" | "Nov" | "Dec"
注意: HTTP 对 date/time stamp 格式的要求只适用于其在协议流中的使用.
client 和 server 不要求在用户展示, request logging 等场景中使用这些格式.
3.3.2 Delta Seconds
某些 HTTP header field 允许把时间值指定为接收 message 之后的整数秒数, 以十进制表示.
delta-seconds = 1*DIGIT
3.4 字符集 (Character Sets)
HTTP 使用与 MIME 所描述相同的 "character set" 术语定义:
本文档使用术语 "character set" 指代一种与一个或多个表配合使用的方法, 用于把 octet 序列转换为字符序列. 注意, 不要求能无条件地反向转换, 因为并非所有字符都一定可用于给定 character set, 且一个 character set 可能提供多个 octet 序列来表示某个特定字符. 该定义旨在允许各种字符编码, 从 US-ASCII 这样简单的单表映射, 到使用 ISO-2022 技术的复杂表切换方法. 但是, 与 MIME character set 名称关联的定义 MUST 完整规定从 octet 到字符的映射. 特别是, 不允许使用外部 profile 信息来确定精确映射.
注意: 这里使用的术语 "character set" 更常被称为 "character encoding."
但是, 由于 HTTP 和 MIME 共享同一个注册表, 共享术语也很重要.
HTTP character set 由大小写不敏感的 token 标识. 完整 token 集由 IANA Character Set registry [19] 定义.
charset = token
虽然 HTTP 允许任意 token 用作 charset 值, 但任何在 IANA Character Set registry [19] 中已有预定义值的 token MUST 表示该注册表定义的 character set. 应用 SHOULD 将其使用的 character set 限制为 IANA registry 定义的集合.
实现者应了解 IETF character set requirements [38] [41].
3.4.1 缺失 Charset
某些 HTTP/1.0 软件曾错误地把不带 charset 参数的 Content-Type header 解释为 "recipient should guess." 希望避免此行为的 sender MAY 即使在 charset 为 ISO-8859-1 时也包含 charset 参数, 且当已知这不会使 recipient 困惑时 SHOULD 这样做.
不幸的是, 某些较旧 HTTP/1.0 client 没有正确处理显式 charset 参数. HTTP/1.1 recipient MUST 尊重 sender 提供的 charset label; 并且那些提供 "guess" charset 功能的 user agent, 在初始显示 document 时, 如果支持 content-type 字段中的 charset, MUST 使用该 charset, 而不是 recipient 的偏好. 见第 3.7.1 节.
3.5 内容编码 (Content Codings)
content coding 值表示已经或可以应用到 entity 的编码转换. content coding 主要用于允许 document 被压缩 或以其他有用方式转换, 同时不丢失其底层 media type 的身份, 也不丢失信息. entity 通常以编码形式存储, 直接传输, 并只由 recipient 解码.
content-coding = token
所有 content-coding 值都大小写不敏感. HTTP/1.1 在 Accept-Encoding (第 14.3 节) 和 Content-Encoding (第 14.11 节) header field 中使用 content-coding 值. 虽然该值描述 content-coding, 但更重要的是它指出移除此 encoding 所需的 decoding mechanism.
Internet Assigned Numbers Authority (IANA) 作为 content-coding value token 的注册机构. 初始时, 注册表包含以下 token:
gzip 由文件压缩程序 "gzip" (GNU zip) 产生的编码格式, 如 RFC 1952 [25] 所述. 该格式是一种带 32 位 CRC 的 Lempel-Ziv coding (LZ77).
compress 常见 UNIX 文件压缩程序 "compress" 产生的编码格式. 该格式是一种自适应 Lempel-Ziv-Welch coding (LZW).
使用程序名标识编码格式并不理想, 未来编码也不鼓励这样做. 此处的使用代表历史实践, 而非良好设计.
为兼容 HTTP 先前实现, 应用 SHOULD 将 "x-gzip" 和 "x-compress" 分别视为等价于 "gzip" 和 "compress".
deflate RFC 1950 [31] 中定义的 "zlib" 格式, 与 RFC 1951 [29] 中描述的 "deflate" 压缩机制组合使用.
identity 默认 (identity) 编码; 即完全不使用任何转换. 该 content-coding 只用于 Accept-Encoding header, 且 SHOULD NOT 用于 Content-Encoding header.
新的 content-coding value token SHOULD 注册; 为允许 client 和 server 之间互操作, 实现新值所需 content coding 算法的规范 SHOULD 公开可得, 足以独立实现, 并符合本节所定义的 content coding 目的.
3.6 传输编码 (Transfer Codings)
transfer-coding 值用于表示已经, 可以或可能需要应用到 entity-body 的编码转换, 以确保通过网络进行 "safe transport". 这与 content coding 不同, 因为 transfer-coding 是 message 的属性, 不是原始 entity 的属性.
transfer-coding = "chunked" | transfer-extension
transfer-extension = token *( ";" parameter )
参数采用 attribute/value 对形式.
parameter = attribute "=" value
attribute = token
value = token | quoted-string
所有 transfer-coding 值都大小写不敏感. HTTP/1.1 在 TE header field (第 14.39 节) 和 Transfer-Encoding header field (第 14.41 节) 中使用 transfer-coding 值.
每当对 message-body 应用 transfer-coding 时, 除非 message 通过关闭 connection 终止, transfer-coding 集合 MUST 包含 "chunked". 使用 "chunked" transfer-coding 时, 它 MUST 是应用到 message-body 的最后一个 transfer-coding. "chunked" transfer-coding MUST NOT 对一个 message-body 应用超过一次. 这些规则使 recipient 能够确定 message 的 transfer-length (第 4.4 节).
transfer-coding 类似 MIME [7] 的 Content-Transfer-Encoding 值, 后者设计用于在 7-bit transport service 上安全传输二进制数据. 但是, 对于 8bit-clean transfer protocol, safe transport 关注点不同. 在 HTTP 中, message-body 唯一不安全特征是难以确定精确 body length (第 7.2.2 节), 或希望在共享传输上加密数据.
Internet Assigned Numbers Authority (IANA) 作为 transfer-coding value token 的注册机构. 初始时, 注册表包含以下 token: "chunked" (第 3.6.1 节), "identity" (第 3.6.2 节), "gzip" (第 3.5 节), "compress" (第 3.5 节), 和 "deflate" (第 3.5 节).
新的 transfer-coding value token SHOULD 按与新的 content-coding value token 相同的方式注册 (第 3.5 节).
收到带有自己不理解 transfer-coding 的 entity-body 的 server SHOULD 返回 501 (Unimplemented), 并关闭 connection. server MUST NOT 向 HTTP/1.0 client 发送 transfer-coding.
3.6.1 Chunked Transfer Coding
chunked encoding 会修改 message body, 以把它作为一系列 chunk 传输, 每个 chunk 都有自己的 size indicator, 后跟一个 OPTIONAL trailer, 其中包含 entity-header field. 这允许动态生成的内容随同必要信息一起传输, 使 recipient 能够验证自己已经收到完整 message.
Chunked-Body = *chunk
last-chunk
trailer
CRLF
chunk = chunk-size [ chunk-extension ] CRLF
chunk-data CRLF
chunk-size = 1*HEX
last-chunk = 1*("0") [ chunk-extension ] CRLF
chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
trailer = *(entity-header CRLF)
chunk-size 字段是十六进制数字字符串, 表示 chunk 大小. chunked encoding 由任意大小为零的 chunk 结束, 后跟 trailer, trailer 由空行终止.
trailer 允许 sender 在 message 末尾包含额外 HTTP header field. Trailer header field 可用于指示 trailer 中包含哪些 header field (见第 14.40 节).
在 response 中使用 chunked transfer-coding 的 server MUST NOT 将 trailer 用于任何 header field, 除非以下至少一项为真:
a) request 包含 TE header field, 表示 response 的 transfer-coding 中可接受 "trailers", 如第 14.39 节所述; 或,
b) server 是该 response 的 origin server, trailer field 完全由可选 metadata 组成, 并且 recipient 即使不接收这些 metadata 也能以 origin server 可接受的方式使用该 message. 换言之, origin server 愿意接受 trailer field 可能在到 client 的路径上被静默丢弃的可能性.
该要求防止 message 由 HTTP/1.1 (或更高版本) proxy 接收并转发给 HTTP/1.0 recipient 时发生互操作失败. 它避免一种情况: 遵守协议会要求 proxy 上存在可能无限大的缓冲区.
解码 Chunked-Body 的示例过程见附录 19.4.6.
所有 HTTP/1.1 应用 MUST 能够接收并解码 "chunked" transfer-coding, 并且 MUST 忽略自己不理解的 chunk-extension 扩展.
3.7 Media Type
HTTP 在 Content-Type (第 14.17 节) 和 Accept (第 14.1 节) header field 中使用 Internet Media Types [17], 以提供开放且可扩展的数据类型标识和类型协商.
media-type = type "/" subtype *( ";" parameter )
type = token
subtype = token
parameter MAY 以 attribute/value 对形式跟在 type/subtype 之后 (如第 3.6 节定义).
type, subtype 和 parameter attribute name 都大小写不敏感. parameter value 可能大小写敏感, 也可能不敏感, 取决于 parameter name 的语义. type 与 subtype 之间, 以及 attribute 与其 value 之间 MUST NOT 使用 Linear white space (LWS). parameter 是否存在可能对 media-type 的处理有意义, 这取决于 media type registry 中的定义.
注意, 某些较旧 HTTP 应用无法识别 media type parameter. 向较旧 HTTP 应用发送数据时, 实现 SHOULD 只在该 type/subtype 定义要求时使用 media type parameter.
Media-type 值在 Internet Assigned Number Authority (IANA [19]) 注册. media type 注册过程概述见 RFC 1590 [17]. 不鼓励使用未注册 media type.
3.7.1 规范化和文本默认值
Internet media type 注册时带有 canonical form. 通过 HTTP message 传输的 entity-body, 除下一段定义的 "text" 类型外, MUST 在传输前以适当 canonical form 表示.
在 canonical form 中, "text" 类型的 media subtype 使用 CRLF 作为文本换行. HTTP 放宽了这一要求, 允许在整个 entity-body 内一致使用单独 CR 或 LF 表示换行来传输 text media. HTTP 应用 MUST 接受通过 HTTP 收到的 text media 中的 CRLF, 裸 CR 和裸 LF 作为换行表示. 此外, 如果文本使用的 character set 不分别用 octet 13 和 10 表示 CR 和 LF (某些多字节 character set 就是如此), HTTP 允许使用该 character set 定义的任何 octet 序列来表示等价于换行的 CR 和 LF. 关于换行的这种灵活性只适用于 entity-body 中的 text media; 在任何 HTTP control structure (如 header field 和 multipart boundary) 中, 裸 CR 或 LF MUST NOT 替代 CRLF.
如果 entity-body 使用 content-coding 编码, 则底层数据在编码前 MUST 采用上述定义的形式.
"charset" parameter 与某些 media type 一起使用, 用于定义数据的 character set (第 3.4 节). 当 sender 没有提供显式 charset parameter 时, 经 HTTP 接收的 "text" 类型 media subtype 被定义为默认 charset 值 "ISO-8859-1". 使用 "ISO-8859-1" 或其子集以外 character set 的数据 MUST 用适当 charset 值标记. 兼容性问题见第 3.4.1 节.
3.7.2 Multipart Type
MIME 提供若干 "multipart" 类型, 即在单个 message-body 中封装一个或多个 entity. 所有 multipart type 共享 RFC 2046
[40] 第 5.1.1 节定义的通用语法, 且 MUST 包含 boundary parameter 作为 media type value 的一部分. message body 本身是协议元素, 因此在 body-part 之间表示换行时 MUST 只使用 CRLF. 与 RFC 2046 不同, 任何 multipart message 的 epilogue MUST 为空; HTTP 应用 MUST NOT 传输 epilogue (即使原始 multipart 包含 epilogue). 这些限制用于保持 multipart message-body 的自定界性质, 其中 message-body 的 "end" 由结束 multipart boundary 表示.
一般而言, HTTP 对 multipart message-body 的处理与其他任何 media type 没有区别: 严格作为 payload. 唯一例外是 "multipart/byteranges" 类型 (附录 19.2) 出现在 206 (Partial Content) response 中时, 某些 HTTP caching mechanism 会按第 13.5.4 和 14.16 节所述解释它. 在所有其他情况下, HTTP user agent 在收到 multipart type 时 SHOULD 遵循与 MIME user agent 相同或相似的行为. multipart message-body 中每个 body-part 内的 MIME header field, 除其 MIME 语义定义的意义外, 对 HTTP 没有任何意义.
一般而言, HTTP user agent 在收到 multipart type 时 SHOULD 遵循与 MIME user agent 相同或相似的行为. 如果应用收到无法识别的 multipart subtype, 该应用 MUST 将其视为等价于 "multipart/mixed".
注意: "multipart/form-data" 类型已专门定义, 用于携带适合通过 POST request method 处理的 form data,
如 RFC 1867 [15] 所述.
3.8 Product Token
product token 用于允许通信应用通过软件名称和版本标识自身. 大多数字段在使用 product token 时, 也允许列出构成该应用重要组成部分的 sub-product, 以空白分隔. 按惯例, product 按其对标识应用的重要性顺序列出.
product = token ["/" product-version]
product-version = token
示例:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
Server: Apache/0.8.4
product token SHOULD 简短并切中要点. 它们 MUST NOT 用于广告或其他非必要信息. 虽然任意 token 字符 MAY 出现在 product-version 中, 但该 token SHOULD 只用于版本标识符 (即同一 product 的连续版本 SHOULD 只在 product value 的 product-version 部分不同).
3.9 Quality Value
HTTP content negotiation (第 12 节) 使用短 "floating point" 数字来表示各种可协商参数的相对重要性 ("weight"). weight 被规范化为 0 到 1 范围内的实数, 其中 0 为最小值, 1 为最大值. 如果某参数的 quality value 为 0, 则带有该参数的内容对 client 而言 `not acceptable'. HTTP/1.1 应用 MUST NOT 生成小数点后三位以上的数字. 用户对这些值的配置 SHOULD 也以这种方式限制.
qvalue = ( "0" [ "." 0*3DIGIT ] )
| ( "1" [ "." 0*3("0") ] )
"Quality values" 是一个误称, 因为这些值只表示期望质量的相对降低.
3.10 Language Tag
language tag 标识人类为向其他人类传达信息而说, 写或以其他方式表达的自然语言. 明确排除计算机语言. HTTP 在 Accept-Language 和 Content-Language 字段中使用 language tag.
HTTP language tag 的语法和注册表与 RFC 1766 [1] 定义相同. 简而言之, language tag 由一个或多个部分组成: 一个 primary language tag 和一个可能为空的 subtag 序列:
language-tag = primary-tag *( "-" subtag )
primary-tag = 1*8ALPHA
subtag = 1*8ALPHA
tag 内不允许空白, 且所有 tag 大小写不敏感. language tag 的命名空间由 IANA 管理. 示例 tag 包括:
en, en-US, en-cockney, i-cherokee, x-pig-latin
其中任何两字母 primary-tag 都是 ISO-639 语言缩写, 任何两字母初始 subtag 都是 ISO-3166 国家代码. (上面最后三个 tag 不是已注册 tag; 除最后一个外, 都是未来可注册 tag 的示例.)
3.11 Entity Tag
entity tag 用于比较来自同一被请求 resource 的两个或更多 entity. HTTP/1.1 在 ETag (第 14.19 节), If-Match (第 14.24 节), If-None-Match (第 14.26 节) 和 If-Range (第 14.27 节) header field 中使用 entity tag. 它们作为 cache validator 如何使用和比较的定义见第 13.3.3 节. entity tag 由一个不透明 quoted string 组成, 可能带有 weakness indicator 前缀.
entity-tag = [ weak ] opaque-tag
weak = "W/"
opaque-tag = quoted-string
只有当 resource 的两个 entity 按 octet equality 等价时, "strong entity tag" MAY 由这两个 entity 共享.
由 "W/" 前缀表示的 "weak entity tag", 只有当 resource 的两个 entity 等价且可以相互替代而不引起显著语义变化时, MAY 由二者共享. weak entity tag 只能用于 weak comparison.
entity tag MUST 在与特定 resource 关联的所有 entity 的所有版本之间唯一. 给定 entity tag 值 MAY 用于通过不同 URI 上的 request 获得的 entity. 将同一个 entity tag 值与通过不同 URI 上 request 获得的 entity 一起使用, 并不意味着这些 entity 等价.
3.12 Range Unit
HTTP/1.1 允许 client 请求 response entity 中只包含一部分 (一个 range). HTTP/1.1 在 Range (第 14.35 节) 和 Content-Range (第 14.16 节) header field 中使用 range unit. entity 可以按各种结构单元划分为 subrange.
range-unit = bytes-unit | other-range-unit
bytes-unit = "bytes"
other-range-unit = token
HTTP/1.1 定义的唯一 range unit 是 "bytes". HTTP/1.1 实现 MAY 忽略使用其他单位指定的 range.
HTTP/1.1 设计为允许实现不依赖 range 知识的应用.