Skip to content

Hypertext Transfer Protocol -- HTTP/1.1 ​

1. Introduction ​

1.1 Purpose ​

HTTP(超文本传输协议)是用于分布式、协作式超媒体信息系统的应用层协议。自 1990 年以来,HTTP 一直被用于全球信息网络(World-Wide Web)的全球信息倡议。HTTP/1.1 是对 HTTP/1.0 的改进,增加了对层次代理、缓存、持久连接和虚拟主机的支持。

1.2 Requirements ​

在此文档中,关键字"MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"MAY"和"OPTIONAL"按照 RFC 2119 的定义进行解释。实现如果未满足 MUST 或 REQUIRED 级别的要求,则不合规。

1.3 Terminology ​

  • Connection: 两个程序之间为通信目的建立的传输层虚拟电路。
  • Message: HTTP 通信的基本单位,由符合特定语法的八位字节序列组成,通过连接传输。
  • Request: HTTP 请求消息。
  • Response: HTTP 响应消息。
  • Resource: 通过 URI 标识的网络数据对象或服务。
  • Entity: 作为请求或响应负载传输的信息,包括实体头字段和实体主体。
  • Representation: 响应中包含的实体,可能有多种表示形式。
  • Content Negotiation: 服务请求时选择合适表示形式的机制。
  • Variant: 资源在特定时间点可能有一个或多个表示形式。
  • Client: 为发送请求而建立连接的程序。
  • User Agent: 发起请求的客户端,通常是浏览器、编辑器或其他终端用户工具。
  • Server: 接受连接以通过发送响应服务请求的应用程序。
  • Origin Server: 给定资源所在或将要创建的服务器。
  • Proxy: 代表其他客户端进行请求的中介程序。
  • Gateway: 作为其他服务器中介的服务器,接收请求如同它是请求资源的原服务器。
  • Tunnel: 在两个连接之间作为盲转发的中介程序。
  • Cache: 程序的本地响应消息存储和控制其存储、检索和删除的子系统。
  • Cacheable: 缓存允许存储响应消息副本以用于回答后续请求。
  • First-hand: 直接且无不必要延迟地从原服务器获得的响应。
  • Explicit Expiration Time: 原服务器打算实体不再由缓存返回而无需进一步验证的时间。
  • Heuristic Expiration Time: 当没有明确到期时间时由缓存分配的到期时间。
  • Age: 响应自从原服务器发送或成功验证以来的时间。
  • Freshness Lifetime: 响应生成与其到期时间之间的时间长度。
  • Fresh: 响应的年龄未超过其新鲜度生命周期。
  • Stale: 响应的年龄已超过其新鲜度生命周期。
  • Semantically Transparent: 缓存的使用不影响请求客户端或原服务器,除非是为了提高性能。
  • Validator: 用于确定缓存条目是否为实体等效副本的协议元素。
  • Upstream/Downstream: 描述消息流向:所有消息从上游流向下游。
  • Inbound/Outbound: 描述消息的请求和响应路径:“入站”表示“向原服务器流动”,“出站”表示“向用户代理流动”。

1.4 Overall Operation ​

HTTP 协议是一个请求/响应协议。客户端发送请求,服务器返回响应。请求包括请求方法、URI 和协议版本,后面跟随请求修饰符、客户端信息和可能的主体内容。服务器返回状态行,包括协议版本和成功或错误代码,后面跟随服务器信息、实体元信息和可能的实体主体内容。

2. Notational Conventions and Generic Grammar ​

2.1 Augmented BNF ​

所有机制都用增广的巴科斯 - 诺尔形式(BNF)描述,包含以下构造:

  • name = definition: 规则的名称和定义之间用等号分隔。
  • "literal": 引号内的文字表示字面文本,区分大小写。
  • rule1 | rule2: 用竖线分隔的元素表示替代选择。
  • (rule1 rule2): 括号内的元素作为单个元素处理。
  • *rule: 星号表示重复,形式为"<n>*<m>element",表示至少 n 次且最多 m 次出现。
  • [rule]: 方括号内的元素是可选的。
  • N rule: 特定重复次数,等价于"<n>*<n>(element)"。
  • #rule: 用于定义元素列表,形式为"<n>#<m>element",表示至少 n 个且最多 m 个元素,每个元素之间用逗号和可选的 LWS 分隔。
  • ; comment: 分号后的注释延续到行尾。
  • implied *LWS: 语法描述基于单词,除非另有说明,线性空白可在相邻单词之间插入而不改变字段解释。

2.2 Basic Rules ​

基本规则用于描述解析构造:

  • OCTET: 任意 8 位数据序列。
  • CHAR: 任意 US-ASCII 字符(八位组 0 - 127)。
  • UPALPHA: 任意 US-ASCII 大写字母“A”..“Z”。
  • LOALPHA: 任意 US-ASCII 小写字母“a”..“z”。
  • ALPHA: 大写或小写字母。
  • DIGIT: 任意 US-ASCII 数字“0”..“9”。
  • CTL: 任意 US-ASCII 控制字符(八位组 0 - 31)和 DEL(127)。
  • CR: US-ASCII 回车符(13)。
  • LF: US-ASCII 换行符(10)。
  • SP: US-ASCII 空格符(32)。
  • HT: US-ASCII 水平制表符(9)。
  • <">: US-ASCII 双引号(34)。

