Skip to main content

3. Terminology and Core Concepts (术语和核心概念)

HTTP是为万维网 (World Wide Web, WWW) 架构创建的, 并随着时间的推移而演进, 以支持全球超文本系统的可扩展性需求. 该架构的大部分内容反映在用于定义HTTP的术语中.

3.1. Resources (资源)

HTTP请求的目标称为"资源" (Resource). HTTP不限制资源的性质; 它仅定义了一个可用于与资源交互的接口. 大多数资源由统一资源标识符 (Uniform Resource Identifier, URI) 标识, 如第4节所述.

HTTP的一个设计目标是将资源标识与请求语义分离, 这是通过将请求语义赋予请求方法 (第9节) 和一些请求修改头字段来实现的. 资源不能以与请求方法语义不一致的方式处理请求. 例如, 尽管资源的URI可能暗示不安全的语义, 但当使用安全方法 (Safe Method) 处理请求时, 客户端可以期望资源避免不安全的操作 (参见第9.2.1节).

HTTP依赖于统一资源标识符 (URI) 标准 [URI] 来指示目标资源 (第7.1节) 和资源之间的关系.

3.2. Representations (表示)

"表示" (Representation) 是旨在反映给定资源的过去、当前或期望状态的信息, 采用可通过协议轻松传达的格式. 表示由一组表示元数据 (Representation Metadata) 和可能无界的表示数据流 (Representation Data, 第8节) 组成.

HTTP通过定义关于资源状态的可传输表示的通信, 而不是传输资源本身, 在其统一接口背后实现"信息隐藏" (Information Hiding). 这允许URI标识的资源可以是任何东西, 包括像"拉古纳海滩的当前天气"这样的时间函数, 同时可能提供在生成消息时代表该资源的信息 [REST].

统一接口类似于一个窗口, 通过该窗口只能通过向另一侧的独立行为者传达消息来观察和作用于某物. 需要一个共享抽象来"表示" (代替) 我们通信中该事物的当前或期望状态. 当表示是超文本时, 它既可以提供资源状态的表示, 也可以提供帮助指导接收方未来交互的处理指令.

目标资源可能被提供或能够生成多个表示, 每个表示都旨在反映资源的当前状态. 通常基于内容协商 (Content Negotiation, 第12节) 的算法将用于选择这些表示中的一个作为最适用于给定请求的表示. 这个"选定的表示" (Selected Representation) 为评估条件请求 (第13节) 和构造对GET (第9.3.1节) 的200 (OK)、206 (Partial Content) 和304 (Not Modified) 响应的内容提供数据和元数据.

3.3. Connections, Clients, and Servers (连接、客户端和服务器)

HTTP是一个客户端/服务器协议, 通过可靠的传输层或会话层"连接" (Connection) 运行.

HTTP"客户端" (Client) 是一个程序, 它建立到服务器的连接以发送一个或多个HTTP请求. HTTP"服务器" (Server) 是一个程序, 它接受连接以通过发送HTTP响应来服务HTTP请求.

术语客户端和服务器仅指这些程序在特定连接中执行的角色. 同一程序可能在某些连接上充当客户端, 在其他连接上充当服务器.

HTTP被定义为无状态协议 (Stateless Protocol), 这意味着每个请求消息的语义可以单独理解, 并且连接与其上的消息之间的关系不会影响对这些消息的解释. 例如, CONNECT请求 (第9.3.6节) 或带有Upgrade头字段 (第7.8节) 的请求可以在任何时候发生, 而不仅仅是在连接上的第一条消息中. 许多实现依赖HTTP的无状态设计来重用代理连接或跨多个服务器动态负载均衡请求.

因此, 服务器禁止 (MUST NOT) 假设同一连接上的两个请求来自同一用户代理, 除非该连接是安全的并且专用于该代理. 已知一些非标准HTTP扩展 (例如, [RFC4559]) 违反了此要求, 导致安全性和互操作性问题.

3.4. Messages (消息)

HTTP是一个无状态的请求/响应协议, 用于通过连接交换"消息" (Messages). 术语"发送方" (Sender) 和"接收方" (Recipient) 分别指发送或接收给定消息的任何实现.

