From bd0599c4ac91d95cae1f34df3ae99c92f3225391 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 2 Sep 2009 23:49:05 -0700 Subject: http: SERVER_PROTOCOL matches HTTP_VERSION And it'll default to HTTP/0.9 if HTTP_VERSION is not specified (as version-less HTTP requests imply HTTP/0.9. --- ext/unicorn_http/global_variables.h | 4 ++++ ext/unicorn_http/unicorn_http.rl | 15 +++++++++++---- test/unit/test_http_parser.rb | 6 +++--- test/unit/test_http_parser_ng.rb | 2 +- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/ext/unicorn_http/global_variables.h b/ext/unicorn_http/global_variables.h index 14aa77a..e593cf6 100644 --- a/ext/unicorn_http/global_variables.h +++ b/ext/unicorn_http/global_variables.h @@ -25,6 +25,8 @@ static VALUE g_port_80; static VALUE g_port_443; static VALUE g_localhost; static VALUE g_http; +static VALUE g_http_09; +static VALUE g_http_10; static VALUE g_http_11; static VALUE g_GET; static VALUE g_HEAD; @@ -78,6 +80,8 @@ void init_globals(void) DEF_GLOBAL(localhost, "localhost"); DEF_GLOBAL(http, "http"); DEF_GLOBAL(http_11, "HTTP/1.1"); + DEF_GLOBAL(http_10, "HTTP/1.0"); + DEF_GLOBAL(http_09, "HTTP/0.9"); DEF_GLOBAL(GET, "GET"); DEF_GLOBAL(HEAD, "HEAD"); } diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl index 8cdcbe2..224b95a 100644 --- a/ext/unicorn_http/unicorn_http.rl +++ b/ext/unicorn_http/unicorn_http.rl @@ -20,6 +20,7 @@ #define UH_FL_INCHUNK 0x20 #define UH_FL_KAMETHOD 0x40 #define UH_FL_KAVERSION 0x80 +#define UH_FL_HASHEADER 0x100 #define UH_FL_KEEPALIVE (UH_FL_KAMETHOD | UH_FL_KAVERSION) @@ -43,7 +44,7 @@ struct http_parser { } len; }; -static void finalize_header(VALUE req); +static void finalize_header(struct http_parser *hp, VALUE req); #define REMAINING (unsigned long)(pe - p) #define LEN(AT, FPC) (FPC - buffer - hp->AT) @@ -73,12 +74,17 @@ http_version(struct http_parser *hp, VALUE req, const char *ptr, size_t len) { VALUE v; + hp->flags |= UH_FL_HASHEADER; + if (CONST_MEM_EQ("HTTP/1.1", ptr, len)) { hp->flags |= UH_FL_KAVERSION; v = g_http_11; + } else if (CONST_MEM_EQ("HTTP/1.0", ptr, len)) { + v = g_http_10; } else { v = rb_str_new(ptr, len); } + rb_hash_aset(req, g_server_protocol, v); rb_hash_aset(req, g_http_version, v); } @@ -223,7 +229,7 @@ static void write_value(VALUE req, struct http_parser *hp, rb_raise(eHttpParserError, "invalid chunk size"); } action header_done { - finalize_header(req); + finalize_header(hp, req); cs = http_parser_first_final; if (hp->flags & UH_FL_HASBODY) { @@ -328,7 +334,7 @@ static struct http_parser *data_get(VALUE self) return hp; } -static void finalize_header(VALUE req) +static void finalize_header(struct http_parser *hp, VALUE req) { VALUE temp = rb_hash_aref(req, g_rack_url_scheme); VALUE server_name = g_localhost; @@ -362,7 +368,8 @@ static void finalize_header(VALUE req) } rb_hash_aset(req, g_server_name, server_name); rb_hash_aset(req, g_server_port, server_port); - rb_hash_aset(req, g_server_protocol, g_http_11); + if (!(hp->flags & UH_FL_HASHEADER)) + rb_hash_aset(req, g_server_protocol, g_http_09); /* rack requires QUERY_STRING */ if (rb_hash_aref(req, g_query_string) == Qnil) diff --git a/test/unit/test_http_parser.rb b/test/unit/test_http_parser.rb index 5430614..5ba0239 100644 --- a/test/unit/test_http_parser.rb +++ b/test/unit/test_http_parser.rb @@ -260,7 +260,7 @@ class HttpParserTest < Test::Unit::TestCase assert_equal 'HTTP/1.0', req['HTTP_VERSION'] assert_nil parser.headers(req, http << "\r") assert_equal req, parser.headers(req, http << "\n") - assert_equal 'HTTP/1.1', req['SERVER_PROTOCOL'] + assert_equal 'HTTP/1.0', req['SERVER_PROTOCOL'] assert_nil req['FRAGMENT'] assert_equal '', req['QUERY_STRING'] assert_equal "", http @@ -367,7 +367,7 @@ class HttpParserTest < Test::Unit::TestCase assert_equal '/', req['REQUEST_URI'] assert_equal 'PUT', req['REQUEST_METHOD'] assert_equal 'HTTP/1.0', req['HTTP_VERSION'] - assert_equal 'HTTP/1.1', req['SERVER_PROTOCOL'] + assert_equal 'HTTP/1.0', req['SERVER_PROTOCOL'] assert_equal "abcde", http assert ! parser.keepalive? # TODO: read HTTP/1.2 when it's final end @@ -381,7 +381,7 @@ class HttpParserTest < Test::Unit::TestCase assert_equal '/l', req['REQUEST_URI'] assert_equal 'PUT', req['REQUEST_METHOD'] assert_equal 'HTTP/1.0', req['HTTP_VERSION'] - assert_equal 'HTTP/1.1', req['SERVER_PROTOCOL'] + assert_equal 'HTTP/1.0', req['SERVER_PROTOCOL'] assert_equal "", http assert ! parser.keepalive? # TODO: read HTTP/1.2 when it's final end diff --git a/test/unit/test_http_parser_ng.rb b/test/unit/test_http_parser_ng.rb index f5b575b..9b86cd3 100644 --- a/test/unit/test_http_parser_ng.rb +++ b/test/unit/test_http_parser_ng.rb @@ -294,7 +294,7 @@ class HttpParserNgTest < Test::Unit::TestCase "PATH_INFO"=>"/read-rfc1945-if-you-dont-believe-me", "REQUEST_URI"=>"/read-rfc1945-if-you-dont-believe-me", "SERVER_PORT"=>"80", - "SERVER_PROTOCOL"=>"HTTP/1.1", # FIXME + "SERVER_PROTOCOL"=>"HTTP/0.9", "REQUEST_METHOD"=>"GET", "QUERY_STRING"=>"" } -- cgit v1.2.3-24-ge0c7