HTTP/1.1 定义 CR LF 作为所有协议元素的行尾标记。

3. Protocol Parameters ​

3.1 HTTP Version ​

HTTP 使用"<major>.<minor>"编号方案表示协议版本。协议版本指示消息格式和理解进一步 HTTP 通信的能力。<minor>号递增表示增加了不改变一般消息解析算法的特性,<major>号递增表示消息格式的改变。

3.2 Uniform Resource Identifiers ​

URI(统一资源标识符)是用于标识资源的格式化字符串,可以通过名称、位置或其他特征来标识资源。

3.3 Date/Time Formats ​

HTTP 应用程序允许三种不同格式表示日期/时间戳。所有 HTTP 日期/时间戳必须以格林尼治标准时间(GMT)表示。

3.4 Character Sets ​

HTTP 使用与 MIME 相同的“字符集”定义,指将八位字节序列转换为字符序列的方法。

3.5 Content Codings ​

内容编码值表示可以应用于实体的编码转换,主要用于允许文档压缩或其他有用的转换而不丢失其底层媒体类型和信息。

3.6 Transfer Codings ​

传输编码值用于指示为了确保网络中“安全传输”而已经、可以或可能需要应用于实体主体的编码转换。

3.7 Media Types ​

HTTP 使用互联网媒体类型在 Content-Type 和 Accept 头字段中提供开放和可扩展的数据类型和类型协商。

3.8 Product Tokens ​

产品标记用于允许通信应用程序通过软件名称和版本标识自己。

3.9 Quality Values ​

HTTP 内容协商使用短“浮点”数表示各种可协商参数的相对重要性(“权重”)。

3.10 Language Tags ​

语言标签标识自然语言,用于人类之间的信息交流。

3.11 Entity Tags ​

实体标签用于比较来自同一请求资源的两个或多个实体。HTTP/1.1 在 ETag、If-Match、If-None-Match 和 If-Range 头字段中使用实体标签。

3.12 Range Units ​

HTTP/1.1 允许客户端请求只包含响应实体的一部分(一个范围)。HTTP/1.1 在 Range 和 Content-Range 头字段中使用范围单位。

4. HTTP Message ​

4.1 Message Types ​

HTTP 消息包括从客户端到服务器的请求和从服务器到客户端的响应。

4.2 Message Headers ​

HTTP 头字段包括通用头、请求头、响应头和实体头字段,遵循 RFC 822 定义的通用格式。每个头字段由名称、冒号和字段值组成。

4.3 Message Body ​

HTTP 消息的消息体(如果有)用于携带与请求或响应相关的实体主体。消息体与实体主体只有在应用了传输编码时才不同。

4.4 Message Length ​

消息的传输长度是消息体在消息中出现的长度。传输长度由以下之一确定(按优先顺序):

  1. 不应包含消息体的响应消息由第一个空行终止。
  2. 如果存在 Transfer-Encoding 头字段且其值不是“identity”,则传输长度由“chunked”传输编码定义。
  3. 如果存在 Content-Length 头字段,其十进制值表示实体长度和传输长度。
  4. 如果消息使用“multipart/byteranges”媒体类型且未指定传输长度,则该自限定媒体类型定义传输长度。
  5. 通过服务器关闭连接。

4.5 General Header Fields ​

一些头字段具有通用适用性,但不适用于传输的实体。这些头字段仅适用于传输的消息。

5 Request ​

5.1 Request-Line ​

Request-Line 是 HTTP 请求消息的第一行,包含了以下几个元素:方法(Method)、请求 URI(Request-URI)和协议版本(HTTP-Version)。这些元素之间使用空格(SP)分隔,并以 CRLF 结束。

plaintext
Request-Line = Method SP Request-URI SP HTTP-Version CRLF

5.1.1 Method ​

Method 表示客户端希望对资源执行的操作。常见的方法包括:

  • OPTIONS:获取服务器支持的通信选项。
  • GET:请求指定资源的表示。
  • HEAD:与 GET 类似,但只请求响应头部。
  • POST:向指定资源提交数据进行处理。
  • PUT:向指定资源上传其最新内容。
  • DELETE:删除指定资源。
  • TRACE:回显服务器收到的请求,主要用于测试或诊断。
  • CONNECT:用于代理服务器,可以将连接转换为管道方式。

其他方法可以通过扩展定义,但必须在服务器和客户端之间达成一致。

5.1.2 Request-URI ​

Request-URI 是一个统一资源标识符(URI),用于标识请求的资源。它可以有以下几种形式:

  • *:此请求不针对特定资源,而是针对服务器本身。
  • absoluteURI:绝对 URI,通常用于代理请求。
  • abs_path:绝对路径,通常用于直接请求服务器上的资源。
  • authority:仅用于 CONNECT 方法。

5.2 The Resource Identified by a Request ​

通过检查 Request-URI 和 Host 头字段来确定请求标识的资源。服务器可以根据请求的主机名来区分资源。

5.3 Request Header Fields ​

