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

Регистрация HTTP-заголовка в журналах доступа nginx, содержащего точку (период)

У меня есть собственный заголовок "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} ... может сработать, а если это не сработает, то я сомневаюсь, что что-нибудь сработает. Я бы просто попробовал, и если это не сработает, полагаю, ничего не выйдет.