如何防止 HAProxy 删除带下划线的 HTTP 标头

如何防止 HAProxy 删除带下划线的 HTTP 标头

我们有一个 API 后端服务器,它要求某些 HTTP 标头包含下划线。我知道这不是最佳做法,标头应该使用连字符,但我无法更改这一点。

我们使用 nginx 作为带有选项的代理服务器underscores_in_headers on。这导致 nginx 不会删除这些标头。

现在我们要切换到 HAProxy,并且像配置更改之前的 nginx 一样,它会删除带有下划线的标头。有没有办法防止 HAProxy 删除带有下划线的标头?

答案1

您是否实际测试过 HAProxy 是否会删除带有下划线的标头?

从源代码来看,似乎不是这样。在这个答案中,我将尝试解释:

  • 为什么 HTTP 中允许在标头中使用下划线
  • 为什么 Nginx 默认丢弃它们
  • 为什么我认为 HAProxy 不会这样做。

HTTP/1.1 与 Nginx

根据 HTTP/1.1 规范RFC 7230 3.2.6,标题字段中使用下划线 ( ) 并没有错_;它只是不常见。

字段值组件

大多数 HTTP 标头字段值使用通用语法组件(标记、带引号的字符串和注释)定义,这些组件由空格或特定分隔符分隔。分隔符从标记中不允许使用的 US-ASCII 可视字符集中选择(DQUOTE(),/:;<=>?@[\]{})。

token         = 1*tchar

tchar         = "!" / "#" / "$" / "%" / "&" / "'" / "*"
              / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
              / DIGIT / ALPHA
              ; any VCHAR, except delimiters

Nginx 陷阱和常见错误:丢失(消失)的 HTTP 标头解释了为什么它们仍然默认被悄悄删除:

如果您未明确设置underscores_in_headers on;,NGINX 将默默删除带下划线的 HTTP 标头(根据 HTTP 标准,这些标头完全有效)。这样做是为了防止在将标头映射到 CGI 变量时出现歧义,因为在此过程中,破折号和下划线都会映射到下划线。


HAProxy

很遗憾,HAProxy 没有这样的设置. 如果您underscore通过 HAProxy搜索配置手册,它只在以下上下文中被提及环境变量节点名称(例如 DNS 名称),代理名称ACL 名称. HTTP 请求章节中未提及。

如果 HAProxy 确实删除了带有下划线的标头,那么您将无法从配置中执行任何操作,并且必须坚持使用 Nginx 或修改 HAProxy 的源代码。

然而,我试图找到 HAProxy 丢弃标头的位置,但无法从proto_http.c的功能void capture_headers()和中找到这样的东西void http_msg_analyzer()

此外,proto_http.c按类型列出所有 ASCII 字符,并(),/:;<=>?@[\]{}列出为,HTTP_FLG_SEP而下划线则列为普通标记:

495 /* It is about twice as fast on recent architectures to lookup a byte in a
496  * table than to perform a boolean AND or OR between two tests. Refer to
497  * RFC2616/RFC5234/RFC7230 for those chars. A token is any ASCII char that is
498  * neither a separator nor a CTL char. An http ver_token is any ASCII which can
499  * be found in an HTTP version, which includes 'H', 'T', 'P', '/', '.' and any
500  * digit. Note: please do not overwrite values in assignment since gcc-2.95
501  * will not handle them correctly. It's worth noting that chars 128..255 are
502  * nothing, not even control chars.
503  */
504 const unsigned char http_char_classes[256] = {
505     [  0] = HTTP_FLG_CTL,

545     ['('] = HTTP_FLG_SEP,
546     [')'] = HTTP_FLG_SEP,
547     ['*'] = HTTP_FLG_TOK,
548     ['+'] = HTTP_FLG_TOK,
549     [','] = HTTP_FLG_SEP,
550     ['-'] = HTTP_FLG_TOK,
551     ['.'] = HTTP_FLG_TOK | HTTP_FLG_VER,

570     ['A'] = HTTP_FLG_TOK,
571     ['B'] = HTTP_FLG_TOK,
572     ['C'] = HTTP_FLG_TOK,

600     ['_'] = HTTP_FLG_TOK,

这里,只是像一样_正常的,和;它不应该引起任何特殊情况。HTTP_FLG_TOKABC

相关内容