跳到主要内容

4. HTTP 消息 (HTTP Message)

4 HTTP 消息

4.1 消息类型

HTTP message 由 client 发往 server 的 request 和 server 发往 client 的 response 组成.

   HTTP-message   = Request | Response     ; HTTP/1.1 messages

Request (第 5 节) 和 Response (第 6 节) message 使用 RFC 822 [9] 的通用 message 格式来传输 entity (message 的 payload). 两种 message 都由 start-line, 零个或多个 header field (也称为 "headers"), 一个表示 header field 结束的空行 (即 CRLF 前没有任何内容的行), 以及可能存在的 message-body 组成.

    generic-message = start-line
*(message-header CRLF)
CRLF
[ message-body ]
start-line = Request-Line | Status-Line

为了健壮性, server SHOULD 忽略在预期 Request-Line 的位置收到的任何空行. 换言之, 如果 server 在 message 开头读取协议流时首先收到 CRLF, 它应忽略该 CRLF.

某些有缺陷的 HTTP/1.0 client 实现在 POST request 后生成额外 CRLF. 重申 BNF 已明确禁止的内容: HTTP/1.1 client MUST NOT 在 request 前添加额外 CRLF, 也 MUST NOT 在 request 后附加额外 CRLF.

4.2 消息头部

HTTP header field 包括 general-header (第 4.5 节), request-header (第 5.3 节), response-header (第 6.2 节) 和 entity-header (第 7.1 节), 它们遵循 RFC 822 [9] 第 3.1 节给出的相同通用格式. 每个 header field 由名称, 冒号 (":") 和字段值组成. field name 大小写不敏感. field value MAY 前置任意数量的 LWS, 但首选单个 SP. header field 可通过在每个额外行前放置至少一个 SP 或 HT 扩展到多行. 应用在生成 HTTP 构造时, 若已知或指定 "common form", 就应遵循该形式, 因为可能存在某些实现不能接受 common form 之外的形式.

  message-header = field-name ":" [ field-value ]
field-name = token
field-value = *( field-content | LWS )
field-content = <the OCTETs making up the field-value
and consisting of either *TEXT or combinations
of token, separators, and quoted-string>

field-content 不包括任何前导或尾随 LWS: 即 field-value 的第一个非空白字符之前或最后一个非空白字符之后出现的 linear white space. 可以移除此类前导或尾随 LWS, 而不改变字段值语义. 在解释字段值或向 downstream 转发 message 前, field-content 之间出现的任何 LWS MAY 被替换为单个 SP.

具有不同 field name 的 header field 的接收顺序并不重要. 但是, 先发送 general-header field, 再发送 request-header 或 response-header field, 最后发送 entity-header field 是 "good practice".

