diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/exec/test_exec.rb | 1 | ||||
-rw-r--r-- | test/unit/test_http_parser.rb | 120 | ||||
-rw-r--r-- | test/unit/test_request.rb | 54 | ||||
-rw-r--r-- | test/unit/test_socket_helper.rb | 45 | ||||
-rw-r--r-- | test/unit/test_upload.rb | 19 |
5 files changed, 176 insertions, 63 deletions
diff --git a/test/exec/test_exec.rb b/test/exec/test_exec.rb index 888f7c7..b0462dc 100644 --- a/test/exec/test_exec.rb +++ b/test/exec/test_exec.rb @@ -459,6 +459,7 @@ end results = nil sock = Tempfile.new('unicorn_test_sock') sock_path = sock.path + @sockets << sock_path sock.close! ucfg = Tempfile.new('unicorn_test_config') ucfg.syswrite("listen \"#{sock_path}\"\n") diff --git a/test/unit/test_http_parser.rb b/test/unit/test_http_parser.rb index f6fdd47..a158ebb 100644 --- a/test/unit/test_http_parser.rb +++ b/test/unit/test_http_parser.rb @@ -22,7 +22,7 @@ class HttpParserTest < Test::Unit::TestCase assert_equal '/', req['REQUEST_URI'] assert_equal 'GET', req['REQUEST_METHOD'] assert_nil req['FRAGMENT'] - assert_nil req['QUERY_STRING'] + assert_equal '', req['QUERY_STRING'] parser.reset req.clear @@ -40,7 +40,40 @@ class HttpParserTest < Test::Unit::TestCase assert_equal '/hello-world', req['REQUEST_URI'] assert_equal 'GET', req['REQUEST_METHOD'] assert_nil req['FRAGMENT'] - assert_nil req['QUERY_STRING'] + assert_equal '', req['QUERY_STRING'] + end + + def test_parse_server_host_default_port + parser = HttpParser.new + req = {} + assert parser.execute(req, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n") + assert_equal 'foo', req['SERVER_NAME'] + assert_equal '80', req['SERVER_PORT'] + end + + def test_parse_server_host_alt_port + parser = HttpParser.new + req = {} + assert parser.execute(req, "GET / HTTP/1.1\r\nHost: foo:999\r\n\r\n") + assert_equal 'foo', req['SERVER_NAME'] + assert_equal '999', req['SERVER_PORT'] + end + + def test_parse_server_host_empty_port + parser = HttpParser.new + req = {} + assert parser.execute(req, "GET / HTTP/1.1\r\nHost: foo:\r\n\r\n") + assert_equal 'foo', req['SERVER_NAME'] + assert_equal '80', req['SERVER_PORT'] + end + + def test_parse_server_host_xfp_https + parser = HttpParser.new + req = {} + assert parser.execute(req, "GET / HTTP/1.1\r\nHost: foo:\r\n" \ + "X-Forwarded-Proto: https\r\n\r\n") + assert_equal 'foo', req['SERVER_NAME'] + assert_equal '443', req['SERVER_PORT'] end def test_parse_strange_headers @@ -100,7 +133,88 @@ class HttpParserTest < Test::Unit::TestCase assert parser.execute(req, http << "\n") assert_equal 'HTTP/1.1', req['SERVER_PROTOCOL'] assert_nil req['FRAGMENT'] - assert_nil req['QUERY_STRING'] + assert_equal '', req['QUERY_STRING'] + end + + # not common, but underscores do appear in practice + def test_absolute_uri_underscores + parser = HttpParser.new + req = {} + http = "GET http://under_score.example.com/foo?q=bar HTTP/1.0\r\n\r\n" + assert parser.execute(req, http) + assert_equal 'http', req['rack.url_scheme'] + assert_equal '/foo?q=bar', req['REQUEST_URI'] + assert_equal '/foo', req['REQUEST_PATH'] + assert_equal 'q=bar', req['QUERY_STRING'] + + assert_equal 'under_score.example.com', req['HTTP_HOST'] + assert_equal 'under_score.example.com', req['SERVER_NAME'] + assert_equal '80', req['SERVER_PORT'] + end + + def test_absolute_uri + parser = HttpParser.new + req = {} + http = "GET http://example.com/foo?q=bar HTTP/1.0\r\n\r\n" + assert parser.execute(req, http) + assert_equal 'http', req['rack.url_scheme'] + assert_equal '/foo?q=bar', req['REQUEST_URI'] + assert_equal '/foo', req['REQUEST_PATH'] + assert_equal 'q=bar', req['QUERY_STRING'] + + assert_equal 'example.com', req['HTTP_HOST'] + assert_equal 'example.com', req['SERVER_NAME'] + assert_equal '80', req['SERVER_PORT'] + end + + # X-Forwarded-Proto is not in rfc2616, absolute URIs are, however... + def test_absolute_uri_https + parser = HttpParser.new + req = {} + http = "GET https://example.com/foo?q=bar HTTP/1.1\r\n" \ + "X-Forwarded-Proto: http\r\n\r\n" + assert parser.execute(req, http) + assert_equal 'https', req['rack.url_scheme'] + assert_equal '/foo?q=bar', req['REQUEST_URI'] + assert_equal '/foo', req['REQUEST_PATH'] + assert_equal 'q=bar', req['QUERY_STRING'] + + assert_equal 'example.com', req['HTTP_HOST'] + assert_equal 'example.com', req['SERVER_NAME'] + assert_equal '443', req['SERVER_PORT'] + end + + # Host: header should be ignored for absolute URIs + def test_absolute_uri_with_port + parser = HttpParser.new + req = {} + http = "GET http://example.com:8080/foo?q=bar HTTP/1.2\r\n" \ + "Host: bad.example.com\r\n\r\n" + assert parser.execute(req, http) + assert_equal 'http', req['rack.url_scheme'] + assert_equal '/foo?q=bar', req['REQUEST_URI'] + assert_equal '/foo', req['REQUEST_PATH'] + assert_equal 'q=bar', req['QUERY_STRING'] + + assert_equal 'example.com:8080', req['HTTP_HOST'] + assert_equal 'example.com', req['SERVER_NAME'] + assert_equal '8080', req['SERVER_PORT'] + end + + def test_absolute_uri_with_empty_port + parser = HttpParser.new + req = {} + http = "GET https://example.com:/foo?q=bar HTTP/1.1\r\n" \ + "Host: bad.example.com\r\n\r\n" + assert parser.execute(req, http) + assert_equal 'https', req['rack.url_scheme'] + assert_equal '/foo?q=bar', req['REQUEST_URI'] + assert_equal '/foo', req['REQUEST_PATH'] + assert_equal 'q=bar', req['QUERY_STRING'] + + assert_equal 'example.com:', req['HTTP_HOST'] + assert_equal 'example.com', req['SERVER_NAME'] + assert_equal '443', req['SERVER_PORT'] end def test_put_body_oneshot diff --git a/test/unit/test_request.rb b/test/unit/test_request.rb index 0613326..7c438da 100644 --- a/test/unit/test_request.rb +++ b/test/unit/test_request.rb @@ -19,11 +19,7 @@ include Unicorn class RequestTest < Test::Unit::TestCase - class MockRequest < StringIO - def unicorn_peeraddr - '666.666.666.666' - end - end + class MockRequest < StringIO; end def setup @request = HttpRequest.new(Logger.new($stderr)) @@ -38,23 +34,56 @@ class RequestTest < Test::Unit::TestCase "Host: foo\r\n\r\n") res = env = nil assert_nothing_raised { env = @request.read(client) } - assert_equal '*', env['REQUEST_PATH'] - assert_equal '*', env['PATH_INFO'] + assert_equal '', env['REQUEST_PATH'] + assert_equal '', env['PATH_INFO'] assert_equal '*', env['REQUEST_URI'] - - # assert_nothing_raised { res = @lint.call(env) } # fails Rack lint + assert_nothing_raised { res = @lint.call(env) } end - def test_full_url_path + def test_absolute_uri_with_query client = MockRequest.new("GET http://e:3/x?y=z HTTP/1.1\r\n" \ "Host: foo\r\n\r\n") res = env = nil assert_nothing_raised { env = @request.read(client) } assert_equal '/x', env['REQUEST_PATH'] assert_equal '/x', env['PATH_INFO'] + assert_equal 'y=z', env['QUERY_STRING'] + assert_nothing_raised { res = @lint.call(env) } + end + + def test_absolute_uri_with_fragment + client = MockRequest.new("GET http://e:3/x#frag HTTP/1.1\r\n" \ + "Host: foo\r\n\r\n") + res = env = nil + assert_nothing_raised { env = @request.read(client) } + assert_equal '/x', env['REQUEST_PATH'] + assert_equal '/x', env['PATH_INFO'] + assert_equal '', env['QUERY_STRING'] + assert_equal 'frag', env['FRAGMENT'] assert_nothing_raised { res = @lint.call(env) } end + def test_absolute_uri_with_query_and_fragment + client = MockRequest.new("GET http://e:3/x?a=b#frag HTTP/1.1\r\n" \ + "Host: foo\r\n\r\n") + res = env = nil + assert_nothing_raised { env = @request.read(client) } + assert_equal '/x', env['REQUEST_PATH'] + assert_equal '/x', env['PATH_INFO'] + assert_equal 'a=b', env['QUERY_STRING'] + assert_equal 'frag', env['FRAGMENT'] + assert_nothing_raised { res = @lint.call(env) } + end + + def test_absolute_uri_unsupported_schemes + %w(ssh+http://e/ ftp://e/x http+ssh://e/x).each do |abs_uri| + client = MockRequest.new("GET #{abs_uri} HTTP/1.1\r\n" \ + "Host: foo\r\n\r\n") + assert_raises(HttpParserError) { @request.read(client) } + @request.reset + end + end + def test_x_forwarded_proto_https res = env = nil client = MockRequest.new("GET / HTTP/1.1\r\n" \ @@ -90,7 +119,7 @@ class RequestTest < Test::Unit::TestCase res = env = nil assert_nothing_raised { env = @request.read(client) } assert_equal "http", env['rack.url_scheme'] - assert_equal '666.666.666.666', env['REMOTE_ADDR'] + assert_equal '127.0.0.1', env['REMOTE_ADDR'] assert_nothing_raised { res = @lint.call(env) } end @@ -113,9 +142,6 @@ class RequestTest < Test::Unit::TestCase buf = (' ' * bs).freeze length = bs * count client = Tempfile.new('big_put') - def client.unicorn_peeraddr - '1.1.1.1' - end client.syswrite( "PUT / HTTP/1.1\r\n" \ "Host: foo\r\n" \ diff --git a/test/unit/test_socket_helper.rb b/test/unit/test_socket_helper.rb index 0608e24..3e28cb9 100644 --- a/test/unit/test_socket_helper.rb +++ b/test/unit/test_socket_helper.rb @@ -123,49 +123,4 @@ class TestSocketHelper < Test::Unit::TestCase sock_name(@unix_server) end - def test_tcp_unicorn_peeraddr - test_bind_listen_tcp - @tcp_server = server_cast(@tcp_listener) - tmp = Tempfile.new 'shared' - pid = fork do - client = @tcp_server.accept - IO.select([client]) - assert_equal GET_SLASH, client.sysread(GET_SLASH.size) - tmp.syswrite "#{client.unicorn_peeraddr}" - exit 0 - end - host, port = sock_name(@tcp_server).split(/:/) - client = TCPSocket.new(host, port.to_i) - client.syswrite(GET_SLASH) - - pid, status = Process.waitpid2(pid) - assert_nothing_raised { client.close } - assert status.success? - tmp.sysseek 0 - assert_equal @test_addr, tmp.sysread(4096) - tmp.sysseek 0 - end - - def test_unix_unicorn_peeraddr - test_bind_listen_unix - @unix_server = server_cast(@unix_listener) - tmp = Tempfile.new 'shared' - pid = fork do - client = @unix_server.accept - IO.select([client]) - assert_equal GET_SLASH, client.sysread(4096) - tmp.syswrite "#{client.unicorn_peeraddr}" - exit 0 - end - client = UNIXSocket.new(@unix_listener_path) - client.syswrite(GET_SLASH) - - pid, status = Process.waitpid2(pid) - assert_nothing_raised { client.close } - assert status.success? - tmp.sysseek 0 - assert_equal '127.0.0.1', tmp.sysread(4096) - tmp.sysseek 0 - end - end diff --git a/test/unit/test_upload.rb b/test/unit/test_upload.rb index 86b6c6c..b06dfdb 100644 --- a/test/unit/test_upload.rb +++ b/test/unit/test_upload.rb @@ -18,7 +18,8 @@ class UploadTest < Test::Unit::TestCase @sha1 = Digest::SHA1.new @sha1_app = lambda do |env| input = env['rack.input'] - resp = { :pos => input.pos, :size => input.stat.size } + resp = { :pos => input.pos, :size => input.size, :class => input.class } + @sha1.reset begin loop { @sha1.update(input.sysread(@bs)) } rescue EOFError @@ -216,6 +217,22 @@ class UploadTest < Test::Unit::TestCase resp = `curl -isSfN -T#{tmp.path} http://#@addr:#@port/` assert $?.success?, 'curl ran OK' assert_match(%r!\b#{sha1}\b!, resp) + assert_match(/Tempfile/, resp) + + # small StringIO path + assert(system("dd", "if=#{@random.path}", "of=#{tmp.path}", + "bs=1024", "count=1"), + "dd #@random to #{tmp}") + sha1_re = %r!\b([a-f0-9]{40})\b! + sha1_out = `sha1sum #{tmp.path}` + assert $?.success?, 'sha1sum ran OK' + + assert_match(sha1_re, sha1_out) + sha1 = sha1_re.match(sha1_out)[1] + resp = `curl -isSfN -T#{tmp.path} http://#@addr:#@port/` + assert $?.success?, 'curl ran OK' + assert_match(%r!\b#{sha1}\b!, resp) + assert_match(/StringIO/, resp) end private |