1
0
Fork 0
mirror of https://github.com/puma/puma.git synced 2022-11-09 13:48:40 -05:00

ext/puma_http11: handle duplicate headers as per RFC for C ext

The parser stores headers in a Ruby hash table so that when a header
is found twice its value replaces the old one. As per RFC[1] this is
not correct, since duplicated headers should all be considered. In
particular, they are semantically equivalent to a single header with
comma separated values. In this case, we follow existing practice of
joining values with a comma and a single space character.

[1] See RFC2616 section 4.2:
    http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
This commit is contained in:
Alejandro Martinez Ruiz 2015-11-06 17:11:05 +01:00
parent 1cd87a600f
commit fdfd7b5b0f

View file

@ -176,14 +176,12 @@ static VALUE find_common_field_value(const char *field, size_t flen)
void http_field(puma_parser* hp, const char *field, size_t flen,
const char *value, size_t vlen)
{
VALUE v = Qnil;
VALUE f = Qnil;
VALUE v;
VALIDATE_MAX_LENGTH(flen, FIELD_NAME);
VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE);
v = rb_str_new(value, vlen);
f = find_common_field_value(field, flen);
if (f == Qnil) {
@ -201,7 +199,17 @@ void http_field(puma_parser* hp, const char *field, size_t flen,
f = rb_str_new(hp->buf, new_size);
}
rb_hash_aset(hp->request, f, v);
/* check for duplicate header */
v = rb_hash_aref(hp->request, f);
if (v == Qnil) {
v = rb_str_new(value, vlen);
rb_hash_aset(hp->request, f, v);
} else {
/* if duplicate header, normalize to comma-separated values */
rb_str_cat2(v, ", ");
rb_str_cat(v, value, vlen);
}
}
void request_method(puma_parser* hp, const char *at, size_t length)