Opened 7 years ago

Closed 3 years ago

Last modified 2 years ago

#1316 closed defect (fixed)

$http_ variables only contain the first field-value

Reported by: vfaronov@… Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.13.x
Keywords: Cc:
uname -a: Linux pergamon 4.4.0-83-generic #106-Ubuntu SMP Mon Jun 26 17:54:43 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.13.3
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
configure arguments: --prefix=/home/vasiliy/tmp/nginx-1.13.3/prefix --with-debug

Description

The value of the $http_X variable is the field-value of the first request header field named X. Further field-values, if any, are not included in the variable.

For example, given a request like:

GET / HTTP/1.1
Host: example.com
Forwarded: for=123.45.67.89
Forwarded: for=234.56.78.90

the value of $http_forwarded is for=123.45.67.89.

A more useful value would be for=123.45.67.89,for=234.56.78.90 (per RFC 7230 § 3.2.2).

Failing that, at least the current behavior should be documented.

Change History (7)

comment:1 by Maxim Dounin, 6 years ago

See also #1762.

comment:2 by Maxim Dounin <mdounin@…>, 3 years ago

In 8023:08b3ea81ff5f/nginx:

Combining unknown headers during variables lookup (ticket #1316).

Previously, $http_*, $sent_http_*, $sent_trailer_*, $upstream_http_*,
and $upstream_trailer_* variables returned only the first header (with
a few specially handled exceptions: $http_cookie, $http_x_forwarded_for,
$sent_http_cache_control, $sent_http_link).

With this change, all headers are returned, combined together. For
example, $http_foo variable will be "a, b" if there are "Foo: a" and
"Foo: b" headers in the request.

Note that $upstream_http_set_cookie will also return all "Set-Cookie"
headers (ticket #1843), though this might not be what one want, since
the "Set-Cookie" header does not follow the list syntax (see RFC 7230,
section 3.2.2).

comment:3 by Maxim Dounin, 3 years ago

Resolution: fixed
Status: newclosed

Fixed, thanks to all involved.

comment:4 by thomas.d.spear@…, 2 years ago

Hi, I found this ticket linked from https://www.nginx.com/resources/wiki/start/topics/examples/forwarded/ and wanted to ask since it is fixed now if the warning could be taken down or at least amended so as to clarify that this has now been fixed as of version x.yy, which ever version is the earliest with this fix?

Warm regards,

Thomas Spear

comment:5 by Maxim Dounin, 2 years ago

Wiki articles are not maintained by nginx developers, but rather by users, if at all. The warning you are referring to is certainly no longer relevant starting with nginx 1.23.0 and in newer versions. On the other hand, the whole article looks, at least, questionable. Either way, feel free to update it if you think it worth the effort.

in reply to:  5 comment:6 by nyurik@…, 2 years ago

Replying to Maxim Dounin:

Wiki articles are not maintained by nginx developers, but rather by users, if at all. The warning you are referring to is certainly no longer relevant starting with nginx 1.23.0 and in newer versions. On the other hand, the whole article looks, at least, questionable. Either way, feel free to update it if you think it worth the effort.

Maxim, thanks for fixing this! Do you know if there are any plans to provider easier path to use the Forwarded header? That wiki page approach with an unreadable regex is, indeed, a horrid hack. In your opinion, should Nginx provide a standard way to handle that? Where would it be documented or requested? (Trac is a bit harder to use than github, but I couldn't find anything relevant)

comment:7 by Maxim Dounin, 2 years ago

Maxim, thanks for fixing this! Do you know if there are any plans to provider easier path to use the Forwarded header? That wiki page approach with an unreadable regex is, indeed, a horrid hack. In your opinion, should Nginx provide a standard way to handle that? Where would it be documented or requested? (Trac is a bit harder to use than github, but I couldn't find anything relevant)

I don't think it needs any special support. Just adding a header with appropriate address is trivial, and can be easily done with existing mechanisms. But attempts to validate the existing header, as the wiki article tries to do, look incorrect and misleading. And these attempts reveal the issue with the Forwarded header as defined by RFC 7239: first elements of the header are not expected to be correct or trusted, yet complex syntax makes it trivial to parse the header incorrectly. In general, I would recommend to use the X-Forwarded-For header instead, or even simpler one, X-Real-IP.

Note: See TracTickets for help on using tickets.