Назад | Перейти на главную страницу

Как запретить HAProxy отбрасывать заголовки HTTP с подчеркиванием

У нас есть внутренний сервер API, которому требуются определенные заголовки HTTP, содержащие символы подчеркивания. Я знаю, что это не лучшая практика и в заголовках следует использовать дефисы, но я не могу это изменить.

Мы использовали nginx в качестве прокси-сервера с опцией underscores_in_headers on. Это заставляет nginx не отбрасывать эти заголовки.

Теперь мы хотим переключиться на HAProxy, и как nginx перед изменением конфигурации он отбрасывает заголовки с подчеркиванием. Есть ли способ запретить HAProxy отбрасывать заголовки с подчеркиванием?

Вы действительно проверяли, что 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_TOK как A, B и C; это не должно вызывать ничего особенного.