Registrando um cabeçalho HTTP em logs de acesso nginx que contém um ponto (ponto)

1

Eu tenho um cabeçalho personalizado " AB.CD ". Eu quero registrar esse valor de cabeçalho em meus logs de acesso nginx.

Este é o formato de log que eu quero experimentar no nginx.conf:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" "$http_AB.CD" '

No entanto, o ponto (ponto) parece ser inaceitável. Eu tentei escapar também, mas sem uso. Ele registra os dados como ... "-" "-.CD"

Qual é a maneira correta de registrar um cabeçalho com um ponto?

    
por TJ- 16.06.2017 / 05:51

3 respostas

1

Embora o período seja de fato um caractere válido para um cabeçalho HTTP , parece que o nginx não consegue lidar com ele corretamente. Isso vai além de simplesmente registrar o valor em um arquivo.

Antes de tentar registrar este cabeçalho personalizado, verifique se o cabeçalho está realmente disponível para ser registrado! Nesse caso, parece que o nginx não reconhece isso como sendo um cabeçalho válido.

Tente definir um cabeçalho personalizado e executar este script PHP simples com o seguinte (exemplo de php.net ):

<?php
foreach (getallheaders() as $name => $value) {
    echo "$name: $value<br/>\n";
}

Isso exibirá uma lista legível de todos os cabeçalhos na solicitação.

Agora, usando essas ferramentas do desenvolvedor da web, tentei definir um cabeçalho HTTP personalizado com um período:

Cada uma dessas ferramentas se comportou da mesma maneira: cabeçalhos HTTP com nomes normais (como AB-CD ) funcionaram como esperado; Os cabeçalhos HTTP com nomes como AB.CD ou AB%CD não foram reconhecidos pelo nginx e não foram mostrados na saída do script acima.

O texto acima se aplica a nginx-1.10.3 , nginx-1.11.8 , nginx-1.12.0 e nginx-1.13.1 .

    
por 20.06.2017 / 06:00
0

Tente usar o parâmetro escape no seu formato de registro:

A partir da [documentação do nginx]: 1

The escape parameter (1.11.8) allows setting json or default
characters escaping in variables, by default, default escaping
is used.
    
por 16.06.2017 / 07:17
0
A documentação é muito boa, mas a principal fonte de verdade é o código-fonte e, potencialmente, pode até ser mais fácil encontrar o que você é dessa maneira. Ou não - YMMV.

A função ngx_http_log_compile_format() no link é o bit que analisa seu log_format diretiva.

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;

Para que o bit esteja claro o suficiente - o nome da variável na sua diretiva log_format pode conter apenas alfanumérico mais '_'.

Isso não é o fim da história, porque ainda há a questão de como um cabeçalho contendo um '.' é mapeado em um nome de variável.

link faz a análise em ngx_http_parse_header_line() . Há um pouco mais para ler do que eu realmente quero entrar. Parece que se o código atingir um '.' no nome do campo, nada é feito para o hash do nome do campo. r->invalid_header = 1; é definido, mas não return NGX_HTTP_PARSE_INVALID_HEADER; como em outros casos. (consulte as linhas de código 922-982).

Eu não me importo de continuar explorando via código o que r->invalid_header = 1; faz, e isso não parece necessário. log_format ... ${http_abcd} ... pode funcionar, e se isso não funcionar, então duvido que qualquer coisa funcione. Eu apenas tentaria, e se isso não funcionar, não assuma nada.

    
por 20.06.2017 / 15:04

Tags