客户端以"请求" (Request) 消息的形式向服务器发送请求, 该消息包含方法 (第9节) 和请求目标 (第7.1节). 请求还可能包含用于请求修饰符、客户端信息和表示元数据的头字段 (第6.3节), 用于根据方法处理的内容 (第6.4节), 以及用于传达在发送内容时收集的信息的尾部字段 (第6.5节).

服务器通过发送一个或多个"响应" (Response) 消息来响应客户端的请求, 每个响应包含一个状态码 (第15节). 响应还可能包含用于服务器信息、资源元数据和表示元数据的头字段, 根据状态码解释的内容, 以及用于传达在发送内容时收集的信息的尾部字段.

3.5. User Agents (用户代理)

术语"用户代理" (User Agent) 指发起请求的各种客户端程序中的任何一个.

用户代理最熟悉的形式是通用Web浏览器, 但这只是实现的一小部分. 其他常见的用户代理包括爬虫 (Spiders, 网络遍历机器人)、命令行工具、广告牌屏幕、家用电器、秤、灯泡、固件更新脚本、移动应用程序以及各种形状和大小的通信设备.

作为用户代理并不意味着在请求时有人类用户直接与软件代理交互. 在许多情况下, 用户代理被安装或配置为在后台运行, 并保存其结果以供以后检查 (或仅保存可能有趣或错误的结果子集). 例如, 爬虫通常被赋予一个起始URI, 并配置为在将Web作为超文本图遍历时遵循某些行为.

许多用户代理不能或选择不向其用户提供交互式建议或为安全或隐私问题提供充分警告. 在本规范要求向用户报告错误的少数情况下, 此类报告仅在错误控制台或日志文件中可观察是可以接受的. 同样, 要求在继续之前由用户确认自动操作的要求可能通过预先配置选择、运行时选项或简单地避免不安全操作来满足; 如果用户已经做出该选择, 确认并不意味着任何特定的用户界面或正常处理的中断.

3.6. Origin Server (源服务器)

术语"源服务器" (Origin Server) 指可以为给定目标资源发起权威响应 (Authoritative Responses) 的程序.

源服务器最熟悉的形式是大型公共网站. 然而, 就像用户代理被等同于浏览器一样, 很容易被误导认为所有源服务器都是相似的. 常见的源服务器还包括家庭自动化单元、可配置网络组件、办公机器、自主机器人、新闻源、交通摄像头、实时广告选择器和视频点播平台.

大多数HTTP通信包括对由URI标识的某个资源的表示的检索请求 (GET). 在最简单的情况下, 这可能通过用户代理 (UA) 和源服务器 (O) 之间的单个双向连接 (===) 来完成.

       request   >
UA ======================================= O
< response

图 1

3.7. Intermediaries (中间人)

HTTP允许使用中间人 (Intermediaries) 通过连接链来满足请求. HTTP"中间人"有三种常见形式: 代理 (Proxy)、网关 (Gateway) 和隧道 (Tunnel). 在某些情况下, 单个中间人可能充当源服务器、代理、网关或隧道, 根据每个请求的性质切换行为.

       >             >             >             >
UA =========== A =========== B =========== C =========== O
< < < <

图 2

上图显示了用户代理和源服务器之间的三个中间人 (A、B和C). 遍历整个链的请求或响应消息将经过四个独立的连接. 某些HTTP通信选项可能仅适用于与最近的非隧道邻居的连接, 仅适用于链的端点, 或适用于链上的所有连接. 尽管图表是线性的, 但每个参与者可能参与多个同时进行的通信. 例如, B可能同时从A以外的许多客户端接收请求, 和/或将请求转发到C以外的服务器, 同时处理A的请求. 同样, 后续请求可能通过不同的连接路径发送, 通常基于负载均衡的动态配置.

术语"上游" (Upstream) 和"下游" (Downstream) 用于描述与消息流相关的方向要求: 所有消息从上游流向下游. 术语"入站" (Inbound) 和"出站" (Outbound) 用于描述与请求路由相关的方向要求: 入站表示"朝向源服务器", 而出站表示"朝向用户代理".

