Logging an HTTP header in nginx access logs that contains a dot (period)
Although the period is indeed a valid character for an HTTP header, it appears that nginx is not able to handle it correctly. This goes beyond simply logging the value to a file.
Before trying to log this custom header, make sure the header is actually available to be logged! In this case, it appears that nginx does not recognize this as being a valid header.
Try setting a custom header and running this simple PHP script with the following (example from php.net):
<?php
foreach (getallheaders() as $name => $value) {
echo "$name: $value<br/>\n";
}
This will display a readable list of all the headers in the request.
Now, using these web developer tools, I attempted to set a custom HTTP header with a period:
- Modify Header Value (HTTP Headers) 0.1.3 (Firefox)
- Modify Headers 0.7.1.1.1-signed.1-signed (Firefox)
- HTTP Header Mangler 1.1.2 (Firefox)
- Advanced REST client 9.14.64.305-stable (Chrome)
Each of these tools behaved the same way: HTTP headers with normal names (like AB-CD
) worked as expected; HTTP headers with names like AB.CD
or AB%CD
were not recognized by nginx, and were not shown in the output of the above script.
The above applies to nginx-1.10.3
, nginx-1.11.8
, nginx-1.12.0
, and nginx-1.13.1
.
Related videos on Youtube
Comments
-
TJ- almost 2 years
I have a custom header "
AB.CD
". I want to log this header value in my nginx access logs.This is the log format that I want to try in nginx.conf :
log_format main '$remote_addr - $remote_user [$time_local] "$request" "$http_AB.CD" '
However the dot (period) seems to be unacceptable. I tried escaping it also, but of no use. It logs the data as
... "-" "-.CD"
What is the right way of logging a header that has a dot in it?
-
Admin about 7 yearsI'm pretty sure a "dot" is a valid character in header names, but none of the standard values have them. I think your life will be easier if you use a different character.
-
Admin about 7 yearsI'm not sure, but try
${http_ab.cd}
-
Admin about 7 years@Tim I agree. But until I get to change it.
-
Admin about 7 years@AlexeyTen: Thanks, but it didn't work.
-
-
TJ- about 7 yearsIt didn't work. i.e. I was able to translate my logs to a json format, but it continues to use the period as a concatenation operator and does not escape it.
-
TJ- about 7 yearsAppreciate your effort investigating the thing. However, this isn't an answer to the query - and yes, of course, the header is available to be logged!
-
JonathanDavidArndt almost 7 yearsOK. So, the header is available to be logged. Does that mean it shows up in the output of
getallheaders()
? How does the header get set in your environment? Is it done by a third-party app, a script, or some plugin? -
JonathanDavidArndt almost 7 yearsThe source does not matter for your end result (logging). But this is an interesting problem, and I am currently unable to investigate further, because I am unable to even set headers like this from any source. It would help me further diagnose the problem.
-
TJ- almost 7 yearsUse a Rest Client chrome plugin. You can send any header you'd want to.
-
JonathanDavidArndt almost 7 yearsI've updated the answer with new information: even with the Rest Client in Chrome, headers with names like
AB.CD
orAB%CD
are still not sent correctly (at least, they are not available in the PHP script throughgetallheaders()
). Every other custom header with normal characters works just fine.