HTTP头字段中是否可以包含多个CRLF?

19

以下是最新的HTTP RFC 7230中HTTP消息的定义。

 HTTP-message   = start-line
                  *( header-field CRLF )
                  CRLF
                  [ message-body ]

以下是“头字段”的定义:

 header-field   = field-name ":" OWS field-value OWS

 field-name     = token
 field-value    = *( field-content / obs-fold )
 field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
 field-vchar    = VCHAR / obs-text

 obs-fold       = CRLF 1*( SP / HTAB )

...还有:

obs-text       = %x80-FF

..还有ABNF的

 VCHAR          =  %x21-7E
                                 ; visible (printing) characters

我们可以看到,字段-值可能具有多个obs-fold,而obs-fold具有一个CRLF。对我来说很奇怪,因为我认为CRLF是头行的结尾。是否有多个CRLF编码到一个头字段的示例?或者,我是否误解了定义?


你尝试在每个CRLF前添加一个空格了吗?单独的空行表示HTTP头部结束。 - paddy
我并没有实践过什么。我只是困惑于ABNF对头字段的定义是否正确。 - appleleaf
1
那么,您是在询问HTTP的RFC中是否存在错误 - 这是全球范围内使用和审查最广泛的信息传输协议之一。 - paddy
是的。但是,我不确定这是一个错误还是我的误解。 - appleleaf
@appleleaf,这是不是 https://dev59.com/33TYa4cB1Zd3GeqPqRKO 的重复问题? - Pacerier
我认为这两个问题应该是重复的问题。 - appleleaf
1个回答

30
您对标准的理解是正确的。在过去,RFC 2616 支持多行头部值。这个特性被称为“折叠行”:
HTTP/1.1 头字段值可以折叠到多行,如果连续行以空格或水平制表符开头。所有线性空白,包括折叠,与 SP 具有相同的语义。接收者可以在解释字段值或向下游转发消息之前用单个 SP 替换任何线性空白。
因此,以下两种形式是等效的:
Header: value1, value2

并且

Header: value1,
        value2

较新的RFC 7230明确不推荐使用此功能。实际上,“obs-fold”中的“obs”代表“过时”。历史上,HTTP标头字段值可以通过在每个额外行前面至少添加一个空格或水平制表符(obs-fold)来扩展多行。本规范不再建议使用这种折行方式,除非是在message/http媒体类型(第8.3.1节)内。发送方不得生成包含折行的消息(即具有任何字段值,其中包含与obs-fold规则匹配的内容),除非该消息旨在打包到message/http媒体类型中。因此,尽管我从未在实践中看到过此功能(或者至少没有注意到它),但它确实存在。此外,似乎连折行都没有被完全废弃,其用法仍然允许在HTTP媒体类型标头中使用。
多行标题仍然被标准的HTTP头解析器所支持,例如PHP [arv]、JavaGo。我找到的唯一一个具体的例子是在这篇technet博客文章中,其中包含了这张图片。

http header line folding

请注意 Content-Type 头部中的黄色 0d 0a (回车,换行)字符。

@Malt,OP正在询问“是否有一个示例可以将多个CRLF编码到一个头字段中?”您的示例仅显示了一个CR LF HT序列...换句话说,它没有回答问题。 - Pacerier
@Pacerier 在 Content-Type 头字段中有两个 CRLF。一个在黄色中间的字段中。另一个在字段末尾,在下一个字段之前,它作为正常的 HTTP 头字段分隔符。 - Malt
你是指的红色圆圈吗?如果是,那不是OP所说的。他说的是多个obs-fold,也就是不仅仅是"CR LF",而是"CR LF HT/SP"。红色圆圈是"CR LF 'S'"和"CR LF 'C'"。 - Pacerier
@Pacerier OP 特别询问了关于“将多个 CRLF 编码到一个头字段中”的问题。该示例显示一个 CRLF 在 Content-Type 字段内,该字段也以 CRLF 结尾。是的,它不是多个obs-fold,但我认为这不是问题的关键。 - Malt
我知道这个答案有点老,但你写道“此外,似乎换行甚至没有完全被弃用,其使用仍允许用于HTTP媒体类型头部。”。什么是HTTP媒体类型头部,现在已不建议使用的头部换行是否有使用示例? - tonix
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接