如何拆分标头值?

mpe*_*pen 5 http rfc2616 http-headers

我正在解析 HTTP 标头。我想将标头值拆分为有意义的数组。

例如,Cache-Control: no-cache, no-store应该返回['no-cache','no-store'].

HTTP RFC2616 说:

当且仅当该头字段的整个字段值被定义为逗号分隔列表[即#(values)]时,具有相同字段名称的多个消息头字段可以出现在消息中。通过将每个后续字段值附加到第一个字段值(每个字段值之间用逗号分隔),必须可以将多个标头字段组合成一个“字段名称:字段值”对,而不更改消息的语义。因此,接收具有相同字段名称的头字段的顺序对于组合字段值的解释很重要,因此当转发消息时,代理不得更改这些字段值的顺序

但我不确定反过来是否正确——用逗号分隔安全吗?

我已经找到了一个导致问题的例子。例如,我的用户代理字符串是

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36
Run Code Online (Sandbox Code Playgroud)

即,它在“KHTML”之后包含一个逗号。显然,我没有多个用户代理,因此拆分此标头没有意义。

User-Agent 字符串是唯一的例外,还是还有更多?

ioq*_*tix 6

不,基于逗号分割标题是不安全的。例如,Accept: foo/bar;p="A,B,C", bob/dole;x="apples,oranges"是一个有效的标头,但如果您尝试在逗号上进行拆分以获取 mime 类型列表,则会得到无效结果。

正确的答案是每个标头都是使用 ABNF 指定的,其中大多数在各种 RFC 中,例如Accept:RFC7231 第 5.3.2 节中定义

我遇到了这个特定问题并编写了一个解析器在边缘情况下对其进行了测试。不仅解析标头很重要,解释它并给出正确的结果也很重要

有些标头比其他标头更复杂,但本质上每个标头都有自己的语法,应该尊重这些语法以进行正确(和安全)的处理。