1 # Copyright (c) 2009 Eric Wong
2 # You can redistribute it and/or modify it under the same terms as Ruby.
4 require 'test/test_helper'
9 warn "Unable to load rack, skipping test"
15 class RequestTest < Test::Unit::TestCase
17 class MockRequest < StringIO; end
20 @request = HttpRequest.new(Logger.new($stderr))
21 @app = lambda do |env|
22 [ 200, { 'Content-Length' => '0', 'Content-Type' => 'text/plain' }, [] ]
24 @lint = Rack::Lint.new(@app)
28 client = MockRequest.new("OPTIONS * HTTP/1.1\r\n" \
31 assert_nothing_raised { env = @request.read(client) }
32 assert_equal '', env['REQUEST_PATH']
33 assert_equal '', env['PATH_INFO']
34 assert_equal '*', env['REQUEST_URI']
35 assert_nothing_raised { res = @lint.call(env) }
38 def test_absolute_uri_with_query
39 client = MockRequest.new("GET http://e:3/x?y=z HTTP/1.1\r\n" \
42 assert_nothing_raised { env = @request.read(client) }
43 assert_equal '/x', env['REQUEST_PATH']
44 assert_equal '/x', env['PATH_INFO']
45 assert_equal 'y=z', env['QUERY_STRING']
46 assert_nothing_raised { res = @lint.call(env) }
49 def test_absolute_uri_with_fragment
50 client = MockRequest.new("GET http://e:3/x#frag HTTP/1.1\r\n" \
53 assert_nothing_raised { env = @request.read(client) }
54 assert_equal '/x', env['REQUEST_PATH']
55 assert_equal '/x', env['PATH_INFO']
56 assert_equal '', env['QUERY_STRING']
57 assert_equal 'frag', env['FRAGMENT']
58 assert_nothing_raised { res = @lint.call(env) }
61 def test_absolute_uri_with_query_and_fragment
62 client = MockRequest.new("GET http://e:3/x?a=b#frag HTTP/1.1\r\n" \
65 assert_nothing_raised { env = @request.read(client) }
66 assert_equal '/x', env['REQUEST_PATH']
67 assert_equal '/x', env['PATH_INFO']
68 assert_equal 'a=b', env['QUERY_STRING']
69 assert_equal 'frag', env['FRAGMENT']
70 assert_nothing_raised { res = @lint.call(env) }
73 def test_absolute_uri_unsupported_schemes
74 %w(ssh+http://e/ ftp://e/x http+ssh://e/x).each do |abs_uri|
75 client = MockRequest.new("GET #{abs_uri} HTTP/1.1\r\n" \
77 assert_raises(HttpParserError) { @request.read(client) }
82 def test_x_forwarded_proto_https
84 client = MockRequest.new("GET / HTTP/1.1\r\n" \
85 "X-Forwarded-Proto: https\r\n" \
87 assert_nothing_raised { env = @request.read(client) }
88 assert_equal "https", env['rack.url_scheme']
89 assert_nothing_raised { res = @lint.call(env) }
92 def test_x_forwarded_proto_http
94 client = MockRequest.new("GET / HTTP/1.1\r\n" \
95 "X-Forwarded-Proto: http\r\n" \
97 assert_nothing_raised { env = @request.read(client) }
98 assert_equal "http", env['rack.url_scheme']
99 assert_nothing_raised { res = @lint.call(env) }
102 def test_x_forwarded_proto_invalid
104 client = MockRequest.new("GET / HTTP/1.1\r\n" \
105 "X-Forwarded-Proto: ftp\r\n" \
107 assert_nothing_raised { env = @request.read(client) }
108 assert_equal "http", env['rack.url_scheme']
109 assert_nothing_raised { res = @lint.call(env) }
112 def test_rack_lint_get
113 client = MockRequest.new("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")
115 assert_nothing_raised { env = @request.read(client) }
116 assert_equal "http", env['rack.url_scheme']
117 assert_equal '127.0.0.1', env['REMOTE_ADDR']
118 assert_nothing_raised { res = @lint.call(env) }
121 def test_rack_lint_put
122 client = MockRequest.new(
123 "PUT / HTTP/1.1\r\n" \
125 "Content-Length: 5\r\n" \
129 assert_nothing_raised { env = @request.read(client) }
130 assert ! env.include?(:http_body)
131 assert_nothing_raised { res = @lint.call(env) }
134 def test_rack_lint_big_put
137 buf = (' ' * bs).freeze
139 client = Tempfile.new('big_put')
141 "PUT / HTTP/1.1\r\n" \
143 "Content-Length: #{length}\r\n" \
145 count.times { assert_equal bs, client.syswrite(buf) }
146 assert_equal 0, client.sysseek(0)
148 assert_nothing_raised { env = @request.read(client) }
149 assert ! env.include?(:http_body)
150 assert_equal length, env['rack.input'].size
151 count.times { assert_equal buf, env['rack.input'].read(bs) }
152 assert_nil env['rack.input'].read(bs)
153 assert_nothing_raised { env['rack.input'].rewind }
154 assert_nothing_raised { res = @lint.call(env) }