Steins;Lab

  • 项目
  • 折腾
  • 笔记
  • 图册
  • 杂谈
  • 文章索引 - 博主自荐博文
  • 关于/留言
Steins;Lab
某团的自留研究所
  1. 首页
  2. 学习笔记
  3. 正文

HTTP Header Name 大小写敏感问题

2022年12月7日 7162点热度 2人点赞 0条评论

平常我们在做应用层开发时,很少会注意到 HTTP 请求的大小写敏感问题。笔者在围观一个 HTTP 服务端 Header 的解析程序时,发现了一个微妙的 bug。这篇笔记是针对该问题的一个有趣的探究。

比如遇到下面的请求,你能直接说出正在使用框架的默认行为吗?

    Host: example.com
    accept-encoding: gzip, deflate
    Accept-Language: en-us
    fOO: Bar
    foo: two

1 问题引入

range 请求是只请求一部分 HTTP 文件的请求。在收取大长度媒体文件的场景非常常见。
在线上观测到了部分此类超出预期的请求,导致返回异常。

GET /z4d4kWk.mp4 HTTP/1.1
Host: example.
Range: bytes=0-1023
range: bytes=0-1

很明显,服务端应当正确处理这种 Header 重复的现象。

2 HTTP 标准?

根据[1]讨论串和 RFC 整理。
之所以打一个问号,是因为浏览器和前端的使用习惯[1]、具体实现[5],我们可能偶尔在实际中遇到该类疑难杂症。

HTTP/1.1

在 RFC 7230 (Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing) 中,规定了 Header Name 是大小写不敏感 case-insensitive 的。

   Each header field consists of a case-insensitive field name followed
   by a colon (":"), optional leading whitespace, the field value, and
   optional trailing whitespace.

HTTP/2

在 RFC 7540 中,规定了同样是大小写不敏感的。

Just as in HTTP/1.x, header field names are strings of ASCII characters that are compared in a case-insensitive fashion.

但值得指出的是,针对应用层的使用,标准如此规定。在 HTTP/2 协议内部,编码前需要统一转化为小写。

However,header field names MUST be converted to lowercase prior to their encoding in HTTP/2. 
A request or response containing uppercase header field names MUST be treated as malformed.

之所以这么处理,推测是送进 HPACK 这种利用字典的 Header 压缩算法前,消除大小写的分歧。

3 Go HTTP 包的处理

Go 的 net/http 标准库使用广泛。注意,其默认使用 CanonicalHeaderKey 模式处理接收和请求的 Header Name。即令第一个字母和横杠后的字母为大写,剩下字母为小写。
其实在官方文档中已经明确示例了处理模式[6]。

接收的 Header

    // If a server received a request with header lines,
    //
    //  Host: example.com
    //  accept-encoding: gzip, deflate
    //  Accept-Language: en-us
    //  fOO: Bar
    //  foo: two
    //
    // then
    //
    //  Header = map[string][]string{
    //      "Accept-Encoding": {"gzip, deflate"},
    //      "Accept-Language": {"en-us"},
    //      "Foo": {"Bar", "two"},
    //  }
    //
    // For incoming requests, the Host header is promoted to the
    // Request.Host field and removed from the Header map.
    //
    // HTTP defines that header names are case-insensitive. The
    // request parser implements this by using CanonicalHeaderKey,
    // making the first character and any characters following a
    // hyphen uppercase and the rest lowercase.

发送的 Header (Header的增改)

涉及 Add Get Set方法,根据文档描述和查看源码,都是默认通过 textproto.CanonicalMIMEHeaderKey. 进行了处理。

作为开发者需要注意

CanonicalHeaderKey 处理是默认的。因此,在使用 net/http 处理 7 层转发时,要注意这个特性。

笔者之所以没有在测试环境的镜像流量中发现开篇的疑难问题,就是因为开发的 7 层镜像转发程序工具默认处理了这种接收请求 Header。

4 结语

虽然标准规定了 Header Name 是大小写不敏感的。但或由于浏览器和前端的使用习惯[1],或由于具体实现[5],我们排查某些疑难杂症的时候也可以考虑该问题。

比如案例 [5] 中,上游 api 并没有按照标准处理大小写,导致业务异常。

如果读者能对 CanonicalHeaderKey 有印象,本篇笔记将非常荣幸。

Extra

讨论串[1]也有回答提示,虽然 header name 是大小写无关的,但 HTTP 方法是大小写敏感的。所以我们在使用 curl 时,基本都会强制输入方法为大写。如 POST, GET 等等。

# RFC 7230
## 3.1.1.  Request Line
   ...
   The method token indicates the request method to be performed on the
   target resource.  The request method is case-sensitive.

参考资料

[1] Are HTTP headers case-sensitive? - StackOverflow
[2] RFC 7230
[3] RFC 7540
[4] HPACK: the silent killer (feature) of HTTP/2 - Cloudflare Blog
[5] AWS API Gateway Custom Authorization header case sensitivity
[6] https://pkg.go.dev/net/http#Request.Header

