4

我正在解析 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

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

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

4

3 回答 3

4

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

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

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

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

于 2016-02-04T04:40:56.683 回答
1

如果该标头字段的整个字段值被定义为逗号分隔的列表 [即,#(values)]

所以情况正好相反。当规范说支持时,您只能假设它Field: value1, value2等于Field: value1+ ,即逗号分隔的值列表。Field: value2Field#(value)

于 2015-04-09T21:38:00.063 回答
0

通过阅读规范,我得出以下结论:支持多个(逗号分隔)值:

  • 接受
  • 接受字符集
  • 接受编码
  • 接受语言
  • 接受补丁
  • 接受范围
  • 允许
  • 缓存控制
  • 联系
  • 内容编码
  • 内容-语言
  • 预计
  • 如果匹配
  • 如果无匹配
  • 编译指示
  • 代理验证
  • TE
  • 预告片
  • 传输编码
  • 升级
  • 各不相同
  • 通过
  • 警告
  • WWW-认证
  • X-Forwarded-For

您可以使用它来创建可拆分标头的白名单。

于 2015-04-09T23:19:11.627 回答