Skip to main content

10. Message Context (消息上下文)

10.1. Request Context Fields (请求上下文字段)

下面的请求头部字段提供有关请求上下文的附加信息,包括有关用户,用户代理和请求背后的资源的信息.

10.1.1. Expect

请求中的"Expect"头部字段指示服务器为了正确处理此请求需要支持的一组特定行为(期望).

Expect =      #expectation
expectation = token [ "=" ( token / quoted-string ) parameters ]

Expect字段值不区分大小写.

本规范定义的唯一期望是"100-continue"(没有定义的参数).

接收到包含除100-continue之外的成员的Expect字段值的服务器可以 (MAY) 以417(Expectation Failed)状态码响应,以指示无法满足意外的期望.

"100-continue"期望通知接收者客户端即将在此请求中发送(大概是大型)内容,并希望如果方法,目标URI和头部字段不足以导致立即成功,重定向或错误响应,则接收100(Continue)临时响应. 这允许客户端在实际发送内容之前等待指示是否值得发送内容,当数据巨大或客户端预期可能出现错误时(例如,在首次发送状态更改方法时,没有先前验证的身份验证凭据),这可以提高效率.

例如,以以下内容开始的请求

PUT /somewhere/fun HTTP/1.1
Host: origin.example.com
Content-Type: video/h264
Content-Length: 1234567890987
Expect: 100-continue

允许源服务器在客户端开始用不必要的数据传输填充管道之前立即以错误消息响应,例如401(Unauthorized)或405(Method Not Allowed).

客户端的要求:

  • 客户端不得 (MUST NOT) 在不包含内容的请求中生成100-continue期望.
  • 在发送请求内容之前将等待100(Continue)响应的客户端必须 (MUST) 发送包含100-continue期望的Expect头部字段.
  • 发送100-continue期望的客户端不需要等待任何特定时间长度; 此类客户端可以 (MAY) 继续发送内容,即使它尚未收到响应. 此外,由于100(Continue)响应不能通过HTTP/1.0中间人发送,因此此类客户端不应该 (SHOULD NOT) 在发送内容之前无限期地等待.
  • 接收到对包含100-continue期望的请求的417(Expectation Failed)状态码响应的客户端应该 (SHOULD) 在没有100-continue期望的情况下重复该请求,因为417响应仅表示响应链不支持期望(例如,它通过HTTP/1.0服务器).

服务器的要求:

  • 在HTTP/1.0请求中接收100-continue期望的服务器必须 (MUST) 忽略该期望.
  • 如果服务器已经接收到相应请求的部分或全部内容,或者如果帧指示没有内容,则服务器可以 (MAY) 省略发送100(Continue)响应.
  • 发送100(Continue)响应的服务器必须 (MUST) 在接收和处理请求内容后最终发送最终状态码,除非连接过早关闭.
  • 在读取整个请求内容之前以最终状态码响应的服务器应该 (SHOULD) 指示它是否打算关闭连接(例如,参见[HTTP/1.1]的第9.6节)或继续读取请求内容.

在接收到具有方法,目标URI和包含100-continue期望并指示将跟随请求内容的完整头部区段的HTTP/1.1(或更高版本)请求时,源服务器必须 (MUST) 发送:

  • 如果可以通过仅检查方法,目标URI和头部字段来确定该状态,则立即响应最终状态码,或
  • 立即100(Continue)响应以鼓励客户端发送请求内容.

源服务器不得 (MUST NOT) 在发送100(Continue)响应之前等待内容.

在接收到具有方法,目标URI和包含100-continue期望并指示将跟随请求内容的完整头部区段的HTTP/1.1(或更高版本)请求时,代理必须 (MUST):

  • 如果可以通过仅检查方法,目标URI和头部字段来确定该状态,则发送立即响应最终状态码,或
  • 通过向下一个入站服务器发送相应的请求行和头部区段来向源服务器转发请求.

如果代理相信(从配置或过去的交互)下一个入站服务器仅支持HTTP/1.0,则代理可以 (MAY) 生成立即100(Continue)响应以鼓励客户端开始发送内容.

10.1.2. From

"From"头部字段包含控制请求用户代理的人类用户的Internet电子邮件地址. 该地址应该是机器可用的,如[RFC5322]的第3.4节中的"mailbox"所定义:

From    = mailbox

mailbox = <mailbox, see [RFC5322], Section 3.4>

一个示例是:

From头部字段很少由非机器人用户代理发送. 用户代理不应该 (SHOULD NOT) 在没有用户明确配置的情况下发送From头部字段,因为这可能与用户的隐私利益或其站点的安全策略冲突.

机器人用户代理应该 (SHOULD) 发送有效的From头部字段,以便在服务器上出现问题时可以联系负责运行机器人的人,例如机器人发送过多,不需要或无效的请求.

服务器不应该 (SHOULD NOT) 将From头部字段用于访问控制或身份验证,因为其值预期对接收或观察请求的任何人可见,并且通常记录在日志文件和错误报告中,而没有任何隐私期望.