"代理" (Proxy) 是由客户端选择的消息转发代理, 通常通过本地配置规则, 以接收某些类型的绝对URI的请求, 并尝试通过HTTP接口的转换来满足这些请求. 一些转换是最小的, 例如对"http" URI的代理请求, 而其他请求可能需要与完全不同的应用层协议之间的转换. 代理通常用于通过公共中间人对组织的HTTP请求进行分组, 以实现安全服务、注释服务或共享缓存. 一些代理被设计为在转发时对选定的消息或内容应用转换, 如第7.7节所述.

"网关" (Gateway, 也称为"反向代理" Reverse Proxy) 是一个中间人, 它充当出站连接的源服务器, 但转换接收到的请求并将其入站转发到另一个或多个服务器. 网关通常用于封装遗留或不受信任的信息服务, 通过"加速器" (Accelerator) 缓存提高服务器性能, 以及跨多台机器实现HTTP服务的分区或负载均衡.

所有适用于源服务器的HTTP要求也适用于网关的出站通信. 网关使用其所需的任何协议与入站服务器通信, 包括本规范范围之外的HTTP私有扩展. 但是, 希望与第三方HTTP服务器互操作的HTTP到HTTP网关需要符合网关入站连接上的用户代理要求.

"隧道" (Tunnel) 充当两个连接之间的盲中继, 而不更改消息. 一旦激活, 隧道不被视为HTTP通信的一方, 尽管隧道可能是由HTTP请求发起的. 当中继连接的两端都关闭时, 隧道不再存在. 隧道用于通过中间人扩展虚拟连接, 例如当使用传输层安全性 (Transport Layer Security, TLS, [TLS13]) 通过共享防火墙代理建立机密通信时.

上述中间人类别仅考虑那些作为HTTP通信参与者的中间人. 还有一些中间人可以在网络协议栈的较低层上运行, 在没有消息发送方的知识或许可的情况下过滤或重定向HTTP流量. 网络中间人在协议级别上与路径上的攻击者无法区分, 经常由于错误地违反HTTP语义而引入安全漏洞或互操作性问题.

例如, "拦截代理" (Interception Proxy) [RFC3040] (也通常称为"透明代理" Transparent Proxy [RFC1919]) 与HTTP代理不同, 因为它不是由客户端选择的. 相反, 拦截代理过滤或重定向出站TCP端口80数据包 (偶尔还有其他常见端口流量). 拦截代理通常出现在公共网络接入点上, 作为在允许使用非本地互联网服务之前强制执行帐户订阅的手段, 以及在公司防火墙内强制执行网络使用策略.

3.8. Caches (缓存)

"缓存" (Cache) 是先前响应消息的本地存储以及控制其消息存储、检索和删除的子系统. 缓存存储可缓存的响应, 以减少未来等效请求的响应时间和网络带宽消耗. 任何客户端或服务器都可以 (MAY) 使用缓存, 尽管在充当隧道时不能使用缓存.

缓存的效果是, 如果链上的参与者之一具有适用于该请求的缓存响应, 则请求/响应链会缩短. 下图说明了如果B具有O (通过C) 的早期响应的缓存副本, 并且该请求尚未被UA或A缓存, 则产生的链.

          >             >
UA =========== A =========== B - - - - - - C - - - - - - O
< <

图 3

如果允许缓存存储响应消息的副本以用于回答后续请求, 则响应是"可缓存的" (Cacheable). 即使响应是可缓存的, 客户端或源服务器也可能对何时可以将该缓存响应用于特定请求施加额外的约束. HTTP对缓存行为和可缓存响应的要求在 [CACHING] 中定义.

在万维网和大型组织内部署了各种各样的缓存架构和配置. 这些包括用于节省带宽和减少延迟的代理缓存的国家层次结构, 使用网关缓存优化流行站点的区域和全球分发的内容分发网络, 广播或多播缓存条目的协作系统, 用于离线或高延迟环境的预取缓存条目存档等.

3.9. Example Message Exchange (消息交换示例)

以下示例说明了对URI "http://www.example.com/hello.txt" 的GET请求 (第9.3.1节) 的典型HTTP/1.1消息交换:

客户端请求:

GET /hello.txt HTTP/1.1
User-Agent: curl/7.64.1
Host: www.example.com
Accept-Language: en, mi

服务器响应:

HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain

Hello World! My content includes a trailing CRLF.