1 votes

Enregistrement dans les journaux d'accès de nginx d'un en-tête HTTP contenant un point (period)

J'ai un en-tête personnalisé " AB.CD ". Je veux enregistrer cette valeur d'en-tête dans mes journaux d'accès nginx.

C'est le format de journal que je veux essayer dans nginx.conf :

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

Cependant, le point semble être inacceptable. J'ai également essayé de l'échapper, mais en vain. Il enregistre les données comme ... "-" "-.CD"

Quelle est la bonne façon d'enregistrer un en-tête qui contient un point ?

2voto

JonathanDavidArndt Points 1414

Bien que la période soit effectivement caractère valide pour un en-tête HTTP il semble que nginx ne soit pas en mesure de le gérer correctement. Cela va au-delà du simple enregistrement de la valeur dans un fichier.

Avant d'essayer d'enregistrer cet en-tête personnalisé, assurez-vous que l'en-tête est réellement disponible pour être enregistré ! Dans ce cas, il apparaît que nginx fait no reconnaît ceci comme étant un en-tête valide.

Essayez de définir un en-tête personnalisé et d'exécuter ce simple script PHP avec ce qui suit (exemple de php.net ) :

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

Cela affichera une liste lisible de tous les en-têtes de la requête.

Maintenant, en utilisant ces outils de développement web, j'ai essayé de définir un en-tête HTTP personnalisé avec un point :

Chacun de ces outils se comportait de la même manière : Les en-têtes HTTP avec des noms normaux (comme AB-CD ) a fonctionné comme prévu ; les en-têtes HTTP avec des noms comme AB.CD ou AB%CD n'étaient pas reconnus par nginx, et n'apparaissaient pas dans la sortie du script ci-dessus.

Ce qui précède s'applique à nginx-1.10.3 , nginx-1.11.8 , nginx-1.12.0 y nginx-1.13.1 .

0voto

quadruplebucky Points 4991

Essayez d'utiliser le escape dans le format de votre journal :

D'après la [documentation nginx] : 1

The escape parameter (1.11.8) allows setting json or default
characters escaping in variables, by default, default escaping
is used.

0voto

mc0e Points 5736

La documentation est une bonne chose, mais la source ultime de vérité est le code source, et il peut même être plus facile de trouver ce que vous cherchez de cette façon. Ou pas - YMMV.

En ngx_http_log_compile_format() fonction dans http://lxr.nginx.org/source/src/http/modules/ngx_http_log_module.c est la partie qui analyse votre log_format directive.

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;

Le nom de la variable dans la directive log_format ne peut contenir que des caractères alphanumériques suivis de '_'.

Mais ce n'est pas tout, car il reste à savoir comment un en-tête contenant un "." est converti en nom de variable.

http://lxr.nginx.org/source/src/http/ngx_http_parse.c effectue l'analyse syntaxique dans ngx_http_parse_header_line() . Il y a un peu plus à lire que ce que je veux vraiment dire. Il semble que si le code trouve un '.' dans le nom du champ, rien n'est fait au hash du nom du champ. r->invalid_header = 1; se met en place, mais ce n'est pas return NGX_HTTP_PARSE_INVALID_HEADER; comme dans d'autres cas. (voir lignes de code 922-982).

Je n'ai pas envie de continuer à explorer le code pour savoir ce que r->invalid_header = 1; le fait, et cela ne semble pas nécessaire. log_format ... ${http_abcd} ... pourrait marcher, et si ça ne marche pas, alors je doute que quelque chose marche. J'essaierais juste, et si ça ne marche pas, je suppose que rien ne marchera.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X