Stop extending core classes
[unicorn.git] / test / unit / test_request.rb
blob7c438da95b52e9a4b3fd6edff84ac31d2ea0bb49
1 # Copyright (c) 2009 Eric Wong
2 # You can redistribute it and/or modify it under the same terms as Ruby.
4 if RUBY_VERSION =~ /1\.9/
5   warn "#$0 current broken under Ruby 1.9 with Rack"
6   exit 0
7 end
9 require 'test/test_helper'
10 begin
11   require 'rack'
12   require 'rack/lint'
13 rescue LoadError
14   warn "Unable to load rack, skipping test"
15   exit 0
16 end
18 include Unicorn
20 class RequestTest < Test::Unit::TestCase
22   class MockRequest < StringIO; end
24   def setup
25     @request = HttpRequest.new(Logger.new($stderr))
26     @app = lambda do |env|
27       [ 200, { 'Content-Length' => '0', 'Content-Type' => 'text/plain' }, [] ]
28     end
29     @lint = Rack::Lint.new(@app)
30   end
32   def test_options
33     client = MockRequest.new("OPTIONS * HTTP/1.1\r\n" \
34                              "Host: foo\r\n\r\n")
35     res = env = nil
36     assert_nothing_raised { env = @request.read(client) }
37     assert_equal '', env['REQUEST_PATH']
38     assert_equal '', env['PATH_INFO']
39     assert_equal '*', env['REQUEST_URI']
40     assert_nothing_raised { res = @lint.call(env) }
41   end
43   def test_absolute_uri_with_query
44     client = MockRequest.new("GET http://e:3/x?y=z HTTP/1.1\r\n" \
45                              "Host: foo\r\n\r\n")
46     res = env = nil
47     assert_nothing_raised { env = @request.read(client) }
48     assert_equal '/x', env['REQUEST_PATH']
49     assert_equal '/x', env['PATH_INFO']
50     assert_equal 'y=z', env['QUERY_STRING']
51     assert_nothing_raised { res = @lint.call(env) }
52   end
54   def test_absolute_uri_with_fragment
55     client = MockRequest.new("GET http://e:3/x#frag HTTP/1.1\r\n" \
56                              "Host: foo\r\n\r\n")
57     res = env = nil
58     assert_nothing_raised { env = @request.read(client) }
59     assert_equal '/x', env['REQUEST_PATH']
60     assert_equal '/x', env['PATH_INFO']
61     assert_equal '', env['QUERY_STRING']
62     assert_equal 'frag', env['FRAGMENT']
63     assert_nothing_raised { res = @lint.call(env) }
64   end
66   def test_absolute_uri_with_query_and_fragment
67     client = MockRequest.new("GET http://e:3/x?a=b#frag HTTP/1.1\r\n" \
68                              "Host: foo\r\n\r\n")
69     res = env = nil
70     assert_nothing_raised { env = @request.read(client) }
71     assert_equal '/x', env['REQUEST_PATH']
72     assert_equal '/x', env['PATH_INFO']
73     assert_equal 'a=b', env['QUERY_STRING']
74     assert_equal 'frag', env['FRAGMENT']
75     assert_nothing_raised { res = @lint.call(env) }
76   end
78   def test_absolute_uri_unsupported_schemes
79     %w(ssh+http://e/ ftp://e/x http+ssh://e/x).each do |abs_uri|
80       client = MockRequest.new("GET #{abs_uri} HTTP/1.1\r\n" \
81                                "Host: foo\r\n\r\n")
82       assert_raises(HttpParserError) { @request.read(client) }
83       @request.reset
84     end
85   end
87   def test_x_forwarded_proto_https
88     res = env = nil
89     client = MockRequest.new("GET / HTTP/1.1\r\n" \
90                              "X-Forwarded-Proto: https\r\n" \
91                              "Host: foo\r\n\r\n")
92     assert_nothing_raised { env = @request.read(client) }
93     assert_equal "https", env['rack.url_scheme']
94     assert_nothing_raised { res = @lint.call(env) }
95   end
97   def test_x_forwarded_proto_http
98     res = env = nil
99     client = MockRequest.new("GET / HTTP/1.1\r\n" \
100                              "X-Forwarded-Proto: http\r\n" \
101                              "Host: foo\r\n\r\n")
102     assert_nothing_raised { env = @request.read(client) }
103     assert_equal "http", env['rack.url_scheme']
104     assert_nothing_raised { res = @lint.call(env) }
105   end
107   def test_x_forwarded_proto_invalid
108     res = env = nil
109     client = MockRequest.new("GET / HTTP/1.1\r\n" \
110                              "X-Forwarded-Proto: ftp\r\n" \
111                              "Host: foo\r\n\r\n")
112     assert_nothing_raised { env = @request.read(client) }
113     assert_equal "http", env['rack.url_scheme']
114     assert_nothing_raised { res = @lint.call(env) }
115   end
117   def test_rack_lint_get
118     client = MockRequest.new("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")
119     res = env = nil
120     assert_nothing_raised { env = @request.read(client) }
121     assert_equal "http", env['rack.url_scheme']
122     assert_equal '127.0.0.1', env['REMOTE_ADDR']
123     assert_nothing_raised { res = @lint.call(env) }
124   end
126   def test_rack_lint_put
127     client = MockRequest.new(
128       "PUT / HTTP/1.1\r\n" \
129       "Host: foo\r\n" \
130       "Content-Length: 5\r\n" \
131       "\r\n" \
132       "abcde")
133     res = env = nil
134     assert_nothing_raised { env = @request.read(client) }
135     assert ! env.include?(:http_body)
136     assert_nothing_raised { res = @lint.call(env) }
137   end
139   def test_rack_lint_big_put
140     count = 100
141     bs = 0x10000
142     buf = (' ' * bs).freeze
143     length = bs * count
144     client = Tempfile.new('big_put')
145     client.syswrite(
146       "PUT / HTTP/1.1\r\n" \
147       "Host: foo\r\n" \
148       "Content-Length: #{length}\r\n" \
149       "\r\n")
150     count.times { assert_equal bs, client.syswrite(buf) }
151     assert_equal 0, client.sysseek(0)
152     res = env = nil
153     assert_nothing_raised { env = @request.read(client) }
154     assert ! env.include?(:http_body)
155     assert_equal length, env['rack.input'].size
156     count.times { assert_equal buf, env['rack.input'].read(bs) }
157     assert_nil env['rack.input'].read(bs)
158     assert_nothing_raised { env['rack.input'].rewind }
159     assert_nothing_raised { res = @lint.call(env) }
160   end