Você já testou que o HAProxy elimina cabeçalhos com sublinhados?
Do código-fonte, parece que não. Nesta resposta vou tentar explicar:
- por que sublinhados em cabeçalhos são permitidos no HTTP
- por que o Nginx os elimina por padrão e
- porque eu acredito que o HAProxy não faria isso.
HTTP / 1.1 & Nginx
De acordo com a especificação HTTP / 1.1 em RFC 7230 3.2.6 , não há nada errado com sublinhados ( _
) nos campos de cabeçalho; é apenas incomum.
Field Value Components
Most HTTP header field values are defined using common syntax components (token, quoted-string, and comment) separated by whitespace or specific delimiting characters. Delimiters are chosen from the set of US-ASCII visual characters not allowed in a token (
DQUOTE
and(),/:;<=>?@[\]{}
).token = 1*tchar tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / "^" / "_" / "'" / "|" / "~" / DIGIT / ALPHA ; any VCHAR, except delimiters
Armadilhas do Nginx e erros comuns: Faltando (desaparecendo) Cabeçalhos HTTP explica por que eles ainda são descartados silenciosamente por padrão:
If you do not explicitly set
underscores_in_headers on;
, NGINX will silently drop HTTP headers with underscores (which are perfectly valid according to the HTTP standard). This is done in order to prevent ambiguities when mapping headers to CGI variables as both dashes and underscores are mapped to underscores during that process.
HAProxy
Infelizmente, o HAProxy não possui essa configuração . Se você pesquisar underscore
por meio do Manual de configuração do HAProxy, ele será mencionado apenas nos contextos < em> variáveis de ambiente , nomes de nós (como em nomes DNS), nomes de proxy e nomes de ACL . Não mencionado no capítulo de solicitações HTTP.
Se o HAProxy soltar os cabeçalhos com underscores, não há nada que você possa fazer na configuração e você teria que ficar com o Nginx ou modificar o código-fonte do HAProxy.
No entanto, tentei descobrir onde o HAProxy exibe os cabeçalhos e não consegui encontrar algo semelhante às funções proto_http.c
void capture_headers()
e void http_msg_analyzer()
.
Além disso, proto_http.c
lista todos os caracteres ASCII por tipo e (),/:;<=>?@[\]{}
estão listados como HTTP_FLG_SEP
, enquanto o sublinhado é listado como um token normal:
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,
Aqui, _
é apenas um HTTP_FLG_TOK
normal, assim como A
, B
e C
; não deve causar nada de especial.