У меня есть собственный заголовок "AB.CD
". Я хочу зарегистрировать это значение заголовка в журналах доступа nginx.
Это формат журнала, который я хочу попробовать в nginx.conf:
log_format main '$remote_addr - $remote_user [$time_local] "$request" "$http_AB.CD" '
Однако точка (точка) кажется неприемлемой. Я тоже пытался сбежать, но без толку. Он регистрирует данные как ... "-" "-.CD"
Как правильно записать заголовок, в котором есть точка?
Хотя период действительно допустимый символ для заголовка HTTP, похоже, что nginx не может правильно с этим справиться. Это выходит за рамки простой записи значения в файл.
Прежде чем пытаться регистрировать этот настраиваемый заголовок, убедитесь, что заголовок действительно доступен для записи! В этом случае похоже, что nginx делает не признать это действительным заголовком.
Попробуйте установить собственный заголовок и запустить этот простой скрипт PHP со следующим (пример из php.net):
<?php
foreach (getallheaders() as $name => $value) {
echo "$name: $value<br/>\n";
}
Это отобразит читаемый список всех заголовков в запросе.
Теперь, используя эти инструменты веб-разработчика, я попытался установить собственный HTTP-заголовок с точкой:
Каждый из этих инструментов вел себя одинаково: заголовки HTTP с обычными именами (например, AB-CD
) заработало как положено; Заголовки HTTP с именами вроде AB.CD
или AB%CD
не распознавались nginx и не отображались в выводе приведенного выше скрипта.
Вышесказанное относится к nginx-1.10.3
, nginx-1.11.8
, nginx-1.12.0
, и nginx-1.13.1
.
Попробуйте использовать escape
параметр в формате вашего журнала:
Из [документации nginx]:1
The escape parameter (1.11.8) allows setting json or default
characters escaping in variables, by default, default escaping
is used.
Документация хороша и хороша, но окончательный источник истины - это исходный код, и потенциально может быть даже легче найти то, что вы есть, после этого. Или нет - YMMV.
В ngx_http_log_compile_format()
функционировать в http://lxr.nginx.org/source/src/http/modules/ngx_http_log_module.c это бит, который анализирует ваш log_format
директива.
1603 if ((ch >= 'A' && ch <= 'Z')
1604 || (ch >= 'a' && ch <= 'z')
1605 || (ch >= '0' && ch <= '9')
1606 || ch == '_')
1607 {
1608 continue;
1609 }
1610
1611 break;
Так что этот бит достаточно ясен - имя переменной в вашей директиве log_format может содержать только буквенно-цифровые символы плюс '_'.
Однако это еще не конец истории, потому что все еще остается вопрос, как заголовок содержит '.' отображается в имя переменной.
http://lxr.nginx.org/source/src/http/ngx_http_parse.c анализирует ли ngx_http_parse_header_line()
. Есть еще кое-что, что я могу прочитать, чем я действительно хочу вдаваться. Похоже, что если код попадает в '.' в имени поля ничего не происходит с хешем имени поля. r->invalid_header = 1;
устанавливается, но это не так return NGX_HTTP_PARSE_INVALID_HEADER;
как и в некоторых других случаях. (см. строки кода 922-982).
Я не собираюсь переходить к изучению кода, что r->invalid_header = 1;
делает, и это не кажется необходимым. log_format ... ${http_abcd} ...
может сработать, а если это не сработает, то я сомневаюсь, что что-нибудь сработает. Я бы просто попробовал, и если это не сработает, полагаю, ничего не выйдет.