请求头字段允许客户端向服务器传递额外的信息。这些字段可以修改请求的行为,类似于编程语言中的方法参数。常见的请求头字段包括:

  • Accept:指定客户端可以处理的内容类型。
  • Authorization:包含用于认证的凭据。
  • Host:指定请求的主机名。
  • User-Agent:标识发出请求的客户端软件。

6 Response ​

服务器在接收到并解释请求消息后,会返回一个 HTTP 响应消息。

plain
Response = Status-Line               ; Section 6.1
           *(( general-header        ; Section 4.5
            | response-header        ; Section 6.2
            | entity-header ) CRLF)  ; Section 7.1
           CRLF
           [ message-body ]          ; Section 7.2

6.1 Status-Line ​

Status-Line 是响应消息的第一行,包含协议版本、状态码和状态短语。

plaintext
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

6.1.1 Status Code and Reason Phrase ​

Status-Code 是一个三位数字,表示请求的处理结果。状态码的第一位数字表示响应的类别:

  • 1xx:信息性 - 请求已收到,继续处理。
  • 2xx:成功 - 请求已成功接收、理解并接受。
  • 3xx:重定向 - 需要进一步操作以完成请求。
  • 4xx:客户端错误 - 请求包含语法错误或无法完成。
  • 5xx:服务器错误 - 服务器未能完成明显有效的请求。

6.2 Response Header Fields ​

响应头字段允许服务器传递额外的信息,这些信息不能放在状态行中。常见的响应头字段包括:

  • Location:用于重定向的 URI。
  • Server:包含服务器软件的信息。
  • WWW-Authenticate:用于客户端认证的挑战。

7 Entity ​

请求和响应消息可以传输一个实体(entity),包含实体头字段和实体主体。

7.1 Entity Header Fields ​

实体头字段定义了关于实体主体或资源的元信息。常见的实体头字段包括:

  • Content-Type:实体主体的媒体类型。
  • Content-Length:实体主体的长度。
  • Last-Modified:资源的最后修改日期。

7.2 Entity Body ​

实体主体(如果存在)包含在 HTTP 请求或响应消息中,其格式和编码由实体头字段定义。

8 Connections ​

8.1 Persistent Connections ​

Persistent Connections 允许在一个 TCP 连接上发送多个请求和接收多个响应,从而减少连接的开销和网络拥塞。

8.1.1 Purpose ​

持久连接的主要优点包括:

  • 减少 CPU 和内存的使用。
  • 允许请求和响应的流水线处理,提高连接的利用效率。
  • 降低网络拥塞。
  • 减少后续请求的延迟。
  • 允许 HTTP 更加优雅地演进。

8.1.2 Overall Operation ​

在 HTTP/1.1 中,持久连接是默认行为。客户端和服务器通过 Connection 头字段来指示是否关闭连接。

8.1.2.2 Pipelining ​

客户端可以在持久连接上流水线发送请求,即在收到前一个响应之前发送多个请求。服务器必须按顺序返回响应。

9 Method Definitions ​

HTTP/1.1 定义了一组常用的方法,包括 GET、 POST、 PUT、 DELETE 等。每个方法都有特定的语义和使用场景。

9.1 Safe and Idempotent Methods ​

Safe Methods(安全方法)是指不会对服务器状态产生副作用的方法,例如 GET 和 HEAD。Idempotent Methods(幂等方法)是指无论执行多少次,其效果都相同的方法,例如 PUT 和 DELETE。

9.3 GET ​

GET 方法用于请求指定资源的表示。它是安全的、幂等的,并且可以被缓存。

9.4 HEAD ​

HEAD 方法与 GET 类似,但服务器只返回响应头部,不返回消息主体。主要用于获取资源的元数据。

9.5 POST ​

POST 方法用于向服务器提交数据。它通常用于表单提交、文件上传等操作。

9.6 PUT ​

PUT 方法用于向指定资源上传其最新内容。如果资源不存在,可以创建新资源。

9.7 DELETE ​

DELETE 方法用于请求服务器删除指定资源。

9.8 TRACE ​

TRACE 方法用于回显服务器收到的请求消息,主要用于测试或诊断。

9.9 CONNECT ​

CONNECT 方法用于代理服务器,可以将连接转换为管道方式(例如 SSL 隧道)。

10 Status Code Definitions ​

10.1 Informational 1xx ​

此类状态码表示临时响应,仅包含状态行和可选的头部字段,以空行结束。在 HTTP/1.0 中没有定义 1xx 状态码,因此服务器不得向 HTTP/1.0 客户端发送 1xx 响应,除非在实验条件下。客户端必须准备好接受一个或多个 1xx 状态响应,即使客户端未预期到 100 (Continue) 状态消息。代理必须转发 1xx 响应,除非代理与其客户端之间的连接已关闭,或代理本身请求生成 1xx 响应。

10.1.1 100 Continue ​

客户端应继续其请求。此中间响应用于通知客户端请求的初始部分已接收且未被服务器拒绝。客户端应继续发送请求的其余部分,或如果请求已完成,则忽略此响应。服务器在请求完成后必须发送最终响应。

10.1.2 101 Switching Protocols ​

服务器理解并愿意遵守客户端通过 Upgrade 消息头字段请求的协议切换。服务器将在 101 响应后的空行之后立即切换到响应的 Upgrade 头字段中定义的协议。

