http11: handle "X-Forwarded-Proto: https"
[unicorn.git] / test / unit / test_request.rb
blob5109c7b6bcd34322b0304d8b579223d01e0b900c
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
23     def unicorn_peeraddr
24       '666.666.666.666'
25     end
26   end
28   def setup
29     @request = HttpRequest.new(Logger.new($stderr))
30     @app = lambda do |env|
31       [ 200, { 'Content-Length' => '0', 'Content-Type' => 'text/plain' }, [] ]
32     end
33     @lint = Rack::Lint.new(@app)
34   end
36   def test_options
37     client = MockRequest.new("OPTIONS * HTTP/1.1\r\n" \
38                              "Host: foo\r\n\r\n")
39     res = env = nil
40     assert_nothing_raised { env = @request.read(client) }
41     assert_equal '*', env['REQUEST_PATH']
42     assert_equal '*', env['PATH_INFO']
43     assert_equal '*', env['REQUEST_URI']
45     # assert_nothing_raised { res = @lint.call(env) } # fails Rack lint
46   end
48   def test_full_url_path
49     client = MockRequest.new("GET http://e:3/x?y=z HTTP/1.1\r\n" \
50                              "Host: foo\r\n\r\n")
51     res = env = nil
52     assert_nothing_raised { env = @request.read(client) }
53     assert_equal '/x', env['REQUEST_PATH']
54     assert_equal '/x', env['PATH_INFO']
55     assert_nothing_raised { res = @lint.call(env) }
56   end
58   def test_x_forwarded_proto
59     res = env = nil
60     client = MockRequest.new("GET / HTTP/1.1\r\n" \
61                              "X-Forwarded-Proto: https\r\n" \
62                              "Host: foo\r\n\r\n")
63     assert_nothing_raised { env = @request.read(client) }
64     assert_equal "https", env['rack.url_scheme']
65     assert_nothing_raised { res = @lint.call(env) }
66   end
68   def test_x_forwarded_proto_invalid
69     res = env = nil
70     client = MockRequest.new("GET / HTTP/1.1\r\n" \
71                              "X-Forwarded-Proto: ftp\r\n" \
72                              "Host: foo\r\n\r\n")
73     assert_nothing_raised { env = @request.read(client) }
74     assert_equal "http", env['rack.url_scheme']
75     assert_nothing_raised { res = @lint.call(env) }
76   end
78   def test_rack_lint_get
79     client = MockRequest.new("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")
80     res = env = nil
81     assert_nothing_raised { env = @request.read(client) }
82     assert_equal "http", env['rack.url_scheme']
83     assert_equal '666.666.666.666', env['REMOTE_ADDR']
84     assert_nothing_raised { res = @lint.call(env) }
85   end
87   def test_rack_lint_put
88     client = MockRequest.new(
89       "PUT / HTTP/1.1\r\n" \
90       "Host: foo\r\n" \
91       "Content-Length: 5\r\n" \
92       "\r\n" \
93       "abcde")
94     res = env = nil
95     assert_nothing_raised { env = @request.read(client) }
96     assert ! env.include?(:http_body)
97     assert_nothing_raised { res = @lint.call(env) }
98   end
100   def test_rack_lint_big_put
101     count = 100
102     bs = 0x10000
103     buf = (' ' * bs).freeze
104     length = bs * count
105     client = Tempfile.new('big_put')
106     def client.unicorn_peeraddr
107       '1.1.1.1'
108     end
109     client.syswrite(
110       "PUT / HTTP/1.1\r\n" \
111       "Host: foo\r\n" \
112       "Content-Length: #{length}\r\n" \
113       "\r\n")
114     count.times { assert_equal bs, client.syswrite(buf) }
115     assert_equal 0, client.sysseek(0)
116     res = env = nil
117     assert_nothing_raised { env = @request.read(client) }
118     assert ! env.include?(:http_body)
119     assert_equal length, env['rack.input'].size
120     count.times { assert_equal buf, env['rack.input'].read(bs) }
121     assert_nil env['rack.input'].read(bs)
122     assert_nothing_raised { env['rack.input'].rewind }
123     assert_nothing_raised { res = @lint.call(env) }
124   end