4. Identifiers in HTTP (HTTP中的标识符)
统一资源标识符 (Uniform Resource Identifiers, URIs) [URI] 在整个HTTP中用作标识资源 (第3.1节) 的手段.
4.1. URI References (URI引用)
URI引用 (URI References) 用于定位请求、指示重定向和定义关系.
"URI-reference"、"absolute-URI"、"relative-part"、"authority"、"port"、"host"、"path-abempty"、"segment" 和 "query" 的定义采用自URI通用语法. 为可以包含非空路径组件的协议元素定义了 "absolute-path" 规则. (此规则与RFC 3986的path-abempty规则略有不同, 后者允许空路径, 以及不允许以 "//" 开头的路径的path-absolute规则.) 为可以包含相对URI但不包含片段组件的协议元素定义了 "partial-URI" 规则.
URI-reference = <URI-reference, see [URI], Section 4.1>
absolute-URI = <absolute-URI, see [URI], Section 4.3>
relative-part = <relative-part, see [URI], Section 4.2>
authority = <authority, see [URI], Section 3.2>
uri-host = <host, see [URI], Section 3.2.2>
port = <port, see [URI], Section 3.2.3>
path-abempty = <path-abempty, see [URI], Section 3.3>
segment = <segment, see [URI], Section 3.3>
query = <query, see [URI], Section 3.4>
absolute-path = 1*( "/" segment )
partial-URI = relative-part [ "?" query ]
HTTP中允许URI引用的每个协议元素将在其ABNF产生式中指示该元素是否允许任何形式的引用 (URI-reference)、仅允许绝对形式的URI (absolute-URI)、仅允许路径和可选查询组件 (partial-URI), 或上述的某种组合. 除非另有说明, URI引用相对于目标URI (第7.1节) 进行解析.
推荐 (RECOMMENDED) 所有发送方和接收方至少支持协议元素中长度为8000个八位字节的URI. 请注意, 这意味着某些结构和线路表示 (例如, HTTP/1.1中的请求行) 在某些情况下必然会更大.
4.2. HTTP-Related URI Schemes (HTTP相关的URI方案)
IANA在 https://www.iana.org/assignments/uri-schemes/ 维护URI方案注册表 [BCP35]. 尽管请求可能针对任何URI方案, 但以下方案是HTTP服务器固有的:
| URI方案 | 描述 | 章节 |
|---|---|---|
| http | 超文本传输协议 | 4.2.1 |
| https | 超文本传输协议安全 | 4.2.2 |
表 2
请注意, "http" 或 "https" URI的存在并不意味着在已识别源处始终有HTTP服务器监听连接. 任何人都可以创建URI, 无论服务器是否存在, 以及该服务器当前是否将该标识符映射到资源. 注册名称和IP地址的委托性质创建了一个联合命名空间 (Federated Namespace), 无论HTTP服务器是否存在.
4.2.1. http URI Scheme
"http" URI方案在此定义, 用于在由潜在HTTP源服务器管理的分层命名空间内创建标识符, 该服务器在给定端口上监听TCP ([TCP]) 连接.
http-URI = "http" "://" authority path-abempty [ "?" query ]
"http" URI的源服务器由authority组件标识, 该组件包括主机标识符 ([URI], 第3.2.2节) 和可选端口号 ([URI], 第3.2.3节). 如果端口子组件为空或未给出, 则TCP端口80 (WWW服务的保留端口) 是默认端口. 源确定谁有权对针对已识别资源的请求进行权威响应, 如第4.3.2节所定义.
发送方禁止 (MUST NOT) 生成具有空主机标识符的 "http" URI. 处理此类URI引用的接收方必须 (MUST) 将其作为无效而拒绝.
分层路径组件和可选查询组件标识该源服务器命名空间内的目标资源.
4.2.2. https URI Scheme
"https" URI方案在此定义, 用于在由潜在源服务器管理的分层命名空间内创建标识符, 该服务器在给定端口上监听TCP连接, 并能够建立已为HTTP通信安全保护的TLS ([TLS13]) 连接. 在此上下文中, "安全保护" (Secured) 具体是指服务器已被认证为代表已识别权威机构行事, 并且与该服务器的所有HTTP通信都具有客户端和服务器都可接受的机密性和完整性保护.
https-URI = "https" "://" authority path-abempty [ "?" query ]
"https" URI的源服务器由authority组件标识, 该组件包括主机标识符 ([URI], 第3.2.2节) 和可选端口号 ([URI], 第3.2.3节). 如果端口子组件为空或未给出, 则TCP端口443 (HTTP over TLS的保留端口) 是默认端口. 源确定谁有权对针对已识别资源的请求进行权威响应, 如第4.3.3节所定义.
发送方禁止 (MUST NOT) 生成具有空主机标识符的 "https" URI. 处理此类URI引用的接收方必须 (MUST) 将其作为无效而拒绝.
分层路径组件和可选查询组件标识该源服务器命名空间内的目标资源.
客户端必须 (MUST) 确保其对 "https" 资源的HTTP请求在通信之前是安全的, 并且它仅接受对这些请求的安全响应. 请注意, 客户端和服务器可接受的加密机制的定义通常是协商的, 并且可能随时间而变化.
通过 "https" 方案提供的资源与 "http" 方案没有共享身份. 它们是具有独立命名空间的不同源 (Origins). 但是, 定义为适用于具有相同主机的所有源的HTTP扩展, 如Cookie协议 [COOKIE], 允许一个服务设置的信息影响与匹配主机域组内其他服务的通信. 此类扩展应该非常小心地设计, 以防止从安全连接获得的信息在不安全的上下文中被无意交换.
4.2.3. http(s) Normalization and Comparison (http(s)规范化和比较)
具有 "http" 或 "https" 方案的URI根据 [URI] 第6节中定义的方法进行规范化和比较, 使用上述每个方案的默认值.
HTTP不要求使用特定方法来确定等价性. 例如, 缓存键可能在基于语法的规范化之后或基于方案的规范化之后作为简单字符串进行比较.
"http" 和 "https" URI的基于方案的规范化 ([URI] 第6.2.3节) 涉及以下附加规则:
-
如果端口等于方案的默认端口, 则正常形式是省略端口子组件.
-
当不用作OPTIONS请求的目标时, 空路径组件等效于绝对路径 "/", 因此正常形式是提供路径 "/" 而不是空路径.
-
方案和主机不区分大小写, 通常以小写形式提供; 所有其他组件以区分大小写的方式进行比较.
-
"reserved" 集合之外的字符等效于其百分比编码的八位字节: 正常形式是不对它们进行编码 (参见 [URI] 第2.1和2.2节).
例如, 以下三个URI是等效的:
http://example.com:80/~smith/home.html
http://EXAMPLE.com/%7Esmith/home.html
http://EXAMPLE.com:/%7esmith/home.html
规范化后 (使用任何方法) 等效的两个HTTP URI可以假定标识相同的资源, 任何HTTP组件都可以 (MAY) 执行规范化. 因此, 不同的资源不应该 (SHOULD NOT) 由规范化后等效的HTTP URI标识 (使用 [URI] 第6.2节中定义的任何方法).
4.2.4. Deprecation of userinfo in http(s) URIs (弃用http(s) URI中的userinfo)
authority的URI通用语法还包括用于在URI中包含用户认证信息的userinfo子组件 ([URI], 第3.2.1节). 在该子组件中, 弃用使用 "user:password" 格式.
一些实现使用userinfo组件进行认证信息的内部配置, 例如在命令调用选项、配置文件或书签列表中, 即使这种使用可能暴露用户标识符或密码.
当在消息中生成 "http" 或 "https" URI引用作为目标URI或字段值时, 发送方禁止 (MUST NOT) 生成userinfo子组件 (及其 "@" 分隔符).
在使用从不受信任的来源接收的 "http" 或 "https" URI引用之前, 接收方应该 (SHOULD) 解析userinfo并将其存在视为错误; 它很可能被用来为了钓鱼攻击而混淆权威机构.
4.2.5. http(s) References with Fragment Identifiers (带有片段标识符的http(s)引用)
片段标识符 (Fragment Identifiers) 允许独立于URI方案间接标识次要资源, 如 [URI] 第3.5节所定义. 一些引用URI的协议元素允许包含片段, 而其他则不允许. 它们通过使用允许片段的元素的ABNF规则来区分; 否则, 使用排除片段的特定规则.
注意: 片段标识符组件不是URI方案的方案定义的一部分 (参见 [URI] 第4.3节), 因此不会出现在上述 "http" 和 "https" URI方案的ABNF定义中.
4.3. Authoritative Access (权威访问)
权威访问 (Authoritative Access) 是指为了访问已识别资源而解引用给定标识符, 其方式是客户端认为是权威的 (由资源所有者控制). 确定是否授予访问权限的过程由URI方案定义, 并且通常使用URI组件内的数据, 例如使用通用语法时的authority组件. 但是, 权威访问不限于已识别的机制.
第4.3.1节将源 (Origin) 的概念定义为此类用途的辅助, 后续小节解释如何确定对等方有权代表源.
有关建立权威的安全考虑, 请参见第17.1节.
4.3.1. URI Origin (URI源)
给定URI的 "源" (Origin) 是方案、主机和端口的三元组, 在将方案和主机规范化为小写并规范化端口以删除任何前导零之后. 如果URI中省略了端口, 则使用该方案的默认端口. 例如, URI
https://Example.Com/happy.js
将具有源
{ "https", "example.com", "443" }
这也可以描述为始终存在端口的规范化URI前缀:
https://example.com:443
每个源定义其自己的命名空间, 并控制如何将该命名空间内的标识符映射到资源. 反过来, 源如何随时间一致地响应有效请求, 决定了用户将与URI关联的语义, 这些语义的有用性最终将这些机制转化为用户将来引用和访问的资源.
如果两个源在方案、主机或端口上不同, 则它们是不同的. 即使可以验证同一实体控制两个不同的源, 这两个源下的两个命名空间也是不同的, 除非由对该源具有权威的服务器明确别名.
源也在HTML和相关Web协议中使用, 超出本文档的范围, 如 [RFC6454] 中所述.
4.3.2. http Origins (http源)
尽管HTTP独立于传输协议, 但 "http" 方案 (第4.2.1节) 特定于将权威与控制在authority组件内标识的任何主机的指定端口上监听TCP连接的源服务器的任何人相关联. 这是一种非常弱的权威意义, 因为它取决于客户端特定的名称解析机制和可能不受路径上攻击者保护的通信. 尽管如此, 它是将 "http" 标识符绑定到源服务器以在受信任环境中进行一致解析的足够最小值.
如果主机标识符作为IP地址提供, 则源服务器是该IP地址上指定TCP端口的监听器 (如果有). 如果主机是注册名称, 则注册名称是与名称解析服务 (如DNS) 一起使用的间接标识符, 以查找适当源服务器的地址.
当在需要访问指定资源的上下文中使用 "http" URI时, 客户端可以 (MAY) 尝试通过将主机标识符解析为IP地址、在指定端口上建立到该地址的TCP连接, 并通过该连接发送包含与客户端目标URI匹配的请求目标的HTTP请求消息 (第7.1节) 来进行访问.
如果服务器使用非临时HTTP响应消息响应此类请求 (如第15节所述), 则该响应被视为对客户端请求的权威答案.
但是, 请注意, 上述方法不是获得权威响应的唯一手段, 也不意味着始终需要权威响应 (参见 [CACHING]). 例如, Alt-Svc头字段 [ALTSVC] 允许源服务器识别对该源也具有权威的其他服务. 对 "http" 标识资源的访问也可能由本文档范围之外的协议提供.
4.3.3. https Origins (https源)
"https" 方案 (第4.2.2节) 基于服务器使用与客户端认为对已识别源服务器可信的证书相对应的私钥的能力来关联权威. 客户端通常依赖于从某个预先安排或配置的信任锚传递的信任链来认为证书是可信的 (第4.3.4节).
在HTTP/1.1及更早版本中, 客户端仅在通过成功建立并安全保护的连接专门与该URI源的主机通信时才将权威归于服务器. 连接建立和证书验证用作权威的证明.
在HTTP/2和HTTP/3中, 如果URI源的主机与服务器证书中存在的任何主机匹配, 并且客户端认为它可以为该URI打开到该主机的连接, 则客户端在通过成功建立并安全保护的连接通信时将权威归于服务器. 实际上, 客户端将进行DNS查询以检查源的主机是否包含与已建立连接相同的服务器IP地址. 源服务器可以通过发送等效的ORIGIN帧 [RFC8336] 来删除此限制.
请求目标的主机和端口值在每个HTTP请求中传递, 标识源并将其与可能由同一服务器控制的其他命名空间区分开来 (第7.2节). 源有责任确保任何提供对其证书私钥控制的服务同样负责管理相应的 "https" 命名空间, 或至少准备拒绝似乎被误导的请求 (第7.4节).
即使源服务器有权这样做, 它也可能不愿意处理某些目标URI的请求. 例如, 当主机在不同端口上运行不同的服务时 (例如, 443和8000), 在源服务器上检查目标URI是必要的 (即使在连接已安全保护之后), 因为网络攻击者可能导致一个端口的连接在其他端口接收. 未能检查目标URI可能允许此类攻击者用来自另一个端口的看似权威的响应 (例如, "https://example.com:8000/foo") 替换对一个目标URI (例如, "https://example.com/foo") 的响应.
请注意, "https" 方案不依赖TCP和连接的端口号来关联权威, 因为两者都在安全通信之外, 因此不能被信任为确定性的. 因此, HTTP通信可能通过任何已安全保护的通道进行, 如第4.2.2节所定义, 包括不使用TCP的协议.
当在需要访问指定资源的上下文中使用 "https" URI时, 客户端可以 (MAY) 尝试通过将主机标识符解析为IP地址、在指定端口上建立到该地址的TCP连接、通过在TCP上成功启动具有机密性和完整性保护的TLS来端到端保护连接, 并通过该连接发送包含与客户端目标URI匹配的请求目标的HTTP请求消息 (第7.1节) 来进行访问.
如果服务器使用非临时HTTP响应消息响应此类请求 (如第15节所述), 则该响应被视为对客户端请求的权威答案.
但是, 请注意, 上述方法不是获得权威响应的唯一手段, 也不意味着始终需要权威响应 (参见 [CACHING]).
4.3.4. https Certificate Verification (https证书验证)
要建立安全连接以解引用URI, 客户端必须 (MUST) 验证服务的身份是否与URI源服务器可接受的匹配. 证书验证用于防止路径上攻击者或控制名称解析的攻击者进行服务器冒充. 此过程要求客户端配置一组信任锚 (Trust Anchors).
通常, 客户端必须 (MUST) 使用 [RFC6125] 第6节中定义的验证过程来验证服务身份. 客户端必须 (MUST) 从服务的主机构造引用身份 (Reference Identity): 如果主机是字面IP地址 (第4.3.5节), 则引用身份是IP-ID, 否则主机是名称, 引用身份是DNS-ID.
客户端禁止 (MUST NOT) 使用CN-ID类型的引用身份. 如 [RFC6125] 第6.2.1节所述, 较旧的客户端可能使用CN-ID类型的引用身份.
客户端可能被特别配置为接受替代形式的服务器身份验证. 例如, 客户端可能连接到地址和主机名动态的服务器, 期望服务将呈现特定证书 (或与某些外部定义的引用身份匹配的证书), 而不是与目标URI源匹配的证书.
在特殊情况下, 客户端简单地忽略服务器的身份可能是适当的, 但必须理解这会使连接容易受到主动攻击.
如果证书对目标URI的源无效, 则用户代理必须 (MUST) 在继续之前从用户获得确认 (参见第3.5节) 或以错误证书错误终止连接. 自动化客户端必须 (MUST) 将错误记录到适当的审计日志 (如果可用), 并应该 (SHOULD) 以错误证书错误终止连接. 自动化客户端可以 (MAY) 提供禁用此检查的配置设置, 但必须 (MUST) 提供启用它的设置.
4.3.5. IP-ID Reference Identity (IP-ID引用身份)
在 "https" URI的 "host" 字段中使用IP地址字面量标识的服务器具有IP-ID类型的引用身份. IP版本4地址使用 "IPv4address" ABNF规则, IP版本6地址使用带有 "IPv6address" 选项的 "IP-literal" 产生式; 参见 [URI] 第3.2.2节. IP-ID的引用身份包含IP地址的解码字节.
IP版本4地址为4个八位字节, IP版本6地址为16个八位字节. 未为任何其他IP版本定义IP-ID的使用. 证书subjectAltName扩展中的iPAddress选择不明确包含IP版本, 因此依赖于地址的长度来区分版本; 参见 [RFC5280] 第4.2.1.6节.
如果地址与证书subjectAltName扩展的iPAddress值相同, 则IP-ID类型的引用身份匹配.