10.2 Successful 2xx ​

此类状态码表示客户端的请求已成功接收、理解并接受。

10.2.1 200 OK ​

请求成功。返回的信息取决于请求使用的方法,例如:

  • GET:响应中包含所请求资源的实体。
  • HEAD:响应中包含所请求资源的实体头字段,但不包含消息体。
  • POST:响应中包含描述或包含操作结果的实体。
  • TRACE:响应中包含服务器接收到的请求消息。

10.2.2 201 Created ​

请求已完成并且创建了一个新资源。新资源的 URI 由响应中的 Location 头字段提供。响应应包含一个实体,列出资源的特征和位置,供用户或用户代理选择最合适的一个。服务器必须在返回 201 状态码之前创建资源。

10.2.3 202 Accepted ​

请求已接受处理,但处理尚未完成。请求最终可能会被执行,也可能在实际处理时被拒绝。202 响应的目的是允许服务器接受一个请求进行其他处理,而不要求用户代理的连接持续到处理完成。

10.2.4 203 Non-Authoritative Information ​

返回的实体头信息不是从原服务器获得的最终集合,而是从本地或第三方副本收集的。此响应代码仅在响应本来会是 200 (OK) 时才适用。

10.2.5 204 No Content ​

服务器成功处理了请求,但不需要返回任何实体内容。响应可能包含新的或更新的元信息。204 响应不应包含消息体。

10.2.6 205 Reset Content ​

服务器成功处理了请求,且用户代理应重置导致请求发送的文档视图。此响应主要用于允许用户输入操作后清除输入表单。

10.2.7 206 Partial Content ​

服务器成功处理了部分 GET 请求。请求必须包含 Range 头字段,指示所需的范围。响应必须包含 Content-Range 头字段,指示响应中包含的范围,或包含 Content-Range 字段的 multipart/byteranges 内容类型。

10.3 Redirection 3xx ​

此类状态码表示需要进一步操作以完成请求。用户代理可以在不与用户交互的情况下执行这些操作,前提是第二个请求使用 GET 或 HEAD 方法。

10.3.1 300 Multiple Choices ​

请求的资源对应于一组表示中的任何一个,每个都有其特定的位置。响应应包含一个实体,列出资源的特征和位置,供用户或用户代理选择最合适的一个。

10.3.2 301 Moved Permanently ​

请求的资源已永久移动到新 URI。响应应包含 Location 头字段,指示新 URI。除非请求方法是 HEAD,否则响应实体应包含一个简短的超文本说明,带有指向新 URI 的超链接。

10.3.3 302 Found ​

请求的资源暂时位于不同的 URI。响应应包含 Location 头字段,指示临时 URI。除非请求方法是 HEAD,否则响应实体应包含一个简短的超文本说明,带有指向新 URI 的超链接。

10.3.4 303 See Other ​

请求的响应可以在不同的 URI 下找到,应使用 GET 方法获取该资源。此响应主要用于允许 POST 激活脚本的输出重定向到选定的资源。303 响应不应被缓存。

10.3.5 304 Not Modified ​

如果客户端执行了条件 GET 请求且允许访问,但文档未修改,服务器应返回此状态码。304 响应不应包含消息体。

10.3.6 305 Use Proxy ​

请求的资源必须通过 Location 头字段中给出的代理访问。305 响应只能由原服务器生成。

10.3.7 306 (Unused) ​

此状态码在先前版本的规范中使用,现已不再使用,代码保留。

10.3.8 307 Temporary Redirect ​

请求的资源暂时位于不同的 URI。响应应包含 Location 头字段,指示临时 URI。除非请求方法是 HEAD,否则响应实体应包含一个简短的超文本说明,带有指向新 URI 的超链接。

10.4 Client Error 4xx ​

4xx 类状态码表示客户端可能有错误。除非响应的是 HEAD 请求,服务器应包含一个实体,解释错误情况,并指明是临时还是永久条件。

10.4.1 400 Bad Request ​

请求由于语法错误无法被服务器理解。客户端不应在不修改的情况下重复请求。

10.4.2 401 Unauthorized ​

请求需要用户身份验证。响应必须包含一个 WWW-Authenticate 头字段,包含适用于请求资源的质询。客户端可以重复请求,并在 Authorization 头字段中包含适当的身份验证信息。

10.4.3 402 Payment Required ​

此代码保留供将来使用。

10.4.4 403 Forbidden ​

服务器理解请求,但拒绝执行。请求不应重复。

10.4.5 404 Not Found ​

服务器找不到请求的资源。没有指明该条件是临时还是永久的。410 (Gone) 状态码应在服务器知道资源永久不可用时使用。

10.4.6 405 Method Not Allowed ​

请求方法不允许用于请求的资源。响应必须包含一个 Allow 头字段,列出请求资源的有效方法。

10.4.7 406 Not Acceptable ​

请求的资源只能生成不符合请求中发送的 accept 头字段的响应实体。响应应包含一个实体,列出可用的实体特征和位置,供用户或用户代理选择。

10.4.8 407 Proxy Authentication Required ​

此代码类似于 401 (Unauthorized),但表示客户端必须先与代理进行身份验证。代理必须返回一个 Proxy-Authenticate 头字段,包含适用于请求资源的质询。