当且仅当某 header field 的整个 field-value 被定义为逗号分隔列表 [即 #(values)] 时, message 中 MAY 存在多个具有相同 field-name 的 message-header field. 通过把每个后续 field-value 追加到第一个 field-value 后面, 并用逗号分隔, MUST 能够将多个 header field 合并为一个 "field-name: field-value" 对, 且不改变 message 语义. 因此, 具有相同 field-name 的 header field 的接收顺序对合并后字段值的解释很重要, 所以 proxy 在转发 message 时 MUST NOT 改变这些 field value 的顺序.

4.3 消息主体

HTTP message 的 message-body (如果存在) 用于承载与 request 或 response 关联的 entity-body. 只有在应用了 transfer-coding 时, message-body 才不同于 entity-body, 这由 Transfer-Encoding header field 指示 (第 14.41 节).

   message-body = entity-body
| `<entity-body encoded as per Transfer-Encoding>`

Transfer-Encoding MUST 用于指示应用为了确保 message 安全且正确传输而应用的任何 transfer-coding. Transfer-Encoding 是 message 的属性, 不是 entity 的属性, 因此 MAY 由 request/response 链上的任何应用添加或移除. (不过, 第 3.6 节限制了某些 transfer-coding 可使用的时机.)

message 中何时允许 message-body 的规则对 request 和 response 不同.

request 中存在 message-body 由 request 的 message-header 中包含 Content-Length 或 Transfer-Encoding header field 表示. 如果 request method 的规范 (第 5.1.1 节) 不允许在 request 中发送 entity-body, 则 MUST NOT 在该 request 中包含 message-body. server SHOULD 读取并转发任意 request 上的 message-body; 如果 request method 没有为 entity-body 定义语义, 则处理 request 时 SHOULD 忽略该 message-body.

对 response message 而言, message 是否包含 message-body 同时取决于 request method 和 response status code (第 6.1.1 节). 对 HEAD request method 的所有 response MUST NOT 包含 message-body, 即使 entity-header field 的存在可能让人以为它包含 message-body. 所有 1xx (informational), 204 (no content) 和 304 (not modified) response MUST NOT 包含 message-body. 所有其他 response 都包含 message-body, 尽管其长度 MAY 为零.

4.4 消息长度

message 的 transfer-length 是 message-body 在 message 中出现时的长度; 即应用任何 transfer-coding 之后的长度. 当 message 包含 message-body 时, 该 body 的 transfer-length 按以下方式之一确定 (按优先级顺序):

  1. 任何 "MUST NOT" 包含 message-body 的 response message (如 1xx, 204 和 304 response, 以及对 HEAD request 的任何 response), 无论 message 中存在什么 entity-header field, 都始终由 header field 后的第一个空行终止.

  2. 如果存在 Transfer-Encoding header field (第 14.41 节) 且其值不是 "identity", 则 transfer-length 由 "chunked" transfer-coding (第 3.6 节) 的使用定义, 除非 message 通过关闭 connection 终止.

  3. 如果存在 Content-Length header field (第 14.13 节), 其以 OCTET 表示的十进制值同时代表 entity-length 和 transfer-length. 如果这两个长度不同 (即存在 Transfer-Encoding header field), MUST NOT 发送 Content-Length header field. 如果收到的 message 同时带有 Transfer-Encoding header field 和 Content-Length header field, 后者 MUST 被忽略.

  1. 如果 message 使用 media type "multipart/byteranges", 且 transfer-length 未以其他方式指定, 则该自定界 media type 定义 transfer-length. 除非 sender 知道 recipient 能够解析它, 否则 MUST NOT 使用该 media type; 来自 1.1 client 的 request 中出现带有多个 byte-range specifier 的 Range header, 暗示该 client 能够解析 multipart/byteranges response.

    Range header 可能由不理解 multipart/byteranges 的 1.0 proxy 转发; 在这种情况下, server MUST 使用本节第 1, 3 或 5 项中定义的方法定界 message.

  2. 由 server 关闭 connection 来确定. (关闭 connection 不能用于表示 request body 的结束, 因为这会使 server 无法发回 response.)

为兼容 HTTP/1.0 应用, 包含 message-body 的 HTTP/1.1 request MUST 包含有效的 Content-Length header field, 除非已知 server 符合 HTTP/1.1. 如果 request 包含 message-body 但未给出 Content-Length, server 在无法确定 message 长度时 SHOULD 响应 400 (bad request), 或者如果希望坚持收到有效 Content-Length, 则响应 411 (length required).

所有接收 entity 的 HTTP/1.1 应用 MUST 接受 "chunked" transfer-coding (第 3.6 节), 从而允许在无法预先确定 message 长度时对 message 使用该机制.

message MUST NOT 同时包含 Content-Length header field 和非 identity transfer-coding. 如果 message 确实包含非 identity transfer-coding, Content-Length MUST 被忽略.

当允许 message-body 的 message 中给出 Content-Length 时, 其字段值 MUST 与 message-body 中 OCTET 的数量精确匹配. HTTP/1.1 user agent 在收到并检测到无效长度时 MUST 通知用户.

4.5 通用头部字段

有少数 header field 对 request 和 response message 都具有通用适用性, 但并不适用于正在传输的 entity. 这些 header field 只适用于正在传输的 message.

   general-header = Cache-Control            ; Section 14.9
| Connection ; Section 14.10
| Date ; Section 14.18
| Pragma ; Section 14.32
| Trailer ; Section 14.40
| Transfer-Encoding ; Section 14.41
| Upgrade ; Section 14.42
| Via ; Section 14.45
| Warning ; Section 14.46

general-header field name 只有结合协议版本变化才能可靠扩展. 但是, 如果通信各方都认识到新的或实验性 header field 是 general-header field, 则可以赋予它们 general header field 的语义. 未识别的 header field 被当作 entity-header field 处理.