Multiple message-header fields handling

I have found a “problem” with multiple message-header fields handling in
Nginx.

The HTTP 1.1 protocol (section 4.2) says that:

“”“Multiple message-header fields with the same field-name MAY be
present in a message if and only if the entire field-value for that
header field is defined as a comma-separated list [i.e., #(values)].”""

This can happen, as an example, with the Cookie header.

The “problem” is that Nginx does not combines these multiple headers:

“”“It MUST be possible to combine the multiple header fields into one
“field-name: field-value” pair, without changing the semantics of the
message, by appending each subsequent field-value to the first, each
separated by a comma. The order in which header fields with the same
field-name are received is therefore significant to the interpretation
of the combined field value, and thus a proxy MUST NOT change the order
of these field values when a message is forwarded.”""

Igor, do you plan to add this feature in a future version?

Thanks and regards Manlio P.

On Tue, Oct 02, 2007 at 10:02:38PM +0200, Manlio P. wrote:

Igor, do you plan to add this feature in a future version?

nginx does not join headers as Apache does.
However, all headers are passed to a proxied server/etc as is if they
are not overwritten.
As to the cookies nginx treats them specially and $http_cookie includes
all Cookie header fields.

On Wed, Oct 03, 2007 at 04:09:49PM +0200, Manlio P. wrote:

Ok.

However, all headers are passed to a proxied server/etc as is if they
are not overwritten.

The problem is that a WSGI application receives the headers in a Python
dictionary (an associative array).
This means that I MUST fold the headers.

All headers are available in r->headers_in.headers list.

As to the cookies nginx treats them specially and $http_cookie includes
all Cookie header fields.

Cookies are a mess.
Does nginx apply some for of preprocessing?

I do not understand the question.

Igor S. ha scritto:

On Tue, Oct 02, 2007 at 10:02:38PM +0200, Manlio P. wrote:

I have found a “problem” with multiple message-header fields handling in
Nginx.

[…]

Igor, do you plan to add this feature in a future version?

nginx does not join headers as Apache does.

Ok.

However, all headers are passed to a proxied server/etc as is if they
are not overwritten.

The problem is that a WSGI application receives the headers in a Python
dictionary (an associative array).
This means that I MUST fold the headers.

As to the cookies nginx treats them specially and $http_cookie includes
all Cookie header fields.

Cookies are a mess.
Does nginx apply some for of preprocessing?

Thanks and regards Manlio P.

On Wed, Oct 03, 2007 at 05:07:35PM +0200, Manlio P. wrote:

Igor, do you plan to add this feature in a future version?

A solution is to do:

This is not very efficient, if I have to do many strings concatenations.

Actually requests with multi line headers are seldom.

As to the cookies nginx treats them specially and $http_cookie includes
all Cookie header fields.

Cookies are a mess.
Does nginx apply some for of preprocessing?

I do not understand the question.

Errata to RFC 2965, HTTP State Management

I still do not understand.
$http_cookie joins cookies using "; " without any processing, see
ngx_http_variable_headers().

Igor S. ha scritto:

nginx does not join headers as Apache does.
Ok.

However, all headers are passed to a proxied server/etc as is if they
are not overwritten.
The problem is that a WSGI application receives the headers in a Python
dictionary (an associative array).
This means that I MUST fold the headers.

All headers are available in r->headers_in.headers list.

In fact I iterate over this list doing (pseudo Python code):

environ = {}
for key, value in r->headers_in.headers list:
environ[key] = value

The problem is that I only save the last multi line header.

A solution is to do:

environ = {}
for key, value in r->headers_in.headers list:
# check if this is a multiline header
old = environ.get(key, None)
if old is None:
environ[key] = value
else:
# fold the header value
environ[key] = old + ", " + value

This is not very efficient, if I have to do many strings concatenations.

As to the cookies nginx treats them specially and $http_cookie includes
all Cookie header fields.

Cookies are a mess.
Does nginx apply some for of preprocessing?

I do not understand the question.

http://kristol.org/cookie/errata.html

Thanks and regards Manlio P.

Igor S. ha scritto:

[…]

Actually requests with multi line headers are seldom.

Thanks, this is a good news.

ngx_http_variable_headers().

Sorry.
What I meant is that, in HTTP 1.1, only headers with values separed by
“,” can be splitted on multiple lines:

“”“Multiple message-header fields with the same field-name MAY be
present in a message if and only if the entire field-value for that
header field is defined as a comma-separated list [i.e., #(values)]”""

However the Cookie header uses “;” as the separator.

P.S.
reading the RFC 2965, I see a:
cookie = “Cookie:” cookie-version 1*((";" | “,”) cookie-value)

so it seems that both “;” and “,” can be used…

Manlio P.