互联网工程任务组(IETF)编辑R.Fielding
征求意见:9112土砖
过时:7230M.Nottingham,编辑
标准:99快速地
类别:标准轨道J.Reschke,编辑
编号:2070-1721绿色字节
2022年6月

HTTP/1.1协议


摘要

超文本传输协议(HTTP)是一种用于分布式、协作、超文本信息系统的无状态应用程序级协议。本文档规定了HTTP/1.1消息语法、消息解析、连接管理和相关安全问题。

本文件废除了RFC 7230的部分内容。

关于下段备忘

这是一个互联网标准跟踪文档。

本文件是互联网工程任务组(IETF)的产品。它代表了IETF社区的共识。它已接受公众审查,并已被互联网工程指导小组(IESG)批准发布。有关互联网标准的更多信息,请访问RFC 7841第2节.

有关本文件当前状态、任何勘误表以及如何提供反馈的信息,请访问https://www.rfc-editor.org/info/rfc9112.

版权声明

版权所有(c)2022 IETF Trust和被认定为文件作者的人员。保留所有权利。

本文件受BCP 78和IETF信托基金有关IETF文件的法律规定的约束(https://trustee.ietf.org/license-info)自本文件发布之日起生效。请仔细阅读这些文件,因为它们描述了您对本文件的权利和限制。从本文件中提取的代码组件必须包括信托法律条款第4.e节中所述的经修订的BSD许可证文本,并按照经修订的BS D许可证中所述提供无担保。

本文件可能包含2008年11月10日之前发布或公开的IETF文件或IETF贡献中的材料。控制部分材料版权的人员可能没有授予IETF信托机构允许在IETF标准过程之外修改此类材料的权利。在未获得此类材料版权控制人员的充分许可的情况下,不得在IETF标准过程之外修改本文件,也不得在IETF标准过程以外创建其衍生作品,除非将其格式化以作为RFC发布或将其翻译为英语以外的语言。

1 介绍

超文本传输协议(HTTP)是一种无状态应用程序级请求/响应协议,它使用可扩展语义和自描述消息与基于网络的超文本信息系统进行灵活交互。HTTP/1.1定义如下:

本文档指定了如何使用HTTP/1.1消息语法、框架和连接管理机制来传递HTTP语义。其目标是定义HTTP/1.1消息解析器和消息转发中介的完整需求集。

本文件废除了副本请求7230与HTTP/1.1消息传递和连接管理相关,更改汇总在附录C.3。的其他部分副本请求7230被“HTTP语义”淘汰【HTTP】.

1.1. 需求符号

关键词“必须", "不能", "必修的", "", "不得", "应该", "不应该", "推荐", "不推荐", "5月“、和”可选“本文件中的解释如BCP 14所述[RFC2119] [RFC8174]当且仅当它们出现在所有大写字母中时,如图所示。

关于错误处理的一致性标准和注意事项在第2节属于【HTTP】.

1.2、。 语法符号

本规范使用增广Backus-Naur形式(ABNF)表示法[RFC5234],使用中定义的字符串中区分大小写的符号进行扩展[RFC7405].

它还使用在中定义的列表扩展名第5.6.1节属于【HTTP】,这允许使用“#”运算符对逗号分隔的列表进行紧凑定义(类似于“*”运算符指示重复的方式)。附录A显示了收集的语法,其中所有列表运算符都扩展为标准ABNF表示法。

按照惯例,前缀为“obs-”的ABNF规则名称表示由于历史原因出现的过时语法规则。

以下核心规则通过引用包括在内,如[射频5244],附录B.1:ALPHA(字母)、CR(回车)、CRLF(CR LF)、CTL(控件)、DIGIT(十进制0-9)、DQUOTE(双引号)、HEXDIG(十六进制0-9/A-F/A-F)、HTAB(水平制表符)、LF(换行)、OCTET(任何8位数据序列)、SP(空格)和VCHAR(任何可见的[美国]字符)。

以下规则定义于【HTTP】:

  BWS公司=<BWS,参见【HTTP】,第5.6.3节>OWS系统=<OWS,参见【HTTP】,第5.6.3节>远程操作系统=<RWS,请参阅【HTTP】,第5.6.3节>绝对通过率=<绝对路径,参见【HTTP】,第4.1节>字段名称=<字段名称,请参阅【HTTP】,第5.1节>字段值=<字段值,参见【HTTP】,第5.5节>obs-文本=<obs文本,请参阅【HTTP】,第5.6.4节>报价单=<quoted-string,参见【HTTP】,第5.6.4节>代币=<标记,请参阅【HTTP】,第5.6.2节>转移编码=<传输编码,请参阅【HTTP】,第10.1.4节>

以下规则定义于[URI]:

  绝对-URI=<绝对URI,参见[URI],第4.3节>权威=<权限,请参阅[URI],第3.2节>乌里霍斯特=<主机,请参阅[URI],第3.2.2节>港口=<端口,请参阅[URI],第3.2.3节>查询=<查询,请参阅[URI],第3.4节>

2 消息

HTTP/1.1客户端和服务器通过发送消息进行通信。请参见第3节属于[网址]了解HTTP的一般术语和核心概念。

2.1. 消息格式

HTTP/1.1消息由一个开始行和一个CRLF以及一系列八位字节组成,其格式类似于Internet消息格式[RFC5322]:零个或多个标头字段行(统称为“标头”或“标头部分”)、指示标头部分结束的空行和可选消息正文。

消息可以是从客户端到服务器的请求,也可以是从服务器到客户端的响应。从语法上讲,这两种类型的消息仅在起始线(请求线(用于请求)或状态线(用于响应))以及确定消息正文长度的算法上有所不同(第6节).

理论上,客户端可以接收请求,服务器可以接收响应,通过不同的起始行格式来区分它们。在实践中,服务器被实现为只期望一个请求(响应被解释为未知或无效的请求方法),而客户端被实现为仅期望一个响应。

HTTP使用了一些类似于多用途互联网邮件扩展(MIME)的协议元素[RFC2045]。请参阅附录B了解HTTP和MIME消息之间的差异。

2.2. 消息分析

解析HTTP消息的正常过程是将起始行读入结构,按字段名将每个标题字段行读入哈希表,直到出现空行,然后使用解析的数据确定是否需要消息正文。如果已指示消息体,则将其作为流读取,直到读取等于消息体长度的八位字节数或关闭连接。

收件人必须将HTTP消息解析为US-ASCII超集编码中的八位字节序列[美国科学院国际研究所]。将HTTP消息解析为Unicode字符流,而不考虑特定的编码,会由于字符串处理库处理包含八位字节LF(%x0A)的无效多字节字符序列的方式不同而产生安全漏洞。只有从消息中提取元素后,才能在协议元素中安全使用基于字符串的解析器,例如,在消息解析划定各个字段行后,在标头字段行值中。

尽管起始行和字段的行终止符是序列CRLF5月将单个LF识别为行终止符,并忽略前面的任何CR。

发件人不能在除内容之外的任何协议元素中生成一个空CR(不紧跟LF的CR字符)。此类无条件CR的接收人必须在处理该元素或转发消息之前,将该元素视为无效或用SP替换每个裸露的CR。

旧的HTTP/1.0用户代理实现可能会在POST请求后发送额外的CRLF,作为一些早期服务器应用程序的解决方案,这些应用程序无法读取未被行式终止的消息正文内容。HTTP/1.1用户代理不能在请求之前或之后添加额外的CRLF。如果需要使用行号终止请求消息体,则用户代理必须将终止CRLF八位字节计数为消息正文长度的一部分。

为了提高健壮性,希望接收和解析请求行的服务器应该忽略请求行之前收到的至少一个空行(CRLF)。

发件人不能在起始行和第一个标题字段之间发送空白。

接收起始行和第一个标题字段之间空白的收件人必须要么拒绝消息为无效消息,要么使用每条空白行,而不进行进一步处理(即忽略整行以及前面有空白的任何后续行,直到收到格式正确的头字段或头部分终止)。有必要拒绝或删除无效的空白行,以防止下游接收人对其进行曲解,因为下游接收人可能容易请求走私(第11.2条)或响应拆分(第11.1条)攻击。

当服务器仅侦听HTTP请求消息,或处理从起始行显示为HTTP请求消息的内容时,除了上面列出的健壮性异常之外,还接收到一系列与HTTP-message语法不匹配的八位字节时,服务器应该用一个400(错误请求)响应并关闭连接。

2.3. HTTP版本

HTTP使用“<major>.<minor>”编号方案来指示协议的版本。本规范定义了版本“1.1”。第2.5节属于【HTTP】指定HTTP版本号的语义。

HTTP/1.x消息的版本由中的HTTP-version字段指示起始线.HTTP-version是区分大小写的。

当HTTP/1.1消息发送给HTTP/1.0收件人时[HTTP/1.0]或者是版本未知的接收者,HTTP/1.1消息的构造方式是,如果忽略所有更新的功能,则可以将其解释为有效的HTTP/1.0消息。该规范对一些新功能提出了接收者版本要求,因此,在通过配置或接收消息确定接收者支持HTTP/1.1之前,一致的发送者将只使用兼容的功能。

处理HTTP消息的中介(即除充当隧道的中介之外的所有中介)必须在转发的消息中发送自己的HTTP-v版本,除非故意将其降级为上游问题的解决方案。换句话说,中介机构不允许盲目转发起始线没有确保该消息中的协议版本与该中介在接收和发送消息时符合的版本相匹配。转发HTTP消息而不重写HTTP-version可能会导致通信错误,因为下游收件人使用消息发送方的版本来确定以后与该发送方通信时可以安全使用哪些功能。

服务器5月如果已知或怀疑客户端错误地实现了HTTP规范,并且无法正确处理更高版本的响应,则向HTTP/1.1请求发送HTTP/1.0响应,例如当客户端未能正确解析版本号时,或者当已知中介机构盲目转发HTTP版本时。此类协议降级不应该除非由特定客户端属性触发,例如当一个或多个请求头字段(例如。,用户代理)唯一匹配已知出错的客户端发送的值。

三。 请求行

请求线以一个方法标记开始,然后是一个空格(SP)、请求目标和另一个空白(SP),最后是协议版本。

虽然请求行语法规则要求每个组件元素由单个SP八位字节分隔,但收件人5月相反,解析以空格分隔的单词边界,除了CRLF终止符外,还将任何形式的空格作为SP分隔符,同时忽略前面或后面的空格;此类空白包括以下一个或多个八位字节:SP、HTAB、VT(%x0B)、FF(%x0C)或bare CR。但是,如果消息有多个收件人,并且每个收件人都有自己独特的健壮性解释,那么宽松的解析可能导致请求走私安全漏洞(请参阅第11.2条).

HTTP不会对请求行的长度设置预定义的限制,如中所述第2.3节属于【HTTP】。接收方法的时间长于它实现的任何方法的服务器应该回答:501(未实施)状态代码。接收请求目标的时间比它希望解析的任何URI都长的服务器必须用一个414(URI过长)状态代码(请参见第15.5.15条属于【HTTP】).

实践中发现了对请求行长度的各种特殊限制。它是推荐所有HTTP发送方和接收方至少支持8000个八位字节的请求行长度。

3.1. 方法

方法标记指示要对目标资源执行的请求方法。请求方法区分大小写。

此规范定义的请求方法可以在中找到第9节属于【HTTP】,以及有关HTTP方法注册表的信息和定义新方法的注意事项。

3.2. 请求目标

请求目标标识应用请求的目标资源。客户端从其所需的目标URI派生请求目标。请求目标有四种不同的格式,这取决于所请求的方法以及请求是否发送给代理。

请求目标中不允许有空白。不幸的是,一些用户代理无法正确编码或排除超文本引用中的空白,导致这些不允许的字符作为错误请求行中的请求目标发送。

无效请求行的收件人应该用一个400(错误请求)错误或301(永久移动)使用正确编码的请求目标重定向。收件人不应该尝试自动更正,然后在没有重定向的情况下处理请求,因为无效的请求线可能是故意构建的,以绕过请求链上的安全过滤器。

客户必须发送主机标题字段(第7.2节属于【HTTP】)在所有HTTP/1.1请求消息中。如果目标URI包含授权组件,则客户端必须发送与该权限组件相同的Host字段值,不包括任何userinfo子组件及其“@”分隔符(第4.2节属于【HTTP】). 如果目标URI的权限组件丢失或未定义,则客户端必须发送一个字段值为空的Host标头字段。

服务器必须用一个400(错误请求)任何缺少主机标头字段的HTTP/1.1请求消息以及包含多个主机标头域行或具有无效字段值的主机标头场的任何请求消息的状态代码。

3.2.1. 原始形态

请求目标的最常见形式是原始形态.

当直接向源服务器发出请求时,而不是CONNECT或服务器范围的OPTIONS请求(如下所述),客户端必须只发送目标URI的绝对路径和查询组件作为请求目标。如果目标URI的路径组件为空,则客户端必须将“/”作为request-target的原始格式中的路径发送。一个主机标题字段也会发送,如中所定义第7.2节属于【HTTP】.

例如,客户机希望检索标识为

http://www.example.org/where?q=现在

直接从源服务器打开(或重用)到主机“www.example.org”的端口80的TCP连接,并发送以下行:

GET/在哪里?q=现在HTTP/1.1主持人:www.example.org

然后是请求消息的其余部分。

3.2.2。 绝对形态

当向代理发出请求时,而不是CONNECT或服务器范围的OPTIONS请求(如下所述),客户端必须在中发送目标URI绝对形态作为请求目标。

如果可能,将代理请求到从有效缓存发出请求的服务,或者代表客户端向下一个入站代理服务器或直接向请求目标指示的源服务器发出相同请求。有关此类消息“转发”的要求,请参见第7.6节属于[网址].

请求线的绝对形式示例如下:

GET(获取)http://www.example.org/pub/www/TheProject.htmlHTTP/1.1协议

客户必须在HTTP/1.1请求中发送Host头字段,即使请求目标是绝对形式,因为这允许通过可能尚未实现Host的古老HTTP/1.0代理转发Host信息。

当代理接收到具有绝对形式的请求目标的请求时,代理必须忽略接收到的主机标头字段(如果有),将其替换为请求目标的主机信息。转发此类请求的代理必须根据收到的请求目标生成新的主机字段值,而不是转发收到的主机字段的值。

当源服务器接收到具有绝对形式的请求目标的请求时,源服务器必须忽略接收到的主机标头字段(如果有),而使用请求目标的主机信息。请注意,如果请求目标没有权限组件,那么在这种情况下将发送一个空的Host头字段。

服务器必须在请求中接受绝对表单,即使大多数HTTP/1.1客户端只会将绝对表单发送给代理。

3.2.3. 权威式的

这个权威式的请求目标的仅用于CONNECT请求(第9.3.6节属于【HTTP】). 它只包括乌里霍斯特港口隧道目的地的编号,用冒号(“:”)分隔。

当发出CONNECT请求以通过一个或多个代理建立隧道时,客户端必须仅发送隧道目的地的主机和端口作为请求目标。客户端从目标URI获取主机和端口权威组件,但如果目标URI省略该端口,它会发送方案的默认端口。例如,CONNECT请求“http://www.example.com“如下所示:

连接www.example.com:80 HTTP/1.1主持人:www.example.com

3.2.4. 星号形状

这个星号形状请求目标的仅用于服务器范围的OPTIONS请求(第9.3.7节属于【HTTP】).

当客户端希望为整个服务器请求OPTIONS,而不是该服务器的特定命名资源时,客户端必须仅发送“*”(%x2A)作为请求目标。例如,

选项*HTTP/1.1

如果代理接收到具有绝对形式的请求目标的OPTIONS请求,其中URI具有空路径且没有查询组件,则请求链上的最后一个代理必须将请求转发到指定的源服务器时,发送“*”的请求目标。

例如,请求

选项http://www.example.org:8001HTTP/1.1协议

将由最终代理转发为

选项*HTTP/1.1主持人:www.example.org:8001

连接到主机“www.example.org”的端口8001后。

3.3. 重建目标URI

目标URI是请求目标当请求目标位于绝对形态在这种情况下,服务器会将URI解析为其通用组件,以便进一步评估。

否则,服务器会根据连接上下文和请求消息的各个部分重新构建目标URI,以识别目标资源(第7.1节属于[网址])以下为:

  • 如果服务器的配置提供了固定URI方案,或者由受信任的出站网关提供了方案,则该方案将用于目标URI。这在大规模部署中很常见,因为网关服务器将接收客户端的连接上下文,并将其替换为自己与入站服务器的连接。否则,如果通过安全连接接收请求,则目标URI的方案为“https”;如果不是,则方案为“http”。
  • 如果请求目标位于权威式的,目标URI的权限组件是请求目标。否则,目标URI的权限组件是主机标题字段。如果没有主机头字段,或者如果其字段值为空或无效,则目标URI的权限组件为空。
  • 如果请求目标位于权威式的星号形状,目标URI的组合路径查询组件为空。否则,目标URI的组合路径查询组件是请求目标。
  • 按照上述方法确定后,重构目标URI的组件可以重新组合为绝对-URI通过连接scheme、“://”、authority和组合路径和查询组件来形成。

示例1:通过安全连接接收到以下消息

GET/pub/WWW/TheProject.html HTTP/1.1主持人:www.example.org

具有的目标URI

https://www.example.org/pub/www/TheProject.html

示例2:通过不安全连接接收到以下消息

选项*HTTP/1.1主持人:www.example.org:8080

具有的目标URI

http://www.example.org:8080

如果目标URI的权限组件为空,并且其URI方案需要非空权限(如“http”和“https”),服务器可以拒绝请求或确定是否应用与传入连接上下文一致的配置默认值。上下文可能包括连接详细信息,如地址和端口、应用的安全性以及特定于该服务器配置的本地定义信息。在进一步处理请求之前,空权限将替换为配置的默认权限。

如果用户代理的预期权限可能与默认权限不同,那么在安全连接上下文中为权限提供默认名称本质上是不安全的。可以从请求上下文中唯一标识授权的服务器5月使用该标识作为默认标识而不存在此风险。或者,最好将请求重定向到解释如何获取新客户端的安全资源。

请注意,重建客户机的目标URI只是标识目标资源过程的一半。另一半是确定目标URI是否标识服务器愿意并能够发送响应的资源,如中所定义第7.4节属于【HTTP】.

4 状态行

响应消息的第一行是状态线,由协议版本、空格(SP)、状态代码和另一个空格组成,以可选描述状态代码的文本短语。

尽管状态线语法规则要求每个组件元素由单个SP八位字节分隔,但收件人5月相反,在以空格分隔的单词边界上进行解析,除了行终止符之外,还可以将任何形式的空格作为SP分隔符,同时忽略前面或后面的空格;此类空白包括以下一个或多个八位字节:SP、HTAB、VT(%x0B)、FF(%x0C)或bare CR。但是,如果消息有多个接收者,并且每个接收者都有自己独特的健壮性解释,则宽松的解析可能导致响应拆分安全漏洞(请参阅第11.1条).

status-code元素是一个3位整数代码,描述服务器尝试理解和满足客户端相应请求的结果。如果接收者识别状态码,则接收者根据为该状态码定义的语义分析和解释响应消息的其余部分,如果特定代码无法识别,则根据该状态码的类别进行分析和解释。

HTTP的核心状态代码定义于第15节属于【HTTP】以及状态代码的类别、新状态代码定义的考虑因素以及收集此类定义的IANA注册中心。

reason-phrase元素的唯一目的是提供与数字状态代码相关的文本描述,这主要是出于对早期Internet应用程序协议的尊重,这些协议更常用于交互式文本客户端。

客户应该忽略reason-phrase内容,因为它不是可靠的信息通道(它可能会被翻译为给定的语言环境,被中介覆盖,或者在通过其他版本的HTTP转发消息时被丢弃)。服务器必须发送分隔状态代码和原因语句的空格,即使没有原因语句(即状态行将以空格结尾)。

5 字段语法

每个字段行包含一个区分大小写的字段名,后跟冒号(“:”)、可选的前导空格、字段行值和可选的尾随空格。

字段值内的解析规则在中定义第5.5节属于【HTTP】本节介绍HTTP/1.1消息中包含标头字段和从中提取标头字段的通用语法。

5.1. 字段行分析

消息使用通用算法进行解析,与各个字段名无关。直到消息解释的后期阶段(通常在消息的整个字段部分处理完之后),才会解析给定字段行值中的内容。

字段名和冒号之间不允许有空格。过去,处理此类空白的差异导致了请求路由和响应处理中的安全漏洞。服务器必须拒绝,响应状态代码为400(错误请求),任何接收到的请求消息,在头字段名和冒号之间包含空白。代理人必须在向下游转发消息之前,从响应消息中删除任何此类空白。

字段行值的前面和/或后面可能有可选空格(OWS);为了人类的一致可读性,字段行值之前的单个SP是首选的。字段行值不包括前导或尾随空格:当从字段行中提取字段行值时,解析器会排除字段行值的第一个非空白八位字节之前或最后一个非空白八位字节之后出现的OWS。

5.2. 过时的折线

历史上,HTTP/1.x字段值可以通过在每一额外行前面至少加一个空格或水平制表符(obsfold)扩展到多行。本规范不推荐这种行折叠,除非是在“message/http”媒体类型中(第10.1条).

发件人不能生成包含行折叠的消息(即,具有包含与obsfold公司规则),除非该消息打算打包在“message/http”媒体类型中。

接收obsfold公司在不在“message/http”容器内的请求消息中必须通过发送400(错误请求)最好用一个表示来解释过时的折线是不可接受的,或者替换每个收到的obsfold公司具有一个或多个服务提供商八位字节,然后解释字段值或向下游转发消息。

接收obsfold公司在不在“message/http”容器内的响应消息中必须要么丢弃消息,然后将其替换为502(错误网关)响应,最好用一个表示来解释收到了不可接受的折线,或替换每个收到的折线obsfold公司具有一个或多个服务提供商八位字节,然后解释字段值或向下游转发消息。

接收obsfold公司在不在“message/http”容器内的响应消息中必须更换每个收到的obsfold公司具有一个或多个服务提供商解释字段值之前的八位字节。

6 消息正文

HTTP/1.1消息的消息体(如果有)用于承载内容(第6.4节属于【HTTP】)请求或响应。除非应用了传输编码,否则消息正文与内容相同,如中所述第6.1节.

确定消息体何时出现在HTTP/1.1消息中的规则因请求和响应而异。

请求中消息体的存在由内容物-长度传输编码标题字段。请求消息框架独立于方法语义。

响应中消息体的存在,如中所述第6.3节,取决于它响应的请求方法和响应状态代码。这对应于HTTP语义允许响应内容的情况(第6.4.1节属于【HTTP】).

6.1. 传输编码

传输编码头字段列出了与已(或将)应用于内容以形成消息正文的传输编码序列相对应的传输编码名称。传输编码定义见第7节.

传输编码类似于MIME的内容传输编码字段,该字段旨在通过7位传输服务实现二进制数据的安全传输([RFC2045],第6节). 然而,安全传输对于8bit-clean传输协议有不同的关注点。在HTTP的情况下,“传输编码”主要用于准确地界定动态生成的内容。它还用于区分仅在传输过程中应用的编码和作为所选表示特征的编码。

收件人必须能够解析分块传输编码(第7.1节)因为在事先不知道内容大小的情况下,它在构建消息的框架中起着至关重要的作用。发件人不能对消息体多次应用分块传输编码(即,不允许对已经分块的消息进行分块)。如果对请求的内容应用了块以外的任何传输编码,则发送方必须应用分块作为最后的传输编码,以确保消息的帧正确。如果对响应的内容应用了除分块以外的任何传输编码,则发送方必须要么应用分块作为最终传输编码,要么通过关闭连接来终止消息。

例如,

传输编码:gzip,分块

表示内容已使用gzip编码进行压缩,然后在形成消息正文时使用分块编码进行分块。

不同于内容编码(第8.4.1条属于【HTTP】),传输编码是消息的属性,而不是表示的属性。请求/响应链上的任何收件人5月对接收到的传输编码进行解码或对消息正文应用附加的传输编码,假设对传输编码字段值进行了相应的更改。关于编码参数的附加信息可以由本说明书未定义的其他报头字段提供。

传输编码5月作为对HEAD请求的响应或在304(未修改)响应(第15.4.5条属于【HTTP】)GET请求(两者都不包含消息体),以指示如果请求是无条件GET,则源服务器将对消息体应用传输编码。但是,不需要此指示,因为响应链上的任何收件人(包括源服务器)都可以在不需要时删除传输代码。

服务器不能在任何响应中发送状态代码为1xx(信息)204(无内容).服务器不能在任何2xx(成功)对CONNECT请求的响应(第9.3.6节属于【HTTP】).

接收带有传输编码的请求消息的服务器无法理解应该用回应501(未实施).

HTTP/1.1中添加了传输编码。通常认为,仅宣传HTTP/1.0支持的实现将无法理解如何处理传输编码的内容,并且使用传输编码接收的HTTP/1.00消息很可能在传输过程中没有正确处理分块传输编码的情况下被转发。

客户不能发送包含Transfer-Encoding的请求,除非它知道服务器将处理HTTP/1.1请求(或稍后的小修订);这种知识可以是特定用户配置的形式,或者通过记住先前接收到的响应的版本。服务器不能发送包含Transfer-Encoding的响应,除非相应的请求指示HTTP/1.1(或更高版本的次要修订)。

传输编码的早期实现偶尔会发送用于消息帧的分块传输编码和用于进度条的估计内容长度标头字段。这就是为什么传输编码被定义为覆盖内容长度,而不是相互不兼容。不幸的是,转发这样的消息可能会导致有关请求走私的漏洞(第11.2条)或响应拆分(第11.1条)如果任何下游收件人未能根据此规范解析消息,尤其是当下游收件人仅实现HTTP/1.0时,将发起攻击。

服务器5月拒绝同时包含内容长度和传输编码的请求,或仅根据传输编码处理此类请求。无论如何,服务器必须在响应此类请求后关闭连接,以避免潜在的攻击。

接收包含Transfer-Encoding头字段的HTTP/1.0消息的服务器或客户端必须即使存在Content-Length,也要将消息视为帧错误,并在处理消息后关闭连接。消息发送方可能在缓冲区中保留了消息的一部分,这可能会被进一步使用连接所误解。

6.2. 内容物-长度

当消息没有传输编码header字段,Content-Length header字段(第8.6条属于【HTTP】)可以提供潜在内容的预期大小,如十进制八位字节数。对于包含内容的消息,content-Length字段值提供了确定数据(和消息)结束位置所需的帧信息。对于不包括内容的消息,“内容长度”指示所选表示的大小(第8.6条属于【HTTP】).

发件人不能在包含传输编码标题字段。

6.3. 消息正文长度

消息正文的长度由以下内容之一决定(按优先顺序):

  1. 对HEAD请求的任何响应和带有1xx(信息),204(无内容),或304(未修改)无论消息中是否存在标题字段,状态代码总是以标题字段后的第一个空行结束,因此不能包含消息正文或尾部部分。

  2. 任何2xx(成功)对CONNECT请求的响应意味着连接将在结束头字段的空行之后立即成为隧道。客户必须忽略任何内容物-长度传输编码在这样的消息中接收到的头字段。

  3. 如果同时收到带有传输编码和a内容物-长度标头字段,则传输编码将覆盖内容长度。此类消息可能表示试图执行请求走私(第11.2节)或响应拆分(第11.1条)应该作为错误处理。选择转发消息的中介必须首先删除接收到的Content-Length字段,并在向下转发消息之前处理Transfer-Encode(如下所述)。

  4. 如果传输编码存在标头字段和分块传输编码(第7.1节)是最终编码,消息体长度通过读取和解码分块数据来确定,直到传输编码指示数据完成为止。

    如果传输编码报头字段出现在响应中,分块传输编码不是最终编码,消息正文长度是通过读取连接来确定的,直到服务器将其关闭。

    如果传输编码请求中存在头字段,分块传输编码不是最终编码,消息体长度无法可靠确定;服务器必须400(错误请求)状态代码,然后关闭连接。

  5. 如果收到的消息没有传输编码还有一个病人内容物-长度header字段,则消息帧无效,收件人必须将其视为不可恢复的错误,除非字段值可以成功解析为逗号分隔的列表(第5.6.1节属于【HTTP】),列表中的所有值都有效,并且列表中的全部值都相同(在这种情况下,将使用作为Content-Length字段值的单个值处理消息)。如果不可恢复的错误出现在请求消息中,则服务器必须用一个400(错误请求)状态代码,然后关闭连接。如果它位于代理接收到的响应消息中,则代理必须关闭与服务器的连接,放弃收到的响应,并发送502(错误网关)对客户端的响应。如果它在用户代理接收的响应消息中,则用户代理必须关闭与服务器的连接并放弃收到的响应。

  6. 如果有效内容物-长度标头字段不存在传输编码,其十进制值以八位字节为单位定义预期的消息正文长度。如果发送方在收到指定数量的八位字节之前关闭连接或接收方超时,则接收方必须将消息视为不完整,然后关闭连接。

  7. 如果这是一条请求消息,并且以上都不为真,那么消息体长度为零(不存在消息体)。

  8. 否则,这是一条没有声明消息正文长度的响应消息,因此消息正文长度由服务器关闭连接之前接收的八位字节数决定。

由于无法区分成功完成的封闭式响应消息和因网络故障中断的部分接收消息,因此服务器应该尽可能生成编码或长度限定的消息。close-delimiting特性的存在主要是为了向后兼容HTTP/1.0。

服务器5月拒绝包含消息正文但不包含内容物-长度通过响应411(要求长度).

除非应用了块以外的传输编码,否则发送包含消息正文的请求的客户端应该使用有效的内容物-长度如果消息正文长度是预先已知的,而不是分块传输编码,则为header字段,因为一些现有服务使用411(所需长度)状态码,即使他们理解分块传输编码。这通常是因为这样的服务是通过一个网关实现的,该网关要求在调用之前有一个内容长度,并且服务器无法或不愿意在处理之前缓冲整个请求。

发送包含消息正文的请求的用户代理必须发送有效的内容物-长度头字段或使用分块传输编码。客户不能使用分块传输编码,除非它知道服务器将处理HTTP/1.1(或更高版本)请求;这种知识可以是特定用户配置的形式,或者通过记住先前接收到的响应的版本。

如果已完全收到对连接上最后一个请求的最终响应,并且仍有其他数据要读取,则用户代理5月丢弃剩余数据或尝试确定该数据是否属于先前消息正文的一部分,如果先前消息的Content-Length值不正确,则可能会出现这种情况。客户不能处理、缓存或转发此类额外数据作为单独的响应,因为此类行为很容易受到缓存中毒的影响。

7 传输编码

传输编码名称用于指示已经、可以或可能需要应用于消息内容的编码转换,以确保通过网络的“安全传输”。这与内容编码不同,因为传输编码是消息的属性,而不是正在传输的表示的属性。

所有传输编码名称都不区分大小写,应该在HTTP传输编码注册表中注册,如中所定义第7.3节。它们用于传输编码(第6.1节)和TE公司(第10.1.4节属于【HTTP】)标题字段(后者还定义了“传输编码”语法)。

7.1. 块传输编码

分块传输编码将内容包装起来,以便将其传输为一系列分块,每个分块都有自己的大小指示器,然后是可选包含拖车字段的拖车部分。分块使大小未知的内容流能够作为一系列长度限定的缓冲区进行传输,这使发送方能够保持连接持久性,而接收方能够知道何时收到了整个消息。

chunk-size字段是一个十六进制数字字符串,以八位字节表示chunk-data的大小。当接收到块大小为零的块时,分块传输编码完成,之后可能是尾部部分,最后以空行结束。

收件人必须能够解析和解码分块传输编码。

HTTP/1.1没有定义任何方法来限制分块响应的大小,从而确保中介可以缓冲整个响应。此外,如果在接收实现中不能准确表示块的值,则块大小过大可能会导致溢出或精度损失。因此,收件人必须预测可能较大的十六进制数字,并防止由于整数转换溢出或整数表示导致的精度损失而导致的解析错误。

分块编码没有定义任何参数。他们的存在应该被视为错误。

7.1.1. 区块扩展

块编码允许每个块包含零个或多个块扩展,紧跟在块大小,以便提供每块元数据(例如签名或散列)、消息中间控制信息或消息体大小的随机化。

分块编码特定于每个连接,在任何更高级别的应用程序有机会检查扩展之前,可能会被每个接收者(包括中介)删除或重新编码。因此,块扩展的使用通常仅限于专门的HTTP服务,如“长轮询”(客户端和服务器可以对块扩展的用法有共同的期望)或用于在端到端安全连接中填充。

收件人必须忽略无法识别的块扩展。服务器应该将请求中接收到的块扩展的总长度限制在对所提供的服务合理的数量,就像它对消息的其他部分应用长度限制和超时一样,并生成适当的4xx(客户端错误)如果超过该数量,则进行响应。

7.1.2. 大块拖车段

尾部部分允许发送方在分块消息的末尾包含附加字段,以便提供在发送内容时可能动态生成的元数据,例如消息完整性检查、数字签名或后处理状态。拖车场的正确使用和限制见第6.5节属于【HTTP】.

从消息中删除分块编码的收件人5月选择性地保留或丢弃接收到的拖车字段。保留接收到的尾部字段的收件人必须将尾部字段与接收到的标题字段分开存储/转发,或者将接收到的尾部字段合并到标题部分。收件人不能将收到的尾部字段合并到头部部分,除非其相应的头部字段定义明确允许并指示如何安全合并尾部字段值。

7.1.3. 解码分块

解码分块传输编码的过程可以用伪码表示为:

长度:=0读取区块大小、区块文本(如果有)和CRLFwhile(chunk-size>0){读取chunk-data和CRLF将区块数据附加到内容长度:=长度+块大小读取chunk-size、chunk-ext(如果有)和CRLF}读取尾部字段while(拖车字段不为空){if(拖车字段单独存储/转发){将拖车字段附加到现有拖车字段}else if(拖车字段被理解为可合并){将尾部字段与现有标题字段合并}其他{丢弃拖车场}读取尾部字段}内容-长度:=长度从传输编码中删除“分块”

7.2. 传输压缩编码

以下用于压缩的传输编码名称由与其对应的内容编码相同的算法定义:

压缩(和x-compress)
请参见第8.4.1.1节属于【HTTP】.
放气
请参见第8.4.1.2节属于【HTTP】.
gzip(和x-gzip)
请参见第8.4.1.3节属于【HTTP】.

压缩编码没有定义任何参数。任何这些压缩编码的参数的存在应该被视为错误。

7.3。 传输编码注册表

“HTTP传输编码注册表”定义了传输编码名称的命名空间。它保持在https://www.iana.org/assignments/http-parameters网站.

注册必须包括以下字段:

  • 姓名
  • 描述
  • 指向规范文本的指针

传输编码名称不能与内容编码名称重叠(第8.4.1条属于【HTTP】)除非编码转换是相同的,如中定义的压缩编码第7.2节.

这个TE公司标题字段(第10.1.4节属于[网址])当可接受多个传输编码时,使用名为“q”的伪参数作为秩值。转让编码的未来注册不应该定义名为“q”(区分大小写)的参数以避免歧义。

要添加到此命名空间的值需要IETF审查(请参阅第4.8节属于[RFC8126])和必须符合本规范中定义的传输编码目的。

使用程序名来识别编码格式是不可取的,不鼓励在将来进行编码。

7.4. 谈判转让编码

TE字段(第10.1.4节属于【HTTP】)在HTTP/1.1中使用,以指示除了分块外,客户端还愿意在响应中接受哪些传输编码,以及客户端是否愿意在分块传输编码中保留尾部字段。

客户不能在TE中发送分块传输编码名称;HTTP/1.1收件人始终可以接受分块。

下面是TE使用的三个示例。

TE:放气技术工程师:TE:拖车,放气;q=0.5

当可以接受多个传输编码时,客户5月使用区分大小写的“q”参数(类似于内容协商字段中使用的q值;请参见第12.4.2条属于【HTTP】). 秩值是0到1范围内的实数,其中0.001是最不可取的,1是最可取的;值为0表示“不可接受”。

如果TE字段值为空或不存在TE字段,则只对可接受的传输编码进行分块。没有传输编码的消息总是可以接受的。

关键字“trails”表示发送方不会丢弃尾部字段,如中所述第6.5节属于[网址].

由于TE头字段仅适用于立即连接,因此TE的发送方必须还发送一个“TE”连接选项连接标题字段(第7.6.1节属于【HTTP】)为了防止TE头字段被不支持其语义的中介转发。

8 处理不完整消息

收到不完整请求消息的服务器,通常是由于取消的请求或触发的超时异常,5月在关闭连接之前发送错误响应。

接收到不完整响应消息的客户端,当连接过早关闭或对假定的分块传输编码解码失败时,可能会发生这种情况,必须将消息记录为不完整。不完整响应的缓存要求在中定义第3.3节属于[缓存].

如果响应在标头部分的中间终止(在收到空行之前),并且状态代码可能依赖标头字段来传达响应的全部含义,则客户端不能假定含义已经传达;客户端可能需要重复该请求,以确定下一步要执行的操作。

如果尚未收到终止编码的零大小块,则使用分块传输编码的消息体是不完整的。使用有效内容物-长度如果接收到的消息正文的大小(以八位字节为单位)小于Content-Length给定的值,则不完整。如果响应既没有分块传输编码,也没有内容长度,则会通过关闭连接来终止,并且如果完整地接收到标头部分,则视为已完成,除非基础连接指示了错误(例如,TLS中的“未完成关闭”会使响应不完整,如中所述第9.8节).

9 连接管理

HTTP消息传递独立于底层传输或会话层连接协议。HTTP仅假定可靠的传输,请求按顺序传递,响应按顺序传递。HTTP请求和响应结构到底层传输协议的数据单元的映射超出了本规范的范围。

如中所述第7.3节属于【HTTP】,用于HTTP交互的特定连接协议由客户端配置和目标URI。例如,“http”URI方案(第4.2.1节属于【HTTP】)表示TCP over IP的默认连接,默认TCP端口为80,但客户端可能被配置为通过其他连接、端口或协议使用代理。

HTTP实现预计将参与连接管理,包括维护当前连接的状态、建立新连接或重用现有连接、处理连接上接收的消息、检测连接故障以及关闭每个连接。大多数客户端并行维护多个连接,包括每个服务器端点多个连接。大多数服务器设计为维护数千个并发连接,同时控制请求队列以实现合理使用并检测拒绝服务攻击。

9.1. 成立

描述如何通过各种传输层或会话层协议建立连接超出了本规范的范围。每个HTTP连接都映射到一个底层传输连接。

9.2. 将响应与请求关联

HTTP/1.1不包含用于将给定请求消息与其对应的一个或多个响应消息关联的请求标识符。因此,它依赖于响应到达的顺序,以便与在同一连接上发出请求的顺序完全对应。只有当一个或多个信息性响应时,每个请求才会出现多条响应消息(1倍; 看见第15.2条属于【HTTP】)在对同一请求做出最终响应之前。

在连接上有多个未完成请求的客户端必须在发送的订单中保留一份未完成请求的列表,并必须将该连接上收到的每个响应消息与尚未收到最终(非-1倍)响应。

如果客户端在没有未完成请求的连接上接收数据,则客户端不能认为该数据是有效的回应;客户应该关闭连接,因为消息分隔现在不明确,除非数据只包含一个或多个CRLF(根据第2.2节).

9.3. 坚持不懈

HTTP/1.1默认使用持久连接,允许通过单个连接承载多个请求和响应。HTTP实现应该支持持久连接。

接收方根据协议版本和连接标题字段(第7.6.1节属于【HTTP】)在最近收到的消息中(如果有):

  • 如果“关闭“存在连接选项(第9.6节),连接在当前响应后将不会持续;否则,
  • 如果接收到的协议是HTTP/1.1(或更高版本),则连接将在当前响应后保持;否则,
  • 如果接收的协议是HTTP/1.0,存在“keep-alive”连接选项,或者接收者不是代理,或者消息是响应,并且接收者希望遵守HTTP/1.0-“keep-alive”机制,则连接将在当前响应后保持;否则,
  • 连接将在当前响应后关闭。

不支持的客户端持久连接 必须发送“关闭“每个请求消息中的连接选项。

不支持的服务器持久连接 必须发送“关闭“每个响应消息中没有1xx(信息)状态代码。

客户5月在持久连接上发送其他请求,直到它发送或接收“关闭”连接选项或在没有“keep-alive”连接选项的情况下接收HTTP/1.0响应。

为了保持持久性,连接上的所有消息都需要具有自行定义的消息长度(即,未通过关闭连接定义的长度),如中所述第6节.A服务器必须读取整个请求消息体或在发送响应后关闭连接;否则,持久连接上的剩余数据将被误解为下一个请求。同样,客户必须如果打算在后续请求中重用相同的连接,请阅读整个响应消息体。

代理服务器不能维护与HTTP/1.0客户端的持久连接(请参阅附录C.2.2获取由许多HTTP/1.0客户端实现的Keep-Alive头字段的信息和问题讨论)。

请参见附录C.2.2有关与HTTP/1.0客户端向后兼容的更多信息。

9.3.1. 重试请求

可以随时关闭连接,无论是否有意。实现应该预见到需要从异步关闭事件中恢复。客户端可以自动重试一系列未完成请求的条件在中定义第9.2.2条属于【HTTP】.

9.3.2. 管道铺设

支持持久连接的客户端5月 管道它的请求(即发送多个请求而不等待每个响应)。服务器5月如果所有的请求都有安全的方法,则并行处理一系列流水线请求(第9.2.1条属于【HTTP】),但它必须以接收请求的相同顺序发送相应的响应。

传送请求的客户端应该如果连接在收到所有相应响应之前关闭,请重试未响应的请求。在连接失败(服务器在最后一次完整响应中未明确关闭的连接)后重试管道化请求时,客户端不能连接建立后立即使用管道,因为前一管道中的第一个剩余请求可能会导致错误响应,如果在过早关闭的连接上发送多个请求,该错误响应可能会再次丢失(请参阅中描述的TCP重置问题第9.6节).

幂等方法(第9.2.2条属于【HTTP】)对于管道来说非常重要,因为在连接失败后可以自动重试。用户代理不应该管道在非幂等方法之后请求,直到接收到该方法的最终响应状态代码,除非用户代理具有检测和恢复涉及管道序列的部分故障条件的方法。

接收流水线请求的中介5月在将这些请求转发到入站时对其进行管道处理,因为它可以依赖出站用户代理来确定哪些请求可以安全地进行管道处理。如果入站连接在接收响应之前失败,则管道中介5月如果请求都具有幂等方法,则尝试重试尚未收到响应的请求序列;否则,管道中介应该转发任何接收到的响应,然后关闭相应的出站连接,以便出站用户代理可以相应地恢复。

9.4. 并发

客户端应该限制它与给定服务器同时保持的打开连接数。

以前的HTTP修订版给出了特定数量的连接作为上限,但这对于许多应用程序来说是不切实际的。因此,该规范没有规定特定的最大连接数,而是鼓励客户端在打开多个连接时保持保守。

多个连接通常用于避免“前端阻塞”问题,其中需要大量服务器端处理和/或传输非常大的内容的请求将阻塞同一连接上的后续请求。然而,每个连接都会消耗服务器资源。

此外,在拥塞的网络中使用多个连接可能会导致不良的副作用。使用更多的连接也会在其他未拥塞的网络中造成副作用,因为它们的聚合和初始同步发送行为可能会导致拥塞,而如果使用较少的并行连接,则不会出现拥塞。

请注意,服务器可能会拒绝它认为具有滥用或拒绝服务攻击特征的流量,例如来自单个客户端的过多打开连接。

9.5. 故障和超时

服务器通常会有一些超时值,超过该值后,它们将不再保持非活动连接。代理服务器可能会使此值更高,因为客户端可能会通过同一代理服务器建立更多连接。使用持久连接对客户端或服务器的超时时间长度(或是否存在)没有任何要求。

希望超时的客户端或服务器应该在连接上优雅地关闭。启动位置应该不断监视打开的连接以获取接收到的关闭信号,并酌情对其作出响应,因为快速关闭连接的两端可以回收分配的系统资源。

客户端、服务器或代理5月随时关闭传输连接。例如,客户端可能在服务器决定关闭“空闲”连接的同时开始发送新请求。从服务器的角度来看,连接是在空闲时关闭的,但从客户端的角度来看,请求正在进行中。

服务器应该在可能的情况下维持持久连接,并允许底层传输的流控制机制解决临时过载,而不是在客户端重试的情况下终止连接。后一种技术会加剧网络拥塞或服务器负载。

发送消息正文的客户端应该在传输请求时,监视网络连接是否有错误响应。如果客户端看到一个响应,指示服务器不希望接收消息正文并正在关闭连接,则客户端应该立即停止传输身体并关闭连接的一侧。

9.6. 拆卸

“关闭”连接选项被定义为发送方将在响应完成后关闭此连接的信号。发件人应该发送连接标题字段(第7.6.1节属于【HTTP】)当它打算关闭连接时,包含“close”连接选项。例如,

连接:关闭

由于请求头字段指示这是客户端将在此连接上发送的最后一个请求,而在响应中,同一字段指示服务器将在响应消息完成后关闭此连接。

请注意,字段名“Close”是保留的,因为使用该名称作为标题字段可能与“Close”连接选项冲突。

发送“关闭”连接选项的客户端不能在该连接上发送进一步的请求(在包含“close”的连接之后),并且必须读取与此请求对应的最终响应消息后,关闭连接。

接收“关闭”连接选项的服务器必须在向包含“close”连接选项的请求发送最终响应后,启动连接关闭(见下文)。服务器应该在该连接的最终响应中发送“关闭”连接选项。服务器不能处理在该连接上收到的任何其他请求。

发送“关闭”连接选项的服务器必须在发送包含“close”连接选项的响应后,启动连接的关闭(见下文)。服务器不能处理在该连接上收到的任何其他请求。

接收“关闭”连接选项的客户端必须停止在该连接上发送请求,并在读取包含“关闭”连接选项的响应消息后关闭连接;如果在连接上发送了其他流水线请求,则客户端不应该假设它们将由服务器处理。

如果服务器立即关闭TCP连接,则存在客户端无法读取最后一个HTTP响应的重大风险。如果服务器在完全关闭的连接上从客户端接收到附加数据,例如客户端在接收服务器响应之前发送的另一个请求,服务器的TCP堆栈将向客户端发送重置包;不幸的是,重置数据包可能会在客户端的HTTP解析器读取和解释之前擦除客户端的未确认输入缓冲区。

为了避免TCP重置问题,服务器通常分阶段关闭连接。首先,服务器通过只关闭读/写连接的写入端来执行半关闭。然后,服务器继续读取连接,直到它收到客户端的相应关闭,或者直到服务器合理确定其自己的TCP堆栈已收到客户端对包含服务器最后响应的数据包的确认。最后,服务器完全关闭连接。

尚不清楚重置问题是TCP独有的,还是其他传输连接协议中也可能存在重置问题。

请注意,客户端半关闭的TCP连接不会分隔请求消息,也不意味着客户端不再对响应感兴趣。一般来说,由于HTTP/1.1独立于传输,因此不能依赖传输信号来发送边缘情况的信号。

9.7. TLS连接启动

从概念上讲,HTTP/TLS只是通过TLS保护的连接发送HTTP消息[TLS13].

HTTP客户端还充当TLS客户端。它在适当的端口上启动与服务器的连接,并发送TLS ClientHello以开始TLS握手。TLS握手完成后,客户端可以启动第一个HTTP请求。所有HTTP数据必须作为TLS“应用程序数据”发送,但在其他方面被视为HTTP的正常连接(包括作为持久连接的潜在重用)。

9.8. TLS连接关闭

TLS在(无错误)连接关闭之前使用关闭警报交换来提供安全的连接关闭;看见第6.1节属于[TLS13]。当收到有效的关闭警报时,可以确保实现不会在该连接上收到更多数据。

当实现知道它已经发送或接收了它关心的所有消息数据时,通常通过检测HTTP消息边界,它可能会通过发送关闭警报,然后关闭连接而不等待从对等方接收相应的关闭警报来生成“不完全关闭”。

不完全关闭不会对已经收到的数据的安全性产生疑问,但可能表明后续数据可能已被截断。由于TLS不直接知道HTTP消息帧,因此有必要检查HTTP数据本身以确定消息是否完整。不完整消息的处理在中定义第8节.

当遇到不完全关闭时,客户应该将其收到的所有请求视为已完成

  1. 内容物-长度标题字段或
  2. 终端零长度块(当传输编码使用块的)。

只有在收到有效的关闭警报时,既没有分块传输编码也没有内容长度的响应才是完整的。将不完整的消息视为完整消息可能会使实现暴露于攻击之下。

客户检测到未完成结算应该优雅地恢复。

客户必须在关闭连接之前发送关闭警报。不希望接收更多数据的客户端5月选择不等待服务器的关闭警报,只需关闭连接,从而在服务器端生成不完整的关闭。

服务器应该准备接收来自客户端的不完全关闭,因为客户端通常可以找到服务器端数据。

服务器必须尝试在关闭连接之前与客户端启动关闭警报交换。服务器5月发送关闭警报后关闭连接,从而在客户端生成不完整的关闭。

10 将消息作为数据括起来

10.1. 媒体类型消息/http

“message/http”媒体类型可用于封装单个http请求或响应消息,前提是它遵守所有“消息”类型关于行长度和编码的MIME限制。由于行长度限制,允许“message/http”中的字段值使用行折叠(obsfold公司),如中所述第5.2节,以在多行上传递字段值。“message/http”数据的接收者必须当消息被使用时,用一个或多个SP字符替换任何过时的折线。

类型名称:
消息
子类型名称:
http协议
所需参数:
不适用
可选参数:
版本,消息类型
版本:
所附消息的HTTP-版本号(例如“1.1”)。如果不存在,可以从正文的第一行确定版本。
消息类型:
消息类型-“请求”或“响应”。如果不存在,则可以从正文的第一行确定类型。
编码注意事项:
只允许“7位”、“8位”或“二进制”
安全注意事项:
看见第11节
互操作性注意事项:
不适用
发布的规范:
RFC 9112(参见第10.1条).
使用此媒体类型的应用程序:
不适用
片段标识符注意事项:
不适用
其他信息:
幻数:
不适用
此类型的别名已弃用:
不适用
文件扩展名:
不适用
Macintosh文件类型代码:
不适用
联系人和电子邮件地址以获取更多信息:
请参阅作者地址部分。
预期用途:
通用
使用限制:
不适用
作者:
请参阅“作者地址”部分。
更改控制器:
IESG公司

10.2. 媒体类型应用程序/http

“application/http”媒体类型可用于封装一个或多个http请求或响应消息(不混合)的管道。

类型名称:
应用
子类型名称:
http协议
所需参数:
不适用
可选参数:
版本,消息类型
版本:
所附消息的HTTP-版本号(例如“1.1”)。如果不存在,可以从正文的第一行确定版本。
消息类型:
消息类型-“请求”或“响应”。如果不存在,则可以从正文的第一行确定类型。
编码注意事项:
此类型包含的HTTP消息是“二进制”格式;通过电子邮件传输时,需要使用适当的内容传输编码。
安全注意事项:
看见第11节
互操作性注意事项:
不适用
发布的规范:
RFC 9112(参见第10.2条).
使用此媒体类型的应用程序:
不适用
片段标识符注意事项:
不适用
其他信息:
此类型的不推荐别名:
不适用
幻数:
不适用
文件扩展名:
不适用
Macintosh文件类型代码:
不适用
联系人和电子邮件地址以获取更多信息:
请参阅作者地址部分。
预期用途:
通用
使用限制:
不适用
作者:
请参阅作者地址部分。
更改控制器:
IESG公司

11 安全注意事项

本节旨在告知开发人员、信息提供者和用户与HTTP消息语法和解析相关的已知安全注意事项。有关HTTP语义、内容和路由的安全注意事项,请参阅【HTTP】.

11.1. 响应拆分

响应拆分(也称为CRLF注入)是一种常见的技术,用于各种针对Web使用的攻击,它利用HTTP消息帧的基于行的特性以及请求与持久连接上的响应的有序关联[克莱因]。当请求通过共享缓存时,此技术可能会造成特别严重的破坏。

响应拆分利用服务器(通常在应用程序服务器内)中的漏洞,攻击者可以在其中发送请求的某些参数内的编码数据,这些数据随后会在响应的任何响应标头字段内进行解码和回显。如果对解码数据进行精心处理,使其看起来像是响应已结束,随后的响应已开始,则响应已被分割,并且第二个明显响应中的内容由攻击者控制。然后,攻击者可以对同一持久连接发出任何其他请求,并诱骗接收者(包括中介)相信分割的后半部分是对第二个请求的权威答复。

例如,应用程序服务器可能会读取请求目标中的参数并在重定向中重用,从而导致相同的参数在位置响应的标题字段。如果应用程序对参数进行了解码,并且在将其放入响应字段时没有正确编码,则攻击者可以发送编码的CRLF八位字节和其他内容,使应用程序的单个响应看起来像两个或多个响应。

针对响应拆分的常见防御措施是过滤看起来像编码CR和LF的数据请求(例如“%0D”和“%0A”)。然而,这假设应用服务器只执行URI解码,而不是更模糊的数据转换,如字符集转换、XML实体转换、base64解码、sprintf重新格式化等。一种更有效的缓解措施是防止服务器核心协议库以外的任何东西在标头部分内发送CR或LF,这意味着将标头字段的输出限制为过滤坏八位字节的API,并且不允许应用程序服务器直接写入协议流。

11.2. 请求走私

请求走私([林哈特])是一种技术,利用不同接收者之间的协议解析差异,在明显无害的请求中隐藏其他请求(否则可能会被策略阻止或禁用)。与响应拆分一样,请求走私可能会导致对HTTP使用的各种攻击。

该规范对请求解析提出了新的要求,特别是在第6.3节,以降低请求走私的有效性。

11.3条。 消息完整性

HTTP没有定义确保消息完整性的特定机制,而是依赖底层传输协议的错误检测能力,以及使用长度或组块分隔的帧来检测完整性。历史上,大多数HTTP通信的非正式性质证明了缺乏单一完整性机制的合理性。然而,HTTP作为一种信息访问机制的流行导致其在消息完整性验证至关重要的环境中的使用越来越多。

“https”方案提供的机制,例如经过身份验证的加密,提供了防止修改消息的保护。然而,需要注意确保连接闭包不能用于截断消息(请参见第9.8节). 用户代理可能拒绝接受不完整的消息或对其进行特殊处理。例如,用于查看病史或药物交互信息的浏览器需要向用户指示协议何时检测到此类信息在传输过程中不完整、过期或损坏。可以通过用户代理扩展或响应中的消息完整性元数据来选择性地启用此类机制。

“http”方案无法防止意外或恶意修改消息。

即使使用“https”方案,也可以使用协议的扩展来降低中介对消息进行不必要修改的风险。通过使用通过可扩展元数据字段选择性地添加到消息中的消息身份验证代码或数字签名,可以确保完整性。

11.4. 消息机密性

HTTP依赖底层传输协议在需要时提供消息机密性。HTTP被专门设计为独立于传输协议,因此它可以在多种形式的加密连接上使用,通过选择URI方案或在用户代理配置内标识此类传输的选择。

“https”方案可用于识别需要机密连接的资源,如中所述第4.2.2节属于【HTTP】.

12 IANA考虑

以下注册的更改控制器是:“IETF(iesg@ietf.org)-互联网工程任务组”。

12.1条。 字段名称注册

IANA在“超文本传输协议(HTTP)字段名称注册表”中添加了以下字段名称https://www.iana.org/assignments/http-fields公司,如中所述第18.4条属于【HTTP】.

表1
字段名称状态章节评论
关闭永久的9.6 (保留)
MIME版本永久的B.1节
传输编码永久的6.1

12.2. 媒体类型注册

IANA更新了“媒体类型”注册表https://www.iana.org/assignments/media-types在节中包含注册信息10.110.2对于媒体类型,分别为“message/http”和“application/http“。

12.3. 传输编码注册

IANA已在更新“HTTP传输编码注册表”https://www.iana.org/assignments/http-parameters网站/注册程序为第7.3节以及下表中总结的内容编码名称。

表2
姓名描述章节
块状的以一系列块的形式转移7.1
压缩UNIX“压缩”数据格式[韦尔奇]7.2
放气“放气”压缩数据([RFC1951])在“zlib”数据格式中([射频1950年])7.2
gzip公司GZIP文件格式[RFC1952]7.2
拖车(保留)12.3
x压缩已弃用(压缩别名)7.2
x-gzip协议不推荐(gzip的别名)7.2

12.4. ALPN协议ID注册

IANA已更新“TLS应用层协议协商(ALPN)协议ID”注册表,地址为https://www.iana.org/assignments/tls-extensiontype-values网站/注册如下:

表3
协议标识顺序参考
HTTP/1.1协议0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31(“http/1.1”)副本请求9112

13工具书类

13.1.规范性引用文件

[缓存]
Fielding,R.,Ed.,Nottingham,M.,Ed,和J.Reschke,Ed.”HTTP缓存”,标准98,RFC 9111,内政部10.17487/RFC91112022年6月。
[超文本传输协议]
Fielding,R.,Ed.,Nottingham,M.,Ed,和J.Reschke,Ed.”HTTP语义”,标准97,RFC 9110,内政部10.17487/RFC91102022年6月。
[射频1950]
Deutsch,P.和J-L.Gailly,”ZLIB压缩数据格式规范3.3版“,RFC 1950,DOI 10.17487/RFC19501996年5月<https://www.rfc-editor.org/info/rfc1950>.
[RFC1951号文件]
Deutsch,P.“DEFLATE压缩数据格式规范1.3版“,RFC 1951,内政部10.17487/RFC19511996年5月<https://www.rfc-editor.org/info/rfc1951>.
[RFC1952号文件]
Deutsch,P.,“GZIP文件格式规范4.3版“,RFC 1952,内政部10.17487/RFC19521996年5月<https://www.rfc-editor.org/info/rfc1952>.
[RFC2119协议]
布拉德纳,S.“RFC中用于指示需求级别的关键词”,业务连续性计划14,RFC 2119,内政部10.17487/RFC21191997年3月<https://www.rfc-editor.org/info/rfc2119>.
[RFC5234号文件]
Crocker,D.,Ed.和P.Overell,”用于语法规范的增强BNF:ABNF”,标准68,RFC 5234,内政部10.17487/RFC52342008年1月<https://www.rfc-editor.org/info/rfc5234>.
[RFC7405协议]
Kyzivat,P.,“ABNF中的大小写敏感字符串支持“,RFC 7405,DOI文件10.17487/RFC74052014年12月<https://www.rfc-editor.org/info/rfc7405>.
[RFC8174号文件]
B.雷巴“RFC 2119关键词中大小写的歧义”,业务连续性计划14,RFC 8174,内政部10.17487/RFC81742017年5月<https://www.rfc-editor.org/info/rfc8174>.
[TLS13标准]
Rescorla,E.,“传输层安全(TLS)协议1.3版“,RFC 8446,内政部10.17487/RFC8446,2018年8月<https://www.rfc-editor.org/info/rfc8446>.
[URI(URI)]
Berners-Lee,T.、Fielding,R.和L.Masinter,“统一资源标识符(URI):通用语法”,标准66,RFC 3986,内政部10.17487/RFC39862005年1月<https://www.rfc-editor.org/info/rfc3986>.
[美国科学院国际研究所]
美国国家标准协会,“编码字符集——7位美国信息交换标准代码”,ANSI X3.41986年。
[韦尔奇]
T.韦尔奇“一种高性能数据压缩技术“,IEEE计算机17(6),内政部10.1109/MC.1984.16591581984年6月<https://ieeexplore.ieee.org/document/1659158/>.

13.2.资料性引用

[HTTP/1.0协议]
Berners-Lee,T.、Fielding,R.和H.Frystyk,“超文本传输协议——HTTP/1.0“,RFC 1945,DOI文件10.17487/RFC19451996年5月<https://www.rfc-editor.org/info/rfc1945>.
[克莱因]
克莱恩,A.,“分而治之-HTTP响应拆分、Web缓存中毒攻击和相关主题“,2004年3月<https://packetstormsecurity.com/papers/general/whitepaper_httpresponse.pdf>.
[林哈特]
Linhart,C.、Klein,A.、Heled,R.和S.Orrin,”HTTP请求走私“,2005年6月<https://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf>.
[RFC2045协议]
Freed、N.和N.Borenstein,”多用途互联网邮件扩展(MIME)第1部分:互联网邮件正文格式“,RFC 2045,内政部10.17487/RFC2045,1996年11月<https://www.rfc-editor.org/info/rfc2045>.
[RFC2046协议]
Freed、N.和N.Borenstein,”多用途互联网邮件扩展(MIME)第二部分:媒体类型“,RFC 2046,内政部10.17487/RFC20461996年11月<https://www.rfc-editor.org/info/rfc2046>.
[RFC2049协议]
Freed、N.和N.Borenstein,”多用途互联网邮件扩展(MIME)第五部分:一致性标准和示例“,RFC 2049,DOI 10.17487/RFC20491996年11月<https://www.rfc-editor.org/info/rfc2049>.
[RFC2068协议]
Fielding,R.、Gettys,J.、Mogul,J.,Frystyk,H.和T.Berners-Lee,”超文本传输协议——HTTP/1.1“,RFC 2068,内政部10.17487/RFC20681997年1月<https://www.rfc-editor.org/info/rfc2068>.
[RFC2557型]
Palme,J.、Hopmann,A.和N.Shelness,”聚合文档的MIME封装,例如HTML(MHTML)”,RFC 2557,内政部10.17487/RFC25571999年3月<https://www.rfc-editor.org/info/rfc2557>.
[RFC5322号文件]
Resnick,P.编辑,“Internet消息格式“,RFC 5322,内政部10.17487/RFC53222008年10月<https://www.rfc-editor.org/info/rfc5322>.
[RFC7230协议]
Fielding,R.,Ed.和J.Reschke,Ed.”超文本传输协议(HTTP/1.1):消息语法和路由”,RFC 7230,内政部10.17487/RFC72302014年6月<https://www.rfc-editor.org/info/rfc7230>.
[RFC8126协议]
Cotton,M.、Leiba,B.和T.Narten,”RFC中IANA注意事项部分的编写指南”,业务连续性计划26,RFC 8126,内政部10.17487/RFC81262017年6月<https://www.rfc-editor.org/info/rfc8126>.

附录A。 收集的ABNF

在下面收集的ABNF中,列表规则根据展开第5.6.1节属于【HTTP】.

BWS公司=<BWS,参见【HTTP】,第5.6.3节>HTTP消息=起始线CRLF*(场线CRLF)CRLF[消息正文]HTTP-名称=%x48.54.50;超文本传输协议HTTP-版本=HTTP-name“/”数字“.”数字OWS系统=<OWS,参见【HTTP】,第5.6.3节>远程操作系统=<RWS,参见【HTTP】,第5.6.3节>传输编码=[传输编码*(OWS“,”OWS传输编码) ]绝对-URI=<绝对URI,参见[URI],第4.3节>绝对形态=绝对-URI绝对通过率=<绝对路径,参见【HTTP】,第4.1节>星号形状= "*"权威=<权限,请参阅[URI],第3.2节>权威式的=uri-host“:”端口=chunk-size[chunk-ext]CRLF chunk-data CRLF组块数据=1*10月块文本=*(BWS“;”BWS chunk-ext-name[BWS“=”BWS chunk-ext-val] )块文本名称=标记chunk-ext-val语言=标记/报价-字符串块大小=1*六角块状身体=*块last-chunk trailer-section CRLF实地考察=字段名称“:”OWS字段值OWS字段名称=<字段名称,请参阅【HTTP】,第5.1节>字段值=>字段值,请参阅【HTTP】,第5.5节>last-chunk系列=1*“0”[chunk-ext]CRLF消息-正文=*10月方法=标记obsfold公司=OWS CRLF RWSobs-文本=<obs-text,请参阅【HTTP】,第5.6.4节>原始形态=绝对路径[“?”查询]港口=<端口,请参阅[URI],第3.2.3节>查询=<查询,请参阅[URI],第3.4节>报价单=<quoted-string,参见【HTTP】,第5.6.4节>合理措辞=1*(HTAB/SP/VCHAR/obs-text)请求行=方法SP请求-目标SP HTTP-版本请求目标=原始形式/绝对形式/权威形式/星号形状起始线=请求行/状态行状态代码=3迪吉特状态行=HTTP-版本SP状态代码SP[原因措辞]代币=<标记,请参阅【HTTP】,第5.6.2节>拖车段=*(场线CRLF)转移编码=<传输编码,请参阅【HTTP】,第10.1.4节>乌里霍斯特=<主机,请参阅[URI],第3.2.2节>

附录B。 HTTP和MIME之间的差异

HTTP/1.1使用了为Internet消息格式定义的许多构造[RFC5322]和多用途互联网邮件扩展(MIME)[RFC2045]以允许消息主体以开放的各种表示和可扩展的字段进行传输。然而,其中一些结构已经被重新解释,以更好地适应交互式通信的需要,这导致了在HTTP中如何使用MIME结构方面的一些差异。仔细选择这些差异是为了优化二进制连接的性能,允许更自由地使用新媒体类型,简化日期比较,并适应常见的实现。

本附录描述了HTTP与MIME不同的特定领域。进出严格MIME环境的代理和网关需要了解这些差异,并在必要时提供适当的转换。

B.1、。 MIME版本

HTTP不是符合MIME的协议。但是,消息可以包含单个MIME-Version头字段,以指示用于构造消息的MIME协议版本。使用MIME-Version头字段表示消息完全符合MIME协议(如[RFC2045]). 在将HTTP消息导出到严格的MIME环境时,发送方负责确保完全一致性(如果可能)。

B.2节。 转换为标准形式

MIME要求在传输之前将Internet邮件正文部分转换为规范形式,如中所述第4节属于[RFC2049],并且带有“文本”类型的内容表示换行符为CRLF,禁止在换行符序列之外使用CR或LF[RFC2046]相反,HTTP不关心是使用CRLF、裸CR还是裸LF来指示内容中的换行符。

从HTTP到严格MIME环境的代理或网关应该将文本媒体类型中的所有换行转换为CRLF的RFC 2049规范形式。但是,请注意,由于存在内容编码HTTP允许使用一些不使用八位字节13和10分别表示CR和LF的字符集。

转换将破坏应用于原始内容的任何加密校验和,除非原始内容已采用规范形式。因此,建议对HTTP中使用此类校验和的任何内容使用规范形式。

B.3节。 日期格式的转换

HTTP/1.1使用一组受限的日期格式(第5.6.7节属于【HTTP】)简化数据比较过程。来自其他协议的代理和网关应确保日期消息中的头字段符合HTTP/1.1格式之一,并在必要时重写日期。

B.4。 内容编码的转换

MIME不包含任何与HTTP等效的概念内容编码标头字段。由于这是媒体类型的修改器,从HTTP到MIME兼容协议的代理和网关应该更改内容类型头字段或在转发消息之前对表示进行解码。(Internet邮件的Content Type的一些实验应用程序使用了媒体类型参数“;conversions=<Content coding>”来执行与Content Encoding等效的功能。但是,此参数不是MIME标准的一部分。)

B.5节。 内容传输编码的转换

HTTP不使用MIME的Content-Transfer-Encoding字段。从MIME兼容协议到HTTP的代理和网关需要在将响应消息传递到HTTP客户端之前删除任何内容传输编码。

从HTTP到MIME兼容协议的代理和网关负责确保消息的格式和编码正确,以便在该协议上安全传输,其中“安全传输”由所使用协议的限制定义。如果这样做可以提高通过目标协议进行安全传输的可能性,那么这样的代理或网关应该使用适当的内容传输编码来转换和标记数据。

B.6节。 MHTML和线路长度限制

与MHTML共享代码的HTTP实现[RFC2557]实现需要注意MIME行长度的限制。由于HTTP没有此限制,HTTP不会折叠长行。通过HTTP传输的MHTML消息遵循MHTML的所有约定,包括行长度限制和折叠、规范化等,因为HTTP传输消息正文时没有修改,除了“多部分/字节”类型之外(第14.6条属于【HTTP】),不解释其中可能包含的内容或任何MIME标头行。

附录C。 以前RFC的更改

C.1、。 HTTP/0.9的更改

由于HTTP/0.9不支持请求中的头字段,因此它没有支持基于名称的虚拟主机的机制(通过检查主机标题字段)。任何实现基于名称的虚拟主机的服务器都应该禁用对HTTP/0.9的支持。事实上,大多数看似HTTP/0.9的请求都是由客户端未能正确编码请求目标而导致的HTTP/1.x请求构造不良。

第2章。 HTTP/1.0的更改

C.2.1、。 多宿主Web服务器

客户端和服务器支持主机标题字段(第7.2节属于【HTTP】),如果HTTP/1.1请求中缺少,则报告错误,并接受绝对URI(第3.2节)是HTTP/1.1定义的最重要的更改之一。

较旧的HTTP/1.0客户端假定IP地址和服务器是一对一的关系;除了请求指向的IP地址之外,没有建立用于区分请求的预期服务器的机制。这个主机header字段是在HTTP/1.1的开发过程中引入的,尽管大多数HTTP/1.0浏览器都很快实现了它,但为了确保完全采用,对所有HTTP/1.4请求都提出了额外的要求。在撰写本文时,大多数基于HTTP的服务都依赖于Host报头字段来定位请求。

C.2.2、。 保持连接畅通

在HTTP/1.0中,每个连接都是在请求之前由客户端建立的,并在发送响应之后由服务器关闭。然而,一些实现实现了中描述的持久连接的显式协商(“Keep-Alive”)版本第19.7.1条属于[RFC2068].

一些客户机和服务器可能希望通过使用“Connection:keep-alive”请求头字段显式协商来与这些以前的持久连接方法兼容。然而,HTTP/1.0持久连接的一些实验实现是错误的;例如,如果HTTP/1.0代理服务器不理解连接,它将错误地将该头字段转发到下一个入站服务器,这将导致挂起连接。

一个尝试的解决方案是引入Proxy-Connection头字段,专门针对代理。在实践中,这也是不可行的,因为代理通常部署在多个层中,这带来了上面讨论的相同问题。

因此,建议客户端不要在任何请求中发送Proxy-Connection头字段。

还鼓励客户仔细考虑在请求中使用“Connection:keep-alive”;虽然它们可以启用与HTTP/1.0服务器的持久连接,但使用它们的客户机需要监视连接中的“挂起”请求(这表明客户机应该停止发送头字段),并且当使用代理时,客户机根本不应该使用此机制。

C.2.3、。 传输编码简介

HTTP/1.1引入了传输编码标题字段(第6.1节). 在通过符合MIME的协议转发HTTP消息之前,需要对传输代码进行解码。

C.3、。 RFC 7230的变更

介绍HTTP设计目标、历史、体系结构、一致性标准、协议版本控制、URI、消息路由和头字段的大部分章节都移到了【HTTP】。本文档已简化为仅针对HTTP/1.1的消息传递语法和连接管理要求。

内容外禁止使用裸CR。(第2.2节)

ABNF的定义权威式的已从URI的更通用权限组件(其中端口是可选的)更改为CONNECT所需的特定主机:端口格式。(第3.2.3节)

在处理不明确的消息框架时,收件人需要避免走私/拆分攻击。(第6.1节)

在用于分块扩展的ABNF中,重新引入了“;”和“=”周围的(错误的)空白。已在中删除空白[RFC7230],但该更改被发现破坏了现有的实现。(第7.1.1节)

尾部字段语义现在超越了分块传输编码的细节。块的解码算法(第7.1.3节)已更新,以鼓励存储/转发与标题部分分开的尾部字段,仅允许在收件人知道相应字段定义允许并定义如何合并时合并到标题部分,否则放弃尾部字段而不合并。拖车部分现在称为拖车部分,以便与收割台部分更加一致,与车身部分更加不同。(第7.1.2节)

不允许使用称为“q”的传输编码参数,以避免与TE公司标题字段。(第7.3节)

致谢

请参见附录“确认”属于【HTTP】,也适用于本文件。

索引

一个 C D类 F类 G公司 H(H) K(K) L(左) M(M) O(运行) R(右) T型 U型 W公司 X(X)

作者地址

罗伊·T·菲尔丁(编辑)
土砖
公园大道345号
加利福尼亚州圣何塞市,邮编:95110
美利坚合众国
电子邮件:fielding@gbiv.com
URI(URI):https://roy.gbiv.com/
马克·诺丁汉(编辑)
快速地
普拉兰
澳大利亚
电子邮件:mnot@mnot.net
URI(URI):网址:https://www.mnot.net/
朱利安·雷什克(编辑)
greenbytes股份有限公司
哈芬威格16
穆斯特48155
德国
电子邮件:julian.reschke@greenbytes.de
URI(URI):https://greenbytes.de/tech/webdav/