test_response: correct OFS test
[unicorn.git] / test / unit / test_request.rb
blob0bfff7d5b1c445c3e855fa71f87366be974415f2
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
18     alias_method :readpartial, :sysread
19   end
21   def setup
22     @request = HttpRequest.new(Logger.new($stderr))
23     @app = lambda do |env|
24       [ 200, { 'Content-Length' => '0', 'Content-Type' => 'text/plain' }, [] ]
25     end
26     @lint = Rack::Lint.new(@app)
27   end
29   def test_options
30     client = MockRequest.new("OPTIONS * HTTP/1.1\r\n" \
31                              "Host: foo\r\n\r\n")
32     res = env = nil
33     assert_nothing_raised { env = @request.read(client) }
34     assert_equal '', env['REQUEST_PATH']
35     assert_equal '', env['PATH_INFO']
36     assert_equal '*', env['REQUEST_URI']
37     assert_nothing_raised { res = @lint.call(env) }
38   end
40   def test_absolute_uri_with_query
41     client = MockRequest.new("GET http://e:3/x?y=z HTTP/1.1\r\n" \
42                              "Host: foo\r\n\r\n")
43     res = env = nil
44     assert_nothing_raised { env = @request.read(client) }
45     assert_equal '/x', env['REQUEST_PATH']
46     assert_equal '/x', env['PATH_INFO']
47     assert_equal 'y=z', env['QUERY_STRING']
48     assert_nothing_raised { res = @lint.call(env) }
49   end
51   def test_absolute_uri_with_fragment
52     client = MockRequest.new("GET http://e:3/x#frag HTTP/1.1\r\n" \
53                              "Host: foo\r\n\r\n")
54     res = env = nil
55     assert_nothing_raised { env = @request.read(client) }
56     assert_equal '/x', env['REQUEST_PATH']
57     assert_equal '/x', env['PATH_INFO']
58     assert_equal '', env['QUERY_STRING']
59     assert_equal 'frag', env['FRAGMENT']
60     assert_nothing_raised { res = @lint.call(env) }
61   end
63   def test_absolute_uri_with_query_and_fragment
64     client = MockRequest.new("GET http://e:3/x?a=b#frag HTTP/1.1\r\n" \
65                              "Host: foo\r\n\r\n")
66     res = env = nil
67     assert_nothing_raised { env = @request.read(client) }
68     assert_equal '/x', env['REQUEST_PATH']
69     assert_equal '/x', env['PATH_INFO']
70     assert_equal 'a=b', env['QUERY_STRING']
71     assert_equal 'frag', env['FRAGMENT']
72     assert_nothing_raised { res = @lint.call(env) }
73   end
75   def test_absolute_uri_unsupported_schemes
76     %w(ssh+http://e/ ftp://e/x http+ssh://e/x).each do |abs_uri|
77       client = MockRequest.new("GET #{abs_uri} HTTP/1.1\r\n" \
78                                "Host: foo\r\n\r\n")
79       assert_raises(HttpParserError) { @request.read(client) }
80     end
81   end
83   def test_x_forwarded_proto_https
84     res = env = nil
85     client = MockRequest.new("GET / HTTP/1.1\r\n" \
86                              "X-Forwarded-Proto: https\r\n" \
87                              "Host: foo\r\n\r\n")
88     assert_nothing_raised { env = @request.read(client) }
89     assert_equal "https", env['rack.url_scheme']
90     assert_nothing_raised { res = @lint.call(env) }
91   end
93   def test_x_forwarded_proto_http
94     res = env = nil
95     client = MockRequest.new("GET / HTTP/1.1\r\n" \
96                              "X-Forwarded-Proto: http\r\n" \
97                              "Host: foo\r\n\r\n")
98     assert_nothing_raised { env = @request.read(client) }
99     assert_equal "http", env['rack.url_scheme']
100     assert_nothing_raised { res = @lint.call(env) }
101   end
103   def test_x_forwarded_proto_invalid
104     res = env = nil
105     client = MockRequest.new("GET / HTTP/1.1\r\n" \
106                              "X-Forwarded-Proto: ftp\r\n" \
107                              "Host: foo\r\n\r\n")
108     assert_nothing_raised { env = @request.read(client) }
109     assert_equal "http", env['rack.url_scheme']
110     assert_nothing_raised { res = @lint.call(env) }
111   end
113   def test_rack_lint_get
114     client = MockRequest.new("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")
115     res = env = nil
116     assert_nothing_raised { env = @request.read(client) }
117     assert_equal "http", env['rack.url_scheme']
118     assert_equal '127.0.0.1', env['REMOTE_ADDR']
119     assert_nothing_raised { res = @lint.call(env) }
120   end
122   def test_rack_lint_put
123     client = MockRequest.new(
124       "PUT / HTTP/1.1\r\n" \
125       "Host: foo\r\n" \
126       "Content-Length: 5\r\n" \
127       "\r\n" \
128       "abcde")
129     res = env = nil
130     assert_nothing_raised { env = @request.read(client) }
131     assert ! env.include?(:http_body)
132     assert_nothing_raised { res = @lint.call(env) }
133   end
135   def test_rack_lint_big_put
136     count = 100
137     bs = 0x10000
138     buf = (' ' * bs).freeze
139     length = bs * count
140     client = Tempfile.new('big_put')
141     client.syswrite(
142       "PUT / HTTP/1.1\r\n" \
143       "Host: foo\r\n" \
144       "Content-Length: #{length}\r\n" \
145       "\r\n")
146     count.times { assert_equal bs, client.syswrite(buf) }
147     assert_equal 0, client.sysseek(0)
148     res = env = nil
149     assert_nothing_raised { env = @request.read(client) }
150     assert ! env.include?(:http_body)
151     assert_equal length, env['rack.input'].size
152     count.times { assert_equal buf, env['rack.input'].read(bs) }
153     assert_nil env['rack.input'].read(bs)
154     assert_nothing_raised { env['rack.input'].rewind }
155     assert_nothing_raised { res = @lint.call(env) }
156   end