10.1.3. Referer

"Referer" [原文如此] 头部字段允许用户代理指定从中获得目标URI的资源的URI引用(即,"引用者" (referrer),尽管字段名称拼写错误). 用户代理在生成Referer字段值时不得 (MUST NOT) 包含URI引用[URI]的片段和userinfo组件(如果有).

Referer = absolute-URI / partial-URI

字段值是absolute-URI或partial-URI. 在后一种情况下(第4节),引用的URI相对于目标URI([URI],第5节).

Referer头部字段允许服务器为简单分析,日志记录,优化缓存等生成到其他资源的反向链接. 它还允许找到过时或拼写错误的链接以进行维护. 一些服务器使用Referer头部字段作为拒绝来自其他站点的链接(所谓的"深度链接")或限制跨站点请求伪造(CSRF)的手段,但并非所有请求都包含它.

示例:

Referer: http://www.example.org/hypertext/Overview.html

如果目标URI是从没有自己的URI的源获得的(例如,来自用户键盘的输入,或用户书签/收藏夹中的条目),则用户代理必须 (MUST) 排除Referer头部字段或以"about:blank"的值发送它.

Referer头部字段值不需要传达引用资源的完整URI; 用户代理可以 (MAY) 截断除引用源之外的部分.

如果引用资源的标识符泄露个人信息(例如帐户名称)或应该保密的资源(例如防火墙后面或安全服务内部),则Referer头部字段有可能泄露有关请求上下文或用户浏览历史的信息,这是隐私问题. 大多数通用用户代理在引用资源是本地"file"或"data" URI时不发送Referer头部字段. 如果引用资源是使用安全协议访问的并且请求目标的源与引用资源的源不同,则用户代理不应该 (SHOULD NOT) 发送Referer头部字段,除非引用资源明确允许发送Referer. 如果引用资源是使用安全协议访问的,则用户代理不得 (MUST NOT) 在不安全的HTTP请求中发送Referer头部字段. 有关其他安全注意事项,请参阅第17.9节.

已知一些中间人会不加区别地从传出请求中删除Referer头部字段. 这具有干扰防止CSRF攻击的不幸副作用,这对其用户可能更有害. 希望限制Referer中信息泄露的中间人和用户代理扩展应该将其更改限制为特定编辑,例如用假名替换内部域名或截断查询和/或路径组件. 当字段值与目标URI共享相同的方案和主机时,中间人不应该 (SHOULD NOT) 修改或删除Referer头部字段.

10.1.4. TE

"TE"头部字段描述客户端关于传输编码和尾部区段的能力.

如第6.5节所述,在请求中发送带有"trailers"成员的TE字段表示客户端不会丢弃尾部字段.

TE也在HTTP/1.1中使用,以告知服务器客户端能够在响应中接受哪些传输编码. 截至发布时,只有HTTP/1.1使用传输编码(参见[HTTP/1.1]的第7节).

TE字段值是成员列表,每个成员(除"trailers"外)由传输编码名称令牌组成,带有指示客户端对该传输编码的相对偏好的可选权重(第12.4.2节)以及该传输编码的可选参数.

TE                 = #t-codings
t-codings = "trailers" / ( transfer-coding [ weight ] )
transfer-coding = token *( OWS ";" OWS transfer-parameter )
transfer-parameter = token BWS "=" BWS ( token / quoted-string )

TE的发送者还必须 (MUST) 在Connection头部字段(第7.6.1节)中发送"TE"连接选项,以通知中间人不要转发此字段.

10.1.5. User-Agent

"User-Agent"头部字段包含有关发起请求的用户代理的信息,服务器通常使用它来帮助识别报告的互操作性问题的范围,解决或定制响应以避免特定用户代理限制,以及有关浏览器或操作系统使用的分析. 用户代理应该 (SHOULD) 在每个请求中发送User-Agent头部字段,除非特别配置为不这样做.

User-Agent = product *( RWS ( product / comment ) )

User-Agent字段值由一个或多个产品标识符组成,每个标识符后跟零个或多个注释(第5.6.5节),它们一起标识用户代理软件及其重要子产品. 按照惯例,产品标识符按其对识别用户代理软件的重要性降序列出. 每个产品标识符由名称和可选版本组成.

product         = token ["/" product-version]
product-version = token

发送者应该 (SHOULD) 将生成的产品标识符限制为识别产品所必需的内容; 发送者不得 (MUST NOT) 在产品标识符中生成广告或其他非必要信息. 发送者不应该 (SHOULD NOT) 在product-version中生成不是版本标识符的信息(即,同一产品名称的连续版本应该仅在产品标识符的product-version部分不同).

示例:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

用户代理不应该 (SHOULD NOT) 生成包含不必要的细粒度细节的User-Agent头部字段,并且应该 (SHOULD) 限制第三方添加子产品. 过长和详细的User-Agent字段值会增加请求延迟和用户被识别违背其意愿("指纹识别")的风险.