10.4.9 408 Request Timeout ​

客户端在服务器准备等待的时间内未能发送请求。客户端可以在任何时候重复请求。

10.4.10 409 Conflict ​

请求无法完成,因为与资源的当前状态冲突。响应实体应包含足够的信息,让用户识别冲突的来源。

10.4.11 410 Gone ​

请求的资源在服务器上不再可用,没有已知的转发地址。此条件应被视为永久的。410 响应主要用于通知接收者资源已故意不可用。

10.4.12 411 Length Required ​

服务器拒绝接受没有定义 Content-Length 的请求。客户端可以在添加有效的 Content-Length 头字段后重复请求。

10.4.13 412 Precondition Failed ​

请求头字段中的前提条件在服务器上测试时为假。此响应代码允许客户端对当前资源元信息设置前提条件,以防止请求方法应用于其他资源。

10.4.14 413 Request Entity Too Large ​

服务器拒绝处理请求,因为请求实体大于服务器愿意或能够处理的大小。如果该条件是暂时的,服务器应包含一个 Retry-After 头字段,指示何时可以重试。

10.4.15 414 Request-URI Too Long ​

服务器拒绝服务请求,因为 Request-URI 的长度超过服务器愿意解释的长度。这种情况很少见,通常发生在客户端错误地将 POST 请求转换为带有长查询信息的 GET 请求时。

10.4.16 415 Unsupported Media Type ​

服务器拒绝服务请求,因为请求实体的格式不受请求资源的请求方法支持。

10.4.17 416 Requested Range Not Satisfiable ​

服务器应返回此状态码,如果请求包含 Range 请求头字段,且该字段中的任何范围规范值都不与选定资源的当前范围重叠,并且请求未包含 If-Range 请求头字段。

10.4.18 417 Expectation Failed ​

服务器无法满足 Expect 请求头字段中给出的期望值,或者如果服务器是代理,服务器有明确的证据表明下一跳服务器无法满足请求。

10.5 Server Error 5xx ​

5xx 类状态码表示服务器知道自己出错或无法执行请求。除非响应的是 HEAD 请求,服务器应包含一个实体,解释错误情况,并指明是临时还是永久条件。

10.5.1 500 Internal Server Error ​

服务器遇到意外情况,无法完成请求。

10.5.2 501 Not Implemented ​

服务器不支持完成请求所需的功能。适用于服务器不识别请求方法并且无法为任何资源支持该方法的情况。

10.5.3 502 Bad Gateway ​

服务器作为网关或代理,从上游服务器收到无效响应。

10.5.4 503 Service Unavailable ​

服务器当前无法处理请求,因为服务器暂时过载或正在维护。此条件是暂时的,可能会在一段时间后解除。如果已知,延迟时间可以在 Retry-After 头字段中指示。

10.5.5 504 Gateway Timeout ​

服务器作为网关或代理,未能及时从上游服务器收到响应。

10.5.6 505 HTTP Version Not Supported ​

服务器不支持或拒绝支持请求消息中使用的 HTTP 协议版本。响应应包含一个实体,描述不支持该版本的原因以及服务器支持的其他协议。

11 Access Authentication ​

HTTP 提供了几种可选的挑战 - 响应认证机制,服务器可以使用这些机制来挑战客户端请求,客户端也可以使用这些机制提供认证信息。最基本的认证方式是“基本认证”和“摘要认证”,这些机制的详细规范在“HTTP Authentication: Basic and Digest Access Authentication”中有描述。具体来说,这些机制定义了“挑战”和“凭证”的概念。

12 Content Negotiation ​

大多数 HTTP 响应包含一个实体,该实体包含供人类用户解释的信息。为了提供给用户最合适的响应内容,HTTP 提供了内容协商机制。内容协商的目的是在多个可供选择的表示中选择一个最佳的表示。

12.1 Server-driven Negotiation ​

当服务器根据请求头字段(如 Accept、Accept-Language、Accept-Encoding 等)和请求相关的信息(如客户端的网络地址)来选择最佳表示时,这种协商方式称为服务器驱动的协商。服务器驱动的协商有以下优点和缺点:

优点:

  • 可以避免第二次请求的延迟,直接返回服务器认为最合适的响应。

缺点:

  • 服务器无法准确知道用户的最佳需求。
  • 每次请求都要描述用户代理的能力,可能效率低下并且影响用户隐私。
  • 增加了服务器实现和响应生成算法的复杂性。
  • 可能限制公共缓存对多个用户请求使用相同响应的能力。

12.2 Agent-driven Negotiation ​

用户代理在收到初始响应后,根据响应中包含的可用表示列表自行选择最佳表示。这种方式称为代理驱动的协商。代理驱动的协商有以下优点和缺点:

优点:

  • 适用于响应会在常用维度(如类型、语言或编码)上变化的情况。
  • 当服务器无法确定用户代理的能力时也能使用。
  • 在公共缓存用于分发服务器负载和减少网络使用时效果更佳。

缺点:

  • 需要第二次请求来获取最佳表示,效率依赖于缓存机制。

12.3 Transparent Negotiation ​

