remove optimizations which only made sense in old Rubies
[unxf.git] / test / test_unxf.rb
blobd5da30c958863e6532af284eacac07f5146076a9
1 require "test/unit"
2 require "logger"
3 require "stringio"
4 require "rack"
5 require "rack/lobster"
6 require "unxf"
8 class TestUnXF < Test::Unit::TestCase
10   def setup
11     @env = nil
12     @io = StringIO.new
13     @req = { "rack.logger" => Logger.new(@io) }
14     app = lambda { |env| @env = env; [ 200, {}, [] ] }
15     @app = Rack::ContentLength.new(Rack::ContentType.new(app, 'text/plain'))
16   end
18   def test_single_proxy
19     req = Rack::MockRequest.new(UnXF.new(@app))
20     env = {
21       "HTTP_X_FORWARDED_FOR" => "0.6.6.6",
22       "REMOTE_ADDR" => "127.0.0.1",
23     }
24     r = req.get("http://example.com/", @req.merge(env))
25     assert_equal 200, r.status.to_i
26     assert_equal "0.6.6.6", @env["REMOTE_ADDR"]
27     assert ! @env.key?("HTTP_X_FORWARDED_FOR")
28     assert_equal "0.6.6.6", @env["unxf.for"]
29   end
31   def test_single_proxy_https
32     req = Rack::MockRequest.new(UnXF.new(@app))
33     env = {
34       "HTTP_X_FORWARDED_FOR" => "0.6.6.6",
35       "HTTP_X_FORWARDED_PROTO" => "https",
36       "REMOTE_ADDR" => "127.0.0.1",
37     }
38     r = req.get("http://example.com/", @req.merge(env))
39     assert_equal 200, r.status.to_i
40     assert_equal "0.6.6.6", @env["REMOTE_ADDR"]
41     assert ! @env.key?("HTTP_X_FORWARDED_FOR")
42     assert_equal "0.6.6.6", @env["unxf.for"]
43     assert_equal "https", @env["unxf.proto"]
44     assert_equal "https", @env["rack.url_scheme"]
45   end
47   def test_ipv6_localhost
48     req = Rack::MockRequest.new(UnXF.new(@app))
49     env = {
50       "HTTP_X_FORWARDED_FOR" => "2600:3c01::f03c:91ff:fe96:f5d6",
51       "REMOTE_ADDR" => "::1",
52     }
53     r = req.get("http://example.com/", @req.merge(env))
54     assert_equal 200, r.status.to_i
55     assert_equal "2600:3c01::f03c:91ff:fe96:f5d6", @env["REMOTE_ADDR"]
56     assert ! @env.key?("HTTP_X_FORWARDED_FOR")
57     assert_equal "2600:3c01::f03c:91ff:fe96:f5d6", @env["unxf.for"]
58   end
60   def test_ipv6_mixed_localhost
61     req = Rack::MockRequest.new(UnXF.new(@app))
62     env = {
63       "HTTP_X_FORWARDED_FOR" => "2600:3c01::f03c:91ff:fe96:f5d6,192.168.1.1",
64       "REMOTE_ADDR" => "127.0.0.1",
65     }
66     r = req.get("http://example.com/", @req.merge(env))
67     assert_equal 200, r.status.to_i
68     assert_equal "2600:3c01::f03c:91ff:fe96:f5d6", @env["REMOTE_ADDR"]
69     assert ! @env.key?("HTTP_X_FORWARDED_FOR")
70     assert_equal "2600:3c01::f03c:91ff:fe96:f5d6,192.168.1.1", @env["unxf.for"]
71   end
73   def test_multiple_proxies
74     req = Rack::MockRequest.new(UnXF.new(@app))
75     env = {
76       "HTTP_X_FORWARDED_FOR" => "0.6.6.6,192.168.1.1",
77       "REMOTE_ADDR" => "127.0.0.1",
78     }
79     r = req.get("http://example.com/", @req.merge(env))
80     assert_equal "0.6.6.6", @env["REMOTE_ADDR"]
81     assert_equal 200, r.status.to_i
82     assert ! @env.key?("HTTP_X_FORWARDED_FOR")
83     assert_equal "0.6.6.6,192.168.1.1", @env["unxf.for"]
84   end
86   def test_spoofed
87     req = Rack::MockRequest.new(UnXF.new(@app))
88     env = {
89       "HTTP_X_FORWARDED_FOR" => "0.6.6.6",
90       "REMOTE_ADDR" => "227.0.0.1",
91     }
92     r = req.get("http://example.com/", @req.merge(env))
93     assert_equal "227.0.0.1", @env["REMOTE_ADDR"]
94     assert_equal r.status.to_i, 200
95     assert_equal "0.6.6.6", @env["unxf.for"]
96   end
98   def test_trusted_chain
99     req = Rack::MockRequest.new(UnXF.new(@app))
100     env = {
101       "HTTP_X_FORWARDED_FOR" => "0.6.6.6,192.168.0.1",
102       "REMOTE_ADDR" => "127.0.0.1",
103     }
104     r = req.get("http://example.com/", @req.merge(env))
105     assert_equal 200, r.status.to_i
106     assert_equal "0.6.6.6", @env["REMOTE_ADDR"]
107     assert ! @env.key?("HTTP_X_FORWARDED_FOR")
108     assert_equal "0.6.6.6,192.168.0.1", @env["unxf.for"]
109   end
111   def test_spoofed_in_chain
112     req = Rack::MockRequest.new(UnXF.new(@app))
113     env = {
114       "HTTP_X_FORWARDED_FOR" => "0.6.6.6,8.8.8.8",
115       "REMOTE_ADDR" => "127.0.0.1",
116     }
117     r = req.get("http://example.com/", @req.merge(env))
118     assert_equal "127.0.0.1", @env["REMOTE_ADDR"]
119     assert_equal r.status.to_i, 200
120     assert_equal "0.6.6.6,8.8.8.8", @env["unxf.for"]
121   end
123   def test_spoofed_null_safe
124     req = Rack::MockRequest.new(UnXF.new(@app))
125     env = {
126       "HTTP_X_FORWARDED_FOR" => "\0.6.6.6,8.8.8.8",
127       "REMOTE_ADDR" => "127.0.0.1",
128     }
129     r = req.get("http://example.com/", @req.merge(env))
130     assert_equal "127.0.0.1", @env["REMOTE_ADDR"]
131     assert_equal r.status.to_i, 200
132     assert_equal "\0.6.6.6,8.8.8.8", @env["unxf.for"]
133   end
135   def test_more_trust
136     req = Rack::MockRequest.new(UnXF.new(@app, [ :LOCALHOST, "0.6.6.6" ]))
137     env = {
138       "HTTP_X_FORWARDED_FOR" => "1.6.6.6,0.6.6.6",
139       "REMOTE_ADDR" => "127.0.0.1",
140     }
141     r = req.get("http://example.com/", @req.merge(env))
142     assert_equal r.status.to_i, 200
143     assert_equal "1.6.6.6", @env["REMOTE_ADDR"]
144     assert ! @env.key?("HTTP_X_FORWARDED_FOR")
145     assert_equal "1.6.6.6,0.6.6.6", @env["unxf.for"]
146   end
148   def test_one_trusted
149     req = Rack::MockRequest.new(UnXF.new(@app, "0.6.6.6"))
150     env = {
151       "HTTP_X_FORWARDED_FOR" => "1.6.6.6",
152       "REMOTE_ADDR" => "0.6.6.6",
153     }
154     r = req.get("http://example.com/", @req.merge(env))
155     assert_equal r.status.to_i, 200
156     assert_equal "1.6.6.6", @env["REMOTE_ADDR"]
157     assert ! @env.key?("HTTP_X_FORWARDED_FOR")
158     assert_equal "1.6.6.6", @env["unxf.for"]
159     assert_nil @env["unxf.proto"]
160   end
162   def test_all_trusted
163     req = Rack::MockRequest.new(UnXF.new(@app, ["0.0.0.0/0", "::/0"]))
164     env = {
165       "HTTP_X_FORWARDED_FOR" => "0.6.6.6",
166       "REMOTE_ADDR" => "127.0.0.1",
167     }
168     r = req.get("http://example.com/", @req.merge(env))
169     assert_equal 200, r.status.to_i
170     assert_equal "0.6.6.6", @env["REMOTE_ADDR"]
171     assert ! @env.key?("HTTP_X_FORWARDED_FOR")
172     assert_equal "0.6.6.6", @env["unxf.for"]
174     env = {
175       "HTTP_X_FORWARDED_FOR" => "::5",
176       "REMOTE_ADDR" => "::1",
177     }
178     r = req.get("http://example.com/", @req.merge(env))
179     assert_equal 200, r.status.to_i
180     assert_equal "::5", @env["REMOTE_ADDR"]
181     assert ! @env.key?("HTTP_X_FORWARDED_FOR")
182     assert_equal "::5", @env["unxf.for"]
183   end