同样,鼓励实现不要使用其他实现的产品令牌来声明与它们的兼容性,因为这违背了字段的目的. 如果用户代理伪装成不同的用户代理,接收者可以假设用户有意希望看到为该标识的用户代理定制的响应,即使它们对实际使用的用户代理可能不太适用.

10.2. Response Context Fields (响应上下文字段)

下面的响应头部字段提供有关响应的附加信息,超出状态码所暗示的内容,包括有关服务器,目标资源或相关资源的信息.

10.2.1. Allow

"Allow"头部字段列出目标资源支持的方法集. 此字段的目的严格是通知接收者与资源关联的有效请求方法.

Allow = #method

使用示例:

Allow: GET, HEAD, PUT

实际允许的方法集由源服务器在每个请求时定义. 源服务器必须 (MUST) 在405(Method Not Allowed)响应中生成Allow头部字段,并且可以 (MAY) 在任何其他响应中这样做. 空的Allow字段值表示资源不允许任何方法,这可能发生在资源已被配置临时禁用的405响应中.

代理不得 (MUST NOT) 修改Allow头部字段——它不需要理解所有指示的方法以便根据通用消息处理规则处理它们.

10.2.2. Location

"Location"头部字段用于某些响应中以引用与响应相关的特定资源. 关系类型由请求方法和状态码语义的组合定义.

Location = URI-reference

字段值由单个URI-reference组成. 当它具有相对引用的形式([URI],第4.2节)时,最终值通过针对目标URI解析它来计算([URI],第5节).

对于201(Created)响应,Location值引用请求创建的主要资源. 对于3xx(Redirection)响应,Location值引用自动重定向请求的首选目标资源.

如果3xx(Redirection)响应中提供的Location值没有片段组件,则用户代理必须 (MUST) 处理重定向,就好像该值继承了用于生成目标URI的URI引用的片段组件(即,重定向继承原始引用的片段,如果有).

例如,为URI引用"http://www.example.org/~tim"生成的GET请求可能导致包含头部字段的303(See Other)响应:

Location: /People.html#tim

这建议用户代理重定向到"http://www.example.org/People.html#tim"

同样,为URI引用"http://www.example.org/index.html#larry"生成的GET请求可能导致包含头部字段的301(Moved Permanently)响应:

Location: http://www.example.net/index.html

这建议用户代理重定向到"http://www.example.net/index.html#larry",保留原始片段标识符.

在某些情况下,Location值中的片段标识符是不合适的. 例如,201(Created)响应中的Location头部字段应该提供特定于所创建资源的URI.

注意: 一些接收者尝试从不是有效URI引用的Location头部字段中恢复. 本规范不强制或定义此类处理,但为了健壮性而允许它. Location字段值不能允许成员列表,因为逗号列表分隔符是URI-reference中的有效数据字符. 如果发送了带有多个Location字段行的无效消息,接收者可能会将这些字段行组合成一个值. 沿路径的恢复可能会将这些字段行组合成一个值. 从这种情况恢复有效的Location字段值是困难的,并且在实现之间不可互操作.

注意: Content-Location头部字段(第8.7节)与Location的不同之处在于Content-Location引用与所包含表示对应的最具体资源. 因此,响应可能同时包含Location和Content-Location头部字段.

10.2.3. Retry-After

服务器发送"Retry-After"头部字段以指示用户代理在发出后续请求之前应该等待多长时间. 当与503(Service Unavailable)响应一起发送时,Retry-After指示服务预期对客户端不可用多长时间. 当与任何3xx(Redirection)响应一起发送时,Retry-After指示在发出重定向请求之前要求用户代理等待的最短时间.

Retry-After字段值可以是HTTP-date或接收响应后延迟的秒数.

Retry-After = HTTP-date / delay-seconds

delay-seconds值是非负十进制整数,表示以秒为单位的时间.

delay-seconds  = 1*DIGIT

其使用的两个示例是

Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120

在后一个示例中,延迟为2分钟.

10.2.4. Server

"Server"头部字段包含有关源服务器用于处理请求的软件的信息,客户端通常使用它来帮助识别报告的互操作性问题的范围,解决或定制请求以避免特定服务器限制,以及有关服务器或操作系统使用的分析. 源服务器可以 (MAY) 在其响应中生成Server头部字段.

Server = product *( RWS ( product / comment ) )

Server头部字段值由一个或多个产品标识符组成,每个标识符后跟零个或多个注释(第5.6.5节),它们一起标识源服务器软件及其重要子产品. 按照惯例,产品标识符按其对识别源服务器软件的重要性降序列出. 每个产品标识符由名称和可选版本组成,如第10.1.5节中定义.

示例:

Server: CERN/3.0 libwww/2.17

源服务器不应该 (SHOULD NOT) 生成包含不必要的细粒度细节的Server头部字段,并且应该 (SHOULD) 限制第三方添加子产品. 过长和详细的Server字段值会增加响应延迟,并可能泄露内部实现细节,这可能使攻击者(稍微)更容易找到和利用已知的安全漏洞.