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:
parent
1cd87a600f
commit
fdfd7b5b0f
1 changed files with 12 additions and 4 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue