3. Request Line (请求行)
请求行 (request-line) 以方法标记 (method token) 开始,后跟一个空格 (SP)、请求目标 (request-target)、另一个空格 (SP),最后以协议版本结束。
request-line = method SP request-target SP HTTP-version
尽管请求行语法规则要求每个组成元素由单个 SP 八位字节分隔,但接收方可以 (MAY) 在空格分隔的单词边界上解析,除 CRLF 终止符外,将任何形式的空格视为 SP 分隔符,同时忽略前导或尾随空格; 这种空格包括以下八位字节中的一个或多个: SP、HTAB、VT (%x0B)、FF (%x0C) 或裸 CR。然而,如果消息有多个接收方且每个接收方对健壮性有自己独特的解释,宽松的解析可能会导致请求走私安全漏洞 (参见第 11.2 节)。
HTTP 不对请求行的长度设置预定义的限制,如 [HTTP] 第 2.3 节所述。收到比它实现的任何方法都长的方法的服务器应该 (SHOULD) 响应 501 (Not Implemented) 状态码。收到比它希望解析的任何 URI 都长的请求目标的服务器必须 (MUST) 响应 414 (URI Too Long) 状态码 (参见 [HTTP] 第 15.5.15 节)。
实践中存在各种对请求行长度的临时限制。推荐 (RECOMMENDED) 所有 HTTP 发送方和接收方至少支持 8000 个八位字节的请求行长度。
3.1. Method (方法)
方法标记 (method token) 指示要在目标资源上执行的请求方法。请求方法区分大小写。
method = token
本规范定义的请求方法可以在 [HTTP] 第 9 节中找到,以及有关 HTTP 方法注册表和定义新方法的考虑事项的信息。
3.2. Request Target (请求目标)
请求目标 (request-target) 标识要应用请求的目标资源。客户端从其所需的目标 URI 派生请求目标。请求目标有四种不同的格式,取决于所请求的方法以及请求是否发往代理。
request-target = origin-form
/ absolute-form
/ authority-form
/ asterisk-form
请求目标中不允许有空格。不幸的是,某些用户代理未能正确编码或排除超文本引用中的空格,导致这些不允许的字符在格式错误的请求行中作为请求目标发送。
无效请求行的接收方应该 (SHOULD) 响应 400 (Bad Request) 错误或 301 (Moved Permanently) 重定向并正确编码请求目标。接收方不应该 (SHOULD NOT) 尝试自动更正然后在没有重定向的情况下处理请求,因为无效的请求行可能是故意制作的以绕过请求链上的安全过滤器。
客户端必须 (MUST) 在所有 HTTP/1.1 请求消息中发送 Host 头字段 ([HTTP] 第 7.2 节)。如果目标 URI 包含权限组件 (authority component),则客户端必须 (MUST) 为 Host 发送与该权限组件相同的字段值,但不包括任何 userinfo 子组件及其 "@" 分隔符 ([HTTP] 第 4.2 节)。如果目标 URI 的权限组件缺失或未定义,则客户端必须 (MUST) 发送空字段值的 Host 头字段。
服务器必须 (MUST) 对任何缺少 Host 头字段的 HTTP/1.1 请求消息以及包含多个 Host 头字段行或具有无效字段值的 Host 头字段的任何请求消息响应 400 (Bad Request) 状态码。
3.2.1. origin-form
最常见的请求目标形式是 "origin-form" (源形式)。
origin-form = absolute-path [ "?" query ]
当直接向源服务器 (origin server) 发出请求时,除了 CONNECT 或服务器范围的 OPTIONS 请求 (详见下文) 之外,客户端必须 (MUST) 仅将目标 URI 的绝对路径和查询组件作为请求目标发送。如果目标 URI 的路径组件为空,客户端必须 (MUST) 发送 "/" 作为请求目标的 origin-form 中的路径。还会发送 Host 头字段,如 [HTTP] 第 7.2 节所定义。
例如,希望检索标识为以下资源的表示的客户端
http://www.example.org/where?q=now
将直接从源服务器打开 (或重用) 到主机 "www.example.org" 端口 80 的 TCP 连接并发送以下行:
GET /where?q=now HTTP/1.1
Host: www.example.org
然后是请求消息的其余部分。
3.2.2. absolute-form
当向代理发出请求时,除了 CONNECT 或服务器范围的 OPTIONS 请求 (详见下文) 之外,客户端必须 (MUST) 以 "absolute-form" (绝对形式) 将目标 URI 作为请求目标发送。
absolute-form = absolute-URI
请求代理从有效缓存中服务该请求 (如果可能),或者代表客户端向下一个入站代理服务器或直接向请求目标指示的源服务器发出相同的请求。有关此类消息 "转发" (forwarding) 的要求在 [HTTP] 第 7.6 节中定义。
绝对形式的请求行示例如下:
GET http://www.example.org/pub/WWW/TheProject.html HTTP/1.1
即使请求目标是绝对形式,客户端也必须 (MUST) 在 HTTP/1.1 请求中发送 Host 头字段,因为这允许 Host 信息通过可能未实现 Host 的古老 HTTP/1.0 代理转发。
当代理收到具有绝对形式请求目标的请求时,代理必须 (MUST) 忽略收到的 Host 头字段 (如果有),而是用请求目标的主机信息替换它。转发此类请求的代理必须 (MUST) 基于收到的请求目标生成新的 Host 字段值,而不是转发收到的 Host 字段值。
当源服务器收到具有绝对形式请求目标的请求时,源服务器必须 (MUST) 忽略收到的 Host 头字段 (如果有),而是使用请求目标的主机信息。请注意,如果请求目标没有权限组件,在这种情况下将发送空的 Host 头字段。
服务器必须 (MUST) 接受请求中的绝对形式,即使大多数 HTTP/1.1 客户端只会向代理发送绝对形式。
3.2.3. authority-form
请求目标的 "authority-form" (权限形式) 仅用于 CONNECT 请求 ([HTTP] 第 9.3.6 节)。它仅由隧道目标的 uri-host 和端口号组成,由冒号 (":") 分隔。
authority-form = uri-host ":" port
当发出 CONNECT 请求以通过一个或多个代理建立隧道时,客户端必须 (MUST) 仅将隧道目标的主机和端口作为请求目标发送。客户端从目标 URI 的权限组件获取主机和端口,但如果目标 URI 省略端口,则发送方案的默认端口。例如,到 "http://www.example.com" 的 CONNECT 请求如下所示:
CONNECT www.example.com:80 HTTP/1.1
Host: www.example.com
3.2.4. asterisk-form
请求目标的 "asterisk-form" (星号形式) 仅用于服务器范围的 OPTIONS 请求 ([HTTP] 第 9.3.7 节)。
asterisk-form = "*"
当客户端希望为整个服务器而不是该服务器的特定命名资源请求 OPTIONS 时,客户端必须 (MUST) 仅发送 "*" (%x2A) 作为请求目标。例如:
OPTIONS * HTTP/1.1
如果代理收到具有绝对形式请求目标的 OPTIONS 请求,其中 URI 具有空路径且没有查询组件,则请求链上的最后一个代理在将请求转发到指示的源服务器时必须 (MUST) 发送 "*" 的请求目标。
例如,请求
OPTIONS http://www.example.org:8001 HTTP/1.1
将由最终代理转发为
OPTIONS * HTTP/1.1
Host: www.example.org:8001
在连接到主机 "www.example.org" 的端口 8001 后。
3.3. Reconstructing the Target URI (重构目标URI)
当请求目标是绝对形式时,目标 URI 就是请求目标。在这种情况下,服务器将解析 URI 为其通用组件以进行进一步评估。
否则,服务器从连接上下文和请求消息的各个部分重构目标 URI,以便识别目标资源 ([HTTP] 第 7.1 节):
-
如果服务器的配置为固定的 URI 方案提供,或者方案由受信任的出站网关提供,则该方案用于目标 URI。这在大规模部署中很常见,因为网关服务器将接收客户端的连接上下文并用它们自己与入站服务器的连接替换。否则,如果通过安全连接收到请求,则目标 URI 的方案是 "https"; 如果不是,则方案是 "http"。
-
如果请求目标是权限形式,则目标 URI 的权限组件是请求目标。否则,目标 URI 的权限组件是 Host 头字段的字段值。如果没有 Host 头字段或其字段值为空或无效,则目标 URI 的权限组件为空。
-
如果请求目标是权限形式或星号形式,则目标 URI 的组合路径和查询组件为空。否则,目标 URI 的组合路径和查询组件是请求目标。
-
一旦如上所述确定,重构的目标 URI 的组件可以通过连接方案、"://"、权限和组合路径及查询组件来重组为绝对 URI 形式。
示例 1: 通过安全连接收到的以下消息
GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.example.org
具有目标 URI
https://www.example.org/pub/WWW/TheProject.html
示例 2: 通过非安全连接收到的以下消息
OPTIONS * HTTP/1.1
Host: www.example.org:8080
具有目标 URI
http://www.example.org:8080