透明协商是服务器驱动和代理驱动协商的结合。当缓存能够理解响应的可变维度并使用代理驱动协商的信息进行服务器驱动的协商时,就形成了透明协商。透明协商的优点在于分担了原始服务器的负担,并消除了代理驱动协商的第二次请求延迟。

13 Caching in HTTP ​

HTTP 中的缓存机制旨在通过减少请求和响应的传输来提高性能。HTTP/1.1 提供了多种机制来实现这一目标,包括过期机制和验证机制。

13.1.1 Cache Correctness ​

一个正确的缓存必须确保其响应是最新的,满足以下条件之一:

  1. 通过与原始服务器重新验证响应的等效性。
  2. 响应是足够新鲜的。
  3. 响应是适当的 304(未修改)、305(代理重定向)或错误(4xx 或 5xx)响应消息。

13.1.2 Warnings ​

当缓存返回的响应既不是第一手的,也不是“足够新鲜”的时候,必须附加一个警告。警告可以让客户端采取适当的行动。

13.1.3 Cache-control Mechanisms ​

Cache-Control 头允许客户端或服务器在请求或响应中传输各种指令,这些指令通常会覆盖默认的缓存算法。

13.2 Expiration Model ​

13.2.1 Server-Specified Expiration ​

服务器可以通过在响应中提供一个明确的未来过期时间,来避免缓存每次都向原始服务器发出请求。服务器可以使用 Expires 头或 Cache-Control 头的 max-age 指令来指定过期时间。

13.2.2 Heuristic Expiration ​

当服务器未提供明确的过期时间时,缓存可以使用启发式算法来估算一个合理的过期时间。

13.3 Validation Model ​

当缓存有一个过期的条目并希望使用它作为响应时,必须先与原始服务器检查该条目是否仍然可用。这称为“验证”缓存条目。HTTP/1.1 支持条件方法来避免重新传输完整响应。

13.4 Response Cacheability ​

除非有特定的 Cache-Control 指令约束,缓存系统可以存储成功的响应,并在响应是新鲜的情况下返回它,而无需验证。

13.5 Constructing Responses From Caches ​

缓存的目的是存储响应信息以供将来请求使用。当缓存持有一个基于先前响应的缓存条目时,可能需要将新响应的部分内容与缓存条目中的内容结合起来。

13.6 Caching Negotiated Responses ​

使用服务器驱动的内容协商时,缓存可以使用 Vary 头字段来告知缓存哪些请求头字段用于选择多个表示中的一个。

13.7 Shared and Non-Shared Caches ​

出于安全和隐私的考虑,有必要区分“共享缓存”和“非共享缓存”。非共享缓存仅供单个用户访问,而共享缓存则可以被多个用户访问。

13.8 Errors or Incomplete Response Cache Behavior ​

缓存接收到不完整的响应时,可以将其存储为部分响应,但不能以 200(OK)状态码返回部分响应。

13.9 Side Effects of GET and HEAD ​

除非原始服务器明确禁止缓存其响应,GET 和 HEAD 方法的应用不应产生副作用。

13.10 Invalidation After Updates or Deletions ​

某些方法在原始服务器上执行后,可能会导致现有缓存条目变得无效。这些方法包括 PUT、DELETE 和 POST。

13.11 Write-Through Mandatory ​

所有可能导致原始服务器资源修改的方法必须通过写入原始服务器来完成。这包括除了 GET 和 HEAD 之外的所有方法。

13.12 Cache Replacement ​

如果从资源接收到一个新的可缓存响应,而缓存中已有相同资源的现有响应,缓存应使用新响应来回复当前请求。

13.13 History Lists ​

用户代理通常有历史机制,如“后退”按钮和历史列表,用于重新显示会话中先前检索到的实体。历史机制和缓存不同,历史机制应显示用户在资源检索时看到的内容,而不是资源的当前状态。

14 Header Field Definitions ​

本节定义了所有标准 HTTP/1.1 头字段的语法和语义。对于实体头字段,发送者和接收者可以是客户端或服务器,具体取决于谁发送和谁接收实体。

14.1 Accept ​

Accept 请求头字段用于指定响应中可接受的媒体类型。可以包含媒体范围和相对质量因子(q 值)。如果没有 Accept 头字段,假定客户端接受所有媒体类型。

14.2 Accept-Charset ​

Accept-Charset 请求头字段用于指示响应中可接受的字符集。字符集可以有一个关联的质量值(q 值)。如果没有 Accept-Charset 头字段,默认接受任何字符集。

14.3 Accept-Encoding ​

Accept-Encoding 请求头字段用于指定响应中可接受的内容编码。可以包含内容编码和相对质量因子(q 值)。如果没有 Accept-Encoding 头字段,假定客户端接受任何内容编码。

14.4 Accept-Language ​

Accept-Language 请求头字段用于指定响应中可接受的自然语言。每个语言范围可以有一个关联的质量值(q 值)。如果没有 Accept-Language 头字段,假定所有语言都同样可接受。

14.5 Accept-Ranges ​

Accept-Ranges 响应头字段允许服务器指示其是否接受对资源的范围请求。可以是 bytes 或 none。

14.6 Age ​

Age 响应头字段传达响应在原始服务器生成后的时间(以秒为单位)。缓存收到一个比其能表示的最大整数还大的值时,必须传输值为 2147483648 的 Age 头字段。

