【问题标题】:How to split header values?如何拆分标题值?
【发布时间】:2015-06-15 10:57:13
【问题描述】:

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

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

HTTP RFC2616 说:

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

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

我已经找到了一个导致问题的示例。例如,我的 User-Agent 字符串是

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36

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

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

【问题讨论】:

    标签: http http-headers rfc2616


    【解决方案1】:

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

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

    我遇到了这个特定的问题,wrote a parsertested it on edge cases。不仅是parsing the header non-trivial,对其进行解释并给出correct result is also non-trivial

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

    【讨论】:

      【解决方案2】:

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

      • 接受
      • 接受字符集
      • 接受编码
      • 接受语言
      • 接受补丁
      • 接受范围
      • 允许
      • 缓存控制
      • 连接
      • 内容编码
      • 内容-语言
      • 期待
      • 如果匹配
      • 如果没有匹配
      • 编译指示
      • 代理验证
      • TE
      • 预告片
      • 传输编码
      • 升级
      • 变化
      • 通过
      • 警告
      • WWW-认证
      • X-Forwarded-For

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

      【讨论】:

      • @CodeCaster 实际上我故意将Set-Cookie 关闭。来自 Wikipedia 的示例显示 sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT - 日期中间有一个逗号。我不确定有没有办法在一条线上放置多个 Set-Cookie,是吗?
      • Accept: foo/bar;p="A,B" 怎么样?这是有效的,但以逗号分隔不会产生预期的结果。最好使用基于 RFC 规范的特定解析器,例如github.com/ioquatix/http-accept
      【解决方案3】:

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

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

      【讨论】:

      • 嗯,这就是我想说的“我不确定反过来是否正确”。有没有什么地方可以找到支持逗号分隔的标题列表,以便我至少可以创建一个黑名单或白名单?
      • @Mark 我一直在努力寻找这些,但 RFC2616RFC7230RFC7231 并不是很详尽。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多