test_request: enable with Ruby 1.9 now Rack 1.0.0 is out
[unicorn.git] / test / unit / test_request.rb
blob060da247df2e9fdcbcdce00bd30b3d696eaf7655
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'
5 begin
6   require 'rack'
7   require 'rack/lint'
8 rescue LoadError
9   warn "Unable to load rack, skipping test"
10   exit 0
11 end
13 include Unicorn
15 class RequestTest < Test::Unit::TestCase
17   class MockRequest < StringIO; end
19   def setup
20     @request = HttpRequest.new(Logger.new($stderr))
21     @app = lambda do |env|
22       [ 200, { 'Content-Length' => '0', 'Content-Type' => 'text/plain' }, [] ]
23     end
24     @lint = Rack::Lint.new(@app)
25   end
27   def test_options
28     client = MockRequest.new("OPTIONS * HTTP/1.1\r\n" \
29                              "Host: foo\r\n\r\n")
30     res = env = nil
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) }
36   end
38   def test_absolute_uri_with_query
39     client = MockRequest.new("GET http://e:3/x?y=z HTTP/1.1\r\n" \
40                              "Host: foo\r\n\r\n")
41     res = env = nil
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) }
47   end
49   def test_absolute_uri_with_fragment
50     client = MockRequest.new("GET http://e:3/x#frag HTTP/1.1\r\n" \
51                              "Host: foo\r\n\r\n")
52     res = env = nil
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) }
59   end
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" \
63                              "Host: foo\r\n\r\n")
64     res = env = nil
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) }
71   end
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" \
76                                "Host: foo\r\n\r\n")
77       assert_raises(HttpParserError) { @request.read(client) }
78       @request.reset
79     end
80   end
82   def test_x_forwarded_proto_https
83     res = env = nil
84     client = MockRequest.new("GET / HTTP/1.1\r\n" \
85                              "X-Forwarded-Proto: https\r\n" \
86                              "Host: foo\r\n\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) }
90   end
92   def test_x_forwarded_proto_http
93     res = env = nil
94     client = MockRequest.new("GET / HTTP/1.1\r\n" \
95                              "X-Forwarded-Proto: http\r\n" \
96                              "Host: foo\r\n\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) }
100   end
102   def test_x_forwarded_proto_invalid
103     res = env = nil
104     client = MockRequest.new("GET / HTTP/1.1\r\n" \
105                              "X-Forwarded-Proto: ftp\r\n" \
106                              "Host: foo\r\n\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) }
110   end
112   def test_rack_lint_get
113     client = MockRequest.new("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")
114     res = env = nil
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) }
119   end
121   def test_rack_lint_put
122     client = MockRequest.new(
123       "PUT / HTTP/1.1\r\n" \
124       "Host: foo\r\n" \
125       "Content-Length: 5\r\n" \
126       "\r\n" \
127       "abcde")
128     res = env = nil
129     assert_nothing_raised { env = @request.read(client) }
130     assert ! env.include?(:http_body)
131     assert_nothing_raised { res = @lint.call(env) }
132   end
134   def test_rack_lint_big_put
135     count = 100
136     bs = 0x10000
137     buf = (' ' * bs).freeze
138     length = bs * count
139     client = Tempfile.new('big_put')
140     client.syswrite(
141       "PUT / HTTP/1.1\r\n" \
142       "Host: foo\r\n" \
143       "Content-Length: #{length}\r\n" \
144       "\r\n")
145     count.times { assert_equal bs, client.syswrite(buf) }
146     assert_equal 0, client.sysseek(0)
147     res = env = nil
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) }
155   end