14.7 Allow ​

Allow 实体头字段列出资源支持的方法集合。必须在 405(方法不允许)响应中出现。

14.8 Authorization ​

Authorization 请求头字段用于包含用户代理的凭据信息,以便对资源进行身份验证。通常在收到 401 响应后使用。

14.9 Cache-Control ​

Cache-Control 通用头字段用于指定请求/响应链中所有缓存机制必须遵循的指令。指令可以控制缓存的行为,如 no-cache、 no-store、 max-age 等。

14.10 Connection ​

Connection 通用头字段允许发送者指定特定连接的选项,并且这些选项不能通过代理传递。HTTP/1.1 定义了 close 选项,表示在完成当前请求/响应后关闭连接。

14.11 Content-Encoding ​

Content-Encoding 实体头字段用于指示对实体主体应用了哪些内容编码,以便接收者解码以获取媒体类型。常见的值有 gzip、 compress 等。

14.12 Content-Language ​

Content-Language 实体头字段描述了实体的预期受众的自然语言。可以包含多个语言标签。

14.13 Content-Length ​

Content-Length 实体头字段指示发送给接收者的实体主体的大小(以八位字节为单位)。如果没有 Content-Length 头字段,消息长度由其他机制确定。

14.14 Content-Location ​

Content-Location 实体头字段用于提供消息中实体的资源位置。值可以是绝对 URI 或相对 URI。

14.15 Content-MD5 ​

Content-MD5 实体头字段是实体主体的 MD5 摘要,用于提供实体主体的端到端完整性检查。

14.16 Content-Range ​

Content-Range 实体头字段用于指定部分实体主体在完整实体主体中的位置。通常与 206(部分内容)状态码一起使用。

14.17 Content-Type ​

Content-Type 实体头字段指示发送给接收者的实体主体的媒体类型。例如: Content-Type: text/html; charset=ISO-8859-4。

14.18 Date ​

Date 通用头字段表示消息生成的日期和时间。必须以 RFC 1123 日期格式发送。

14.19 ETag ​

ETag 响应头字段提供请求变体的当前实体标签值,用于比较同一资源的其他实体。

14.20 Expect ​

Expect 请求头字段用于指示客户端需要服务器执行的特定行为。如果服务器不能满足 Expect 字段中的任何期望值,必须响应 417(期望失败)状态码。

14.21 Expires ​

Expires 实体头字段给出响应过期的日期和时间。过期的缓存条目通常不能返回,除非首先与原始服务器验证。

14.22 From ​

From 请求头字段包含控制请求用户代理的用户的电子邮件地址。主要用于日志记录和标识无效或不受欢迎的请求源。

14.23 Host ​

Host 请求头字段指定被请求资源的互联网主机和端口号。所有 HTTP/1.1 请求消息必须包含 Host 头字段。

14.24 If-Match ​

If-Match 请求头字段用于使请求条件化。客户端可以验证资源的一个或多个实体是否当前有效。

14.25 If-Modified-Since ​

If-Modified-Since 请求头字段用于使请求条件化:如果请求的变体自指定时间以来未被修改,服务器返回 304(未修改)响应。

14.26 If-None-Match ​

If-None-Match 请求头字段用于使请求条件化。客户端可以验证资源的一个或多个实体是否不再当前有效。

14.27 If-Range ​

If-Range 请求头字段允许客户端在实体未改变时请求部分实体,否则请求整个实体。

14.28 If-Unmodified-Since ​

If-Unmodified-Since 请求头字段用于使请求条件化:如果请求的资源自指定时间以来未被修改,服务器执行请求操作。

14.29 Last-Modified ​

Last-Modified 实体头字段指示服务器认为变体最后修改的日期和时间。

14.30 Location ​

Location 响应头字段用于重定向接收者到与请求 URI 不同的位置,以完成请求或标识新资源。

14.31 Max-Forwards ​

Max-Forwards 请求头字段用于限制 TRACE 和 OPTIONS 方法可以转发请求的代理或网关的次数。

14.32 Pragma ​

Pragma 通用头字段用于包含可能适用于请求/响应链中任何接收者的实现特定指令。主要用于向后兼容 HTTP/1.0。

14.33 Proxy-Authenticate ​

Proxy-Authenticate 响应头字段必须包含在 407(代理身份验证要求)响应中,包含适用于请求 URI 的身份验证方案和参数。

14.34 Proxy-Authorization ​

Proxy-Authorization 请求头字段允许客户端向需要身份验证的代理标识自己。仅适用于下一个需要身份验证的代理。

14.35 Range ​

Range 请求头字段用于请求实体的一个或多个子范围,而不是整个实体。服务器可以忽略 Range 头字段。

14.36 Referer ​

Referer 请求头字段允许客户端指定请求 URI 的来源地址。用于生成资源的反向链接列表、日志记录等。

14.37 Retry-After ​

Retry-After 响应头字段用于指示服务预期不可用的时间。可以是 HTTP 日期或秒数。

14.38 Server ​

Server 响应头字段包含处理请求的原始服务器软件信息。可以包含多个产品令牌和注释。

14.39 TE ​