相关

标签: 暂无
最后更新:2024年3月19日

SPtuan

SPtuan 是一名普通的工程师,最大的愿望是度过平静的时光。 当前从事网络/CDN/对象存储研发。

点赞
< 上一篇
下一篇 >
0 0 votes
文章评分
Subscribe
Login
提醒
guest

guest

0 评论
最新
最旧 得票最多
Inline Feedbacks
View all comments

SPtuan

SPtuan 是一名普通的工程师,最大的愿望是度过平静的时光。
当前从事网络/CDN/对象存储研发。

  • 1 问题引入
  • 2 HTTP 标准?
    • HTTP/1.1
    • HTTP/2
  • 3 Go HTTP 包的处理
    • 接收的 Header
    • 发送的 Header (Header的增改)
    • 作为开发者需要注意
  • 4 结语
  • Extra
  • 参考资料
分类
  • Uncategorized
  • 图册
  • 学习笔记
  • 库
  • 折腾
  • 杂谈
  • 瞎**扯
  • 碎碎念
  • 项目跟踪
最近评论
SPtuan 发布于 2 个月前(03月22日) 书签: 关于 disk-io 的经验, 异步/同步 io 系统设计的经验 https://you...
SPtuan 发布于 2 个月前(03月21日) 如果公司不是对外提供这些服务的,这种岗位都是 infra 部门,平均年龄确实会大一些。尤其构建和维护...
HUA 发布于 2 个月前(03月19日) 想请问博主对于国内CDN行业,以及CDN调度、DNS托管类服务相关岗位的看法,以及是否还推荐校招新人...
SPtuan 发布于 3 个月前(02月03日) 2025 注: 长辈对于只身去深圳的担忧,更多地来自于 80s/90s 治安情况。近几年了解了严打...
SPtuan 发布于 4 个月前(01月16日) 哈哈,100就100吧,新年快乐!
热门主题 & 页面
  • [实验]VPS搭建ss服务中转实现纯ipv6访问网络-校园网免流量
  • 使用 WSL2 + X11 转发 - 在 Windows10 中打造 GNU/Linux 学习生产环境
  • HTTP Header Name 大小写敏感问题
  • iowait 到底是什么?
  • 全球互联网拓扑探索 (1) : 互联网是如何工作的
归档
  • 2025 年 5 月
  • 2025 年 3 月
  • 2024 年 12 月
  • 2024 年 9 月
  • 2024 年 8 月
  • 2024 年 5 月
  • 2024 年 3 月
  • 2024 年 2 月
  • 2023 年 12 月
  • 2023 年 11 月
  • 2023 年 9 月
  • 2023 年 8 月
  • 2023 年 4 月
  • 2023 年 1 月
  • 2022 年 12 月
  • 2022 年 10 月
  • 2022 年 9 月
  • 2022 年 7 月
  • 2022 年 6 月
  • 2022 年 2 月
  • 2021 年 12 月
  • 2021 年 11 月
  • 2021 年 2 月
  • 2021 年 1 月
  • 2020 年 9 月
  • 2020 年 4 月
  • 2020 年 3 月
  • 2020 年 1 月
  • 2019 年 8 月
  • 2019 年 7 月
  • 2019 年 5 月
  • 2019 年 4 月
  • 2019 年 3 月
  • 2019 年 2 月
  • 2018 年 12 月
  • 2018 年 10 月
  • 2018 年 9 月
  • 2018 年 8 月
  • 2018 年 5 月
  • 2018 年 2 月
  • 2018 年 1 月
  • 2017 年 11 月
  • 2017 年 9 月
  • 2017 年 7 月
  • 2017 年 6 月
  • 2017 年 5 月
  • 2017 年 4 月
  • 2017 年 3 月
  • 2017 年 2 月
  • 2017 年 1 月
  • 2016 年 12 月
  • 2016 年 11 月
  • 2016 年 10 月
  • 2016 年 9 月
  • 2016 年 8 月
  • 2016 年 7 月
  • 2016 年 6 月
  • 2016 年 5 月
  • 2016 年 4 月
  • 2016 年 3 月
  • 2016 年 2 月
  • 2016 年 1 月
  • 2015 年 12 月
  • 2015 年 11 月
  • 2015 年 9 月

友情链接:

Blessing Studio hahaschool 绘枫和畅 魔法少女Fandy monsterx Clarke的博客 Luminous’ Home Shintaku's Blog
蓝黑的博客 haruhi.club Yida的博客 Bo2SS 涛叔 TangBao 同和君Hocassian

Steins;Lab 团子神社 zdfmc.net

steinslab.io built with ❤. Thanks for all 2015-2025.

Theme Kratos Made By Seaton Jiang

wpDiscuz