diff options
-rw-r--r-- | ext/unicorn_http/unicorn_http.rl | 13 | ||||
-rw-r--r-- | test/unit/test_http_parser_ng.rb | 11 |
2 files changed, 21 insertions, 3 deletions
diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl index edf39ae..e985e0e 100644 --- a/ext/unicorn_http/unicorn_http.rl +++ b/ext/unicorn_http/unicorn_http.rl @@ -57,6 +57,7 @@ static void write_value(VALUE req, struct http_parser *hp, { VALUE f = find_common_field(PTR_TO(start.field), hp->s.field_len); VALUE v; + VALUE e; VALIDATE_MAX_LENGTH(LEN(mark, p), FIELD_VALUE); v = STR_NEW(mark, p); @@ -76,10 +77,16 @@ static void write_value(VALUE req, struct http_parser *hp, } else if (f == g_http_trailer) { hp->flags |= UH_FL_HASTRAILER; invalid_if_trailer(hp->flags); - } else if (f == g_http_host && rb_hash_aref(req, f) != Qnil) { - return; /* full URLs in REQUEST_URI take precedence */ } - rb_hash_aset(req, f, v); + + e = rb_hash_aref(req, f); + if (e == Qnil) { + rb_hash_aset(req, f, v); + } else if (f != g_http_host) { + /* full URLs in REQUEST_URI take precedence for the Host: header */ + rb_str_buf_cat(e, ",", 1); + rb_str_buf_append(e, v); + } } /** Machine **/ diff --git a/test/unit/test_http_parser_ng.rb b/test/unit/test_http_parser_ng.rb index 6fc0bda..8c453dd 100644 --- a/test/unit/test_http_parser_ng.rb +++ b/test/unit/test_http_parser_ng.rb @@ -252,4 +252,15 @@ class HttpParserNgTest < Test::Unit::TestCase assert_raise(HttpParserError) { @parser.trailers(req, str) } end + def test_repeat_headers + str = "PUT / HTTP/1.1\r\n" \ + "Trailer: Content-MD5\r\n" \ + "Trailer: Content-SHA1\r\n" \ + "transfer-Encoding: chunked\r\n\r\n" \ + "1\r\na\r\n2\r\n..\r\n0\r\n" + req = {} + assert_equal req, @parser.headers(req, str) + assert_equal 'Content-MD5,Content-SHA1', req['HTTP_TRAILER'] + end + end |