У нас есть внутренний сервер API, которому требуются определенные заголовки HTTP, содержащие символы подчеркивания. Я знаю, что это не лучшая практика и в заголовках следует использовать дефисы, но я не могу это изменить.
Мы использовали nginx в качестве прокси-сервера с опцией underscores_in_headers on
. Это заставляет nginx не отбрасывать эти заголовки.
Теперь мы хотим переключиться на HAProxy, и как nginx перед изменением конфигурации он отбрасывает заголовки с подчеркиванием. Есть ли способ запретить HAProxy отбрасывать заголовки с подчеркиванием?
Вы действительно проверяли, что HAProxy отбрасывает заголовки с подчеркиванием?
Судя по исходному коду, это не так. В этом ответе я постараюсь объяснить:
Согласно спецификации 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 не имеет такой настройки. Если вы ищете 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
; это не должно вызывать ничего особенного.