TE 请求头字段指示客户端愿意接受的扩展传输编码和是否愿意接受块传输编码中的尾部字段。

14.40 Trailer ​

Trailer 通用字段值指示使用块传输编码的消息尾部中存在的头字段集合。

14.41 Transfer-Encoding ​

Transfer-Encoding 通用头字段指示为了安全传输消息主体而应用的转换类型。与内容编码不同,传输编码是消息的属性。

14.42 Upgrade ​

Upgrade 通用头字段允许客户端指定支持的其他通信协议,并希望服务器切换协议。服务器在 101(切换协议)响应中使用 Upgrade 头字段指示切换的协议。

14.43 User-Agent ​

User-Agent 请求头字段包含发起请求的用户代理信息。用于统计目的、协议违规跟踪和自动识别用户代理。

14.44 Vary ​

Vary 字段值指示在响应新鲜时,缓存是否允许使用响应来回复后续请求,而无需重新验证。 Vary 字段值为 * 表示缓存无法确定后续请求的适当表示。

14.45 Via ​

Via 通用头字段必须由网关和代理使用,以指示请求/响应链中的中间协议和接收者。用于跟踪消息转发、避免请求循环和标识所有发送者的协议能力。

14.46 Warning ​

Warning 通用头字段用于传递关于消息状态或转换的附加信息,通常用于警告缓存操作或实体主体转换可能导致的语义透明性缺失。

14.47 WWW-Authenticate ​

WWW-Authenticate 响应头字段必须包含在 401(未授权)响应消息中。字段值至少包含一个挑战,指示适用于请求 URI 的身份验证方案和参数。

15 Security Considerations ​

本节旨在告知应用程序开发人员、信息提供者和用户关于 HTTP/1.1 的安全限制。讨论并不包括这些问题的最终解决方案,但提供了一些减少安全风险的建议。

15.1 Personal Information ​

HTTP 客户端通常会接触到大量个人信息(例如用户的姓名、位置、邮件地址、密码、加密密钥等),应非常小心地防止通过 HTTP 协议无意泄露这些信息。建议提供方便的界面供用户控制这些信息的传播,设计者和实现者应特别注意这一领域。

15.1.1 Abuse of Server Log Information ​

服务器可以保存用户请求的个人数据,这些数据可能会识别用户的阅读模式或兴趣主题。这些信息显然是机密的,在某些国家受法律约束。使用 HTTP 协议提供数据的人有责任确保这些材料未经相关个人同意不会被分发。

15.1.2 Transfer of Sensitive Information ​

HTTP 无法控制传输数据的内容,也无法预先确定任何特定信息的敏感性。因此,应用程序应尽可能为信息提供者提供对这些信息的控制。特别是 Server、Via、Referer 和 From 头字段需要特别注意。

15.1.3 Encoding Sensitive Information in URI's ​

由于链接的来源可能是私密信息或可能泄露私人信息源,强烈建议用户能够选择是否发送 Referer 字段。例如,浏览器客户端可以有一个开关,用于公开/匿名浏览,分别启用/禁用 Referer 和 From 信息的发送。

15.1.4 Privacy Issues Connected to Accept Headers ​

Accept 请求头可以向所有访问的服务器透露用户信息。特别是 Accept-Language 头可能会透露用户认为是私密的信息,因为对特定语言的理解通常与特定民族群体的成员身份密切相关。

15.2 Attacks Based On File and Path Names ​

HTTP 服务器实现应小心限制通过 HTTP 请求返回的文档,仅限于服务器管理员打算提供的文档。如果 HTTP 服务器直接将 HTTP URI 转换为文件系统调用,则必须特别注意不提供不打算传递给 HTTP 客户端的文件。

15.3 DNS Spoofing ​

HTTP 客户端严重依赖域名服务,因此容易受到基于 IP 地址和 DNS 名称故意错误关联的安全攻击。客户端应谨慎假设 IP 号码/DNS 名称关联的持续有效性。

15.4 Location Headers and Spoofing ​

如果单个服务器支持多个不互信的组织,则必须检查这些组织控制下生成的响应中的 Location 和 Content-Location 头的值,以确保它们不会试图使其无权管理的资源失效。

15.5 Content-Disposition Issues ​

HTTP 中的 Content-Disposition 头源自 RFC 1806,具有一些严重的安全考虑。虽然 Content-Disposition 不是 HTTP 标准的一部分,但由于其广泛实现,我们记录了其使用和风险。

15.6 Authentication Credentials and Idle Clients ​

现有的 HTTP 客户端和用户代理通常会无限期地保留认证信息。HTTP/1.1 没有提供服务器指示客户端丢弃这些缓存凭据的方法。这是一个需要进一步扩展 HTTP 的重大缺陷。

15.7 Proxies and Caching ​

HTTP 代理本质上是中间人,可能导致中间人攻击。代理系统的妥协可能导致严重的安全和隐私问题。代理访问安全相关信息、个人信息和用户及内容提供者的专有信息。因此,代理操作员应像保护任何包含或传输敏感信息的系统一样保护运行代理的系统。

15.7.1 Denial of Service Attacks on Proxies ​

存在针对代理的拒绝服务攻击,防御困难,研究仍在继续,需保持警惕。