rack 1.6.13 → 2.0.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack might be problematic. Click here for more details.

Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/COPYING +1 -1
  3. data/HISTORY.md +138 -8
  4. data/README.rdoc +18 -28
  5. data/Rakefile +6 -14
  6. data/SPEC +3 -3
  7. data/contrib/rack_logo.svg +164 -111
  8. data/example/protectedlobster.rb +1 -1
  9. data/example/protectedlobster.ru +1 -1
  10. data/lib/rack/auth/abstract/request.rb +5 -1
  11. data/lib/rack/auth/digest/params.rb +2 -3
  12. data/lib/rack/auth/digest/request.rb +1 -1
  13. data/lib/rack/body_proxy.rb +14 -9
  14. data/lib/rack/builder.rb +3 -3
  15. data/lib/rack/chunked.rb +5 -5
  16. data/lib/rack/{commonlogger.rb → common_logger.rb} +3 -3
  17. data/lib/rack/content_length.rb +2 -2
  18. data/lib/rack/deflater.rb +4 -39
  19. data/lib/rack/directory.rb +66 -54
  20. data/lib/rack/etag.rb +5 -4
  21. data/lib/rack/events.rb +154 -0
  22. data/lib/rack/file.rb +64 -40
  23. data/lib/rack/handler/cgi.rb +15 -16
  24. data/lib/rack/handler/fastcgi.rb +13 -14
  25. data/lib/rack/handler/lsws.rb +11 -11
  26. data/lib/rack/handler/scgi.rb +15 -15
  27. data/lib/rack/handler/thin.rb +3 -0
  28. data/lib/rack/handler/webrick.rb +24 -26
  29. data/lib/rack/handler.rb +3 -25
  30. data/lib/rack/head.rb +15 -17
  31. data/lib/rack/lint.rb +40 -40
  32. data/lib/rack/lobster.rb +1 -1
  33. data/lib/rack/lock.rb +15 -10
  34. data/lib/rack/logger.rb +2 -2
  35. data/lib/rack/media_type.rb +38 -0
  36. data/lib/rack/{methodoverride.rb → method_override.rb} +6 -6
  37. data/lib/rack/mime.rb +18 -5
  38. data/lib/rack/mock.rb +36 -54
  39. data/lib/rack/multipart/generator.rb +5 -5
  40. data/lib/rack/multipart/parser.rb +270 -157
  41. data/lib/rack/multipart/uploaded_file.rb +1 -2
  42. data/lib/rack/multipart.rb +35 -6
  43. data/lib/rack/{nulllogger.rb → null_logger.rb} +1 -1
  44. data/lib/rack/query_parser.rb +192 -0
  45. data/lib/rack/recursive.rb +8 -8
  46. data/lib/rack/request.rb +394 -305
  47. data/lib/rack/response.rb +130 -57
  48. data/lib/rack/rewindable_input.rb +1 -12
  49. data/lib/rack/runtime.rb +10 -18
  50. data/lib/rack/sendfile.rb +5 -7
  51. data/lib/rack/server.rb +30 -23
  52. data/lib/rack/session/abstract/id.rb +110 -75
  53. data/lib/rack/session/cookie.rb +24 -17
  54. data/lib/rack/session/memcache.rb +9 -9
  55. data/lib/rack/session/pool.rb +8 -8
  56. data/lib/rack/show_exceptions.rb +386 -0
  57. data/lib/rack/{showstatus.rb → show_status.rb} +3 -3
  58. data/lib/rack/static.rb +30 -5
  59. data/lib/rack/tempfile_reaper.rb +2 -2
  60. data/lib/rack/urlmap.rb +15 -14
  61. data/lib/rack/utils.rb +138 -211
  62. data/lib/rack.rb +70 -21
  63. data/rack.gemspec +10 -9
  64. data/test/builder/an_underscore_app.rb +5 -0
  65. data/test/builder/options.ru +1 -1
  66. data/test/cgi/test.fcgi +1 -0
  67. data/test/cgi/test.gz +0 -0
  68. data/test/helper.rb +34 -0
  69. data/test/multipart/filename_with_encoded_words +7 -0
  70. data/test/multipart/filename_with_single_quote +7 -0
  71. data/test/multipart/quoted +15 -0
  72. data/test/multipart/rack-logo.png +0 -0
  73. data/test/multipart/unity3d_wwwform +11 -0
  74. data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
  75. data/test/spec_auth_basic.rb +27 -19
  76. data/test/spec_auth_digest.rb +47 -46
  77. data/test/spec_body_proxy.rb +27 -27
  78. data/test/spec_builder.rb +51 -41
  79. data/test/spec_cascade.rb +24 -22
  80. data/test/spec_cgi.rb +49 -67
  81. data/test/spec_chunked.rb +37 -35
  82. data/test/{spec_commonlogger.rb → spec_common_logger.rb} +23 -21
  83. data/test/{spec_conditionalget.rb → spec_conditional_get.rb} +29 -28
  84. data/test/spec_config.rb +3 -2
  85. data/test/spec_content_length.rb +18 -17
  86. data/test/spec_content_type.rb +13 -12
  87. data/test/spec_deflater.rb +85 -49
  88. data/test/spec_directory.rb +87 -27
  89. data/test/spec_etag.rb +32 -31
  90. data/test/spec_events.rb +133 -0
  91. data/test/spec_fastcgi.rb +50 -72
  92. data/test/spec_file.rb +120 -77
  93. data/test/spec_handler.rb +19 -34
  94. data/test/spec_head.rb +15 -14
  95. data/test/spec_lint.rb +164 -199
  96. data/test/spec_lobster.rb +24 -23
  97. data/test/spec_lock.rb +79 -39
  98. data/test/spec_logger.rb +4 -3
  99. data/test/spec_media_type.rb +42 -0
  100. data/test/{spec_methodoverride.rb → spec_method_override.rb} +34 -35
  101. data/test/spec_mime.rb +19 -19
  102. data/test/spec_mock.rb +206 -144
  103. data/test/spec_multipart.rb +322 -200
  104. data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
  105. data/test/spec_recursive.rb +17 -14
  106. data/test/spec_request.rb +780 -605
  107. data/test/spec_response.rb +233 -112
  108. data/test/spec_rewindable_input.rb +50 -40
  109. data/test/spec_runtime.rb +11 -10
  110. data/test/spec_sendfile.rb +30 -35
  111. data/test/spec_server.rb +78 -52
  112. data/test/spec_session_abstract_id.rb +11 -33
  113. data/test/spec_session_abstract_session_hash.rb +45 -0
  114. data/test/spec_session_cookie.rb +99 -67
  115. data/test/spec_session_memcache.rb +67 -68
  116. data/test/spec_session_pool.rb +52 -51
  117. data/test/{spec_showexceptions.rb → spec_show_exceptions.rb} +23 -28
  118. data/test/{spec_showstatus.rb → spec_show_status.rb} +36 -35
  119. data/test/spec_static.rb +71 -32
  120. data/test/spec_tempfile_reaper.rb +11 -10
  121. data/test/spec_thin.rb +55 -50
  122. data/test/spec_urlmap.rb +79 -78
  123. data/test/spec_utils.rb +441 -346
  124. data/test/spec_version.rb +2 -8
  125. data/test/spec_webrick.rb +93 -71
  126. data/test/static/foo.html +1 -0
  127. data/test/testrequest.rb +1 -1
  128. data/test/unregistered_handler/rack/handler/unregistered.rb +1 -1
  129. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +1 -1
  130. metadata +57 -36
  131. data/KNOWN-ISSUES +0 -44
  132. data/lib/rack/backports/uri/common_18.rb +0 -56
  133. data/lib/rack/backports/uri/common_192.rb +0 -52
  134. data/lib/rack/backports/uri/common_193.rb +0 -29
  135. data/lib/rack/handler/evented_mongrel.rb +0 -8
  136. data/lib/rack/handler/mongrel.rb +0 -106
  137. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  138. data/lib/rack/showexceptions.rb +0 -387
  139. data/lib/rack/utils/okjson.rb +0 -600
  140. data/test/spec_mongrel.rb +0 -182
  141. /data/lib/rack/{conditionalget.rb → conditional_get.rb} +0 -0
data/test/spec_request.rb CHANGED
@@ -1,574 +1,724 @@
1
+ require 'minitest/autorun'
1
2
  require 'stringio'
2
3
  require 'cgi'
3
4
  require 'rack/request'
4
5
  require 'rack/mock'
6
+ require 'rack/multipart'
5
7
  require 'securerandom'
6
8
 
7
- describe Rack::Request do
8
- should "wrap the rack variables" do
9
- req = Rack::Request.new(Rack::MockRequest.env_for("http://example.com:8080/"))
9
+ class RackRequestTest < Minitest::Spec
10
+ it "copies the env when duping" do
11
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
12
+ refute_same req.env, req.dup.env
13
+ end
14
+
15
+ it 'can check if something has been set' do
16
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
17
+ refute req.has_header?("FOO")
18
+ end
19
+
20
+ it "can get a key from the env" do
21
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
22
+ assert_equal "example.com", req.get_header("SERVER_NAME")
23
+ end
24
+
25
+ it 'can calculate the authority' do
26
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
27
+ assert_equal "example.com:8080", req.authority
28
+ end
29
+
30
+ it 'can calculate the authority without a port' do
31
+ req = make_request(Rack::MockRequest.env_for("http://example.com/"))
32
+ assert_equal "example.com:80", req.authority
33
+ end
34
+
35
+ it 'can calculate the authority without a port on ssl' do
36
+ req = make_request(Rack::MockRequest.env_for("https://example.com/"))
37
+ assert_equal "example.com:443", req.authority
38
+ end
39
+
40
+ it 'yields to the block if no value has been set' do
41
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
42
+ yielded = false
43
+ req.fetch_header("FOO") do
44
+ yielded = true
45
+ req.set_header "FOO", 'bar'
46
+ end
47
+
48
+ assert yielded
49
+ assert_equal "bar", req.get_header("FOO")
50
+ end
51
+
52
+ it 'can iterate over values' do
53
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
54
+ req.set_header 'foo', 'bar'
55
+ hash = {}
56
+ req.each_header do |k,v|
57
+ hash[k] = v
58
+ end
59
+ assert_equal 'bar', hash['foo']
60
+ end
61
+
62
+ it 'can set values in the env' do
63
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
64
+ req.set_header("FOO", "BAR")
65
+ assert_equal "BAR", req.get_header("FOO")
66
+ end
67
+
68
+ it 'can add to multivalued headers in the env' do
69
+ req = make_request(Rack::MockRequest.env_for('http://example.com:8080/'))
70
+
71
+ assert_equal '1', req.add_header('FOO', '1')
72
+ assert_equal '1', req.get_header('FOO')
73
+
74
+ assert_equal '1,2', req.add_header('FOO', '2')
75
+ assert_equal '1,2', req.get_header('FOO')
76
+
77
+ assert_equal '1,2', req.add_header('FOO', nil)
78
+ assert_equal '1,2', req.get_header('FOO')
79
+ end
80
+
81
+ it 'can delete env values' do
82
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
83
+ req.set_header 'foo', 'bar'
84
+ assert req.has_header? 'foo'
85
+ req.delete_header 'foo'
86
+ refute req.has_header? 'foo'
87
+ end
88
+
89
+ it "wrap the rack variables" do
90
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
10
91
 
11
- req.body.should.respond_to? :gets
12
- req.scheme.should.equal "http"
13
- req.request_method.should.equal "GET"
92
+ req.body.must_respond_to :gets
93
+ req.scheme.must_equal "http"
94
+ req.request_method.must_equal "GET"
14
95
 
15
- req.should.be.get
16
- req.should.not.be.post
17
- req.should.not.be.put
18
- req.should.not.be.delete
19
- req.should.not.be.head
20
- req.should.not.be.patch
96
+ req.must_be :get?
97
+ req.wont_be :post?
98
+ req.wont_be :put?
99
+ req.wont_be :delete?
100
+ req.wont_be :head?
101
+ req.wont_be :patch?
21
102
 
22
- req.script_name.should.equal ""
23
- req.path_info.should.equal "/"
24
- req.query_string.should.equal ""
103
+ req.script_name.must_equal ""
104
+ req.path_info.must_equal "/"
105
+ req.query_string.must_equal ""
25
106
 
26
- req.host.should.equal "example.com"
27
- req.port.should.equal 8080
107
+ req.host.must_equal "example.com"
108
+ req.port.must_equal 8080
28
109
 
29
- req.content_length.should.equal "0"
30
- req.content_type.should.be.nil
110
+ req.content_length.must_equal "0"
111
+ req.content_type.must_be_nil
31
112
  end
32
113
 
33
- should "figure out the correct host" do
34
- req = Rack::Request.new \
114
+ it "figure out the correct host" do
115
+ req = make_request \
35
116
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org")
36
- req.host.should.equal "www2.example.org"
117
+ req.host.must_equal "www2.example.org"
37
118
 
38
- req = Rack::Request.new \
119
+ req = make_request \
39
120
  Rack::MockRequest.env_for("/", "SERVER_NAME" => "example.org", "SERVER_PORT" => "9292")
40
- req.host.should.equal "example.org"
121
+ req.host.must_equal "example.org"
41
122
 
42
- req = Rack::Request.new \
123
+ req = make_request \
43
124
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org:9292")
44
- req.host.should.equal "example.org"
125
+ req.host.must_equal "example.org"
45
126
 
46
127
  env = Rack::MockRequest.env_for("/", "SERVER_ADDR" => "192.168.1.1", "SERVER_PORT" => "9292")
47
128
  env.delete("SERVER_NAME")
48
- req = Rack::Request.new(env)
49
- req.host.should.equal "192.168.1.1"
129
+ req = make_request(env)
130
+ req.host.must_equal "192.168.1.1"
50
131
 
51
132
  env = Rack::MockRequest.env_for("/")
52
133
  env.delete("SERVER_NAME")
53
- req = Rack::Request.new(env)
54
- req.host.should.equal ""
134
+ req = make_request(env)
135
+ req.host.must_equal ""
55
136
  end
56
137
 
57
- should "figure out the correct port" do
58
- req = Rack::Request.new \
138
+ it "figure out the correct port" do
139
+ req = make_request \
59
140
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org")
60
- req.port.should.equal 80
141
+ req.port.must_equal 80
61
142
 
62
- req = Rack::Request.new \
143
+ req = make_request \
63
144
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org:81")
64
- req.port.should.equal 81
145
+ req.port.must_equal 81
65
146
 
66
- req = Rack::Request.new \
147
+ req = make_request \
67
148
  Rack::MockRequest.env_for("/", "SERVER_NAME" => "example.org", "SERVER_PORT" => "9292")
68
- req.port.should.equal 9292
149
+ req.port.must_equal 9292
69
150
 
70
- req = Rack::Request.new \
151
+ req = make_request \
71
152
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org:9292")
72
- req.port.should.equal 9292
153
+ req.port.must_equal 9292
73
154
 
74
- req = Rack::Request.new \
155
+ req = make_request \
75
156
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org")
76
- req.port.should.equal 80
157
+ req.port.must_equal 80
77
158
 
78
- req = Rack::Request.new \
159
+ req = make_request \
79
160
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org", "HTTP_X_FORWARDED_SSL" => "on")
80
- req.port.should.equal 443
161
+ req.port.must_equal 443
81
162
 
82
- req = Rack::Request.new \
163
+ req = make_request \
83
164
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org", "HTTP_X_FORWARDED_PROTO" => "https")
84
- req.port.should.equal 443
165
+ req.port.must_equal 443
85
166
 
86
- req = Rack::Request.new \
167
+ req = make_request \
87
168
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org", "HTTP_X_FORWARDED_PORT" => "9393")
88
- req.port.should.equal 9393
169
+ req.port.must_equal 9393
89
170
 
90
- req = Rack::Request.new \
171
+ req = make_request \
91
172
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org:9393", "SERVER_PORT" => "80")
92
- req.port.should.equal 9393
173
+ req.port.must_equal 9393
93
174
 
94
- req = Rack::Request.new \
175
+ req = make_request \
95
176
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org", "SERVER_PORT" => "9393")
96
- req.port.should.equal 80
177
+ req.port.must_equal 80
97
178
 
98
- req = Rack::Request.new \
179
+ req = make_request \
99
180
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost", "HTTP_X_FORWARDED_PROTO" => "https", "SERVER_PORT" => "80")
100
- req.port.should.equal 443
181
+ req.port.must_equal 443
101
182
 
102
- req = Rack::Request.new \
183
+ req = make_request \
103
184
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost", "HTTP_X_FORWARDED_PROTO" => "https,https", "SERVER_PORT" => "80")
104
- req.port.should.equal 443
185
+ req.port.must_equal 443
105
186
  end
106
187
 
107
- should "figure out the correct host with port" do
108
- req = Rack::Request.new \
188
+ it "figure out the correct host with port" do
189
+ req = make_request \
109
190
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org")
110
- req.host_with_port.should.equal "www2.example.org"
191
+ req.host_with_port.must_equal "www2.example.org"
111
192
 
112
- req = Rack::Request.new \
193
+ req = make_request \
113
194
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81")
114
- req.host_with_port.should.equal "localhost:81"
195
+ req.host_with_port.must_equal "localhost:81"
115
196
 
116
- req = Rack::Request.new \
197
+ req = make_request \
117
198
  Rack::MockRequest.env_for("/", "SERVER_NAME" => "example.org", "SERVER_PORT" => "9292")
118
- req.host_with_port.should.equal "example.org:9292"
199
+ req.host_with_port.must_equal "example.org:9292"
119
200
 
120
- req = Rack::Request.new \
201
+ req = make_request \
121
202
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org:9292")
122
- req.host_with_port.should.equal "example.org:9292"
203
+ req.host_with_port.must_equal "example.org:9292"
123
204
 
124
- req = Rack::Request.new \
205
+ req = make_request \
125
206
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org", "SERVER_PORT" => "9393")
126
- req.host_with_port.should.equal "example.org"
207
+ req.host_with_port.must_equal "example.org"
127
208
  end
128
209
 
129
- should "parse the query string" do
130
- req = Rack::Request.new(Rack::MockRequest.env_for("/?foo=bar&quux=bla"))
131
- req.query_string.should.equal "foo=bar&quux=bla"
132
- req.GET.should.equal "foo" => "bar", "quux" => "bla"
133
- req.POST.should.be.empty
134
- req.params.should.equal "foo" => "bar", "quux" => "bla"
210
+ it "parse the query string" do
211
+ req = make_request(Rack::MockRequest.env_for("/?foo=bar&quux=bla"))
212
+ req.query_string.must_equal "foo=bar&quux=bla"
213
+ req.GET.must_equal "foo" => "bar", "quux" => "bla"
214
+ req.POST.must_be :empty?
215
+ req.params.must_equal "foo" => "bar", "quux" => "bla"
135
216
  end
136
217
 
137
- should "not truncate query strings containing semi-colons #543 only in POST" do
218
+ it "not truncate query strings containing semi-colons #543 only in POST" do
138
219
  mr = Rack::MockRequest.env_for("/",
139
220
  "REQUEST_METHOD" => 'POST',
140
221
  :input => "foo=bar&quux=b;la")
141
- req = Rack::Request.new mr
142
- req.query_string.should.equal ""
143
- req.GET.should.be.empty
144
- req.POST.should.equal "foo" => "bar", "quux" => "b;la"
145
- req.params.should.equal req.GET.merge(req.POST)
222
+ req = make_request mr
223
+ req.query_string.must_equal ""
224
+ req.GET.must_be :empty?
225
+ req.POST.must_equal "foo" => "bar", "quux" => "b;la"
226
+ req.params.must_equal req.GET.merge(req.POST)
227
+ end
228
+
229
+ it "should use the query_parser for query parsing" do
230
+ c = Class.new(Rack::QueryParser::Params) do
231
+ def initialize(*)
232
+ super
233
+ @params = Hash.new{|h,k| h[k.to_s] if k.is_a?(Symbol)}
234
+ end
235
+ end
236
+ parser = Rack::QueryParser.new(c, 65536, 100)
237
+ c = Class.new(Rack::Request) do
238
+ define_method(:query_parser) do
239
+ parser
240
+ end
241
+ end
242
+ req = c.new(Rack::MockRequest.env_for("/?foo=bar&quux=bla"))
243
+ req.GET[:foo].must_equal "bar"
244
+ req.GET[:quux].must_equal "bla"
245
+ req.params[:foo].must_equal "bar"
246
+ req.params[:quux].must_equal "bla"
146
247
  end
147
248
 
148
- should "use semi-colons as separators for query strings in GET" do
149
- req = Rack::Request.new(Rack::MockRequest.env_for("/?foo=bar&quux=b;la;wun=duh"))
150
- req.query_string.should.equal "foo=bar&quux=b;la;wun=duh"
151
- req.GET.should.equal "foo" => "bar", "quux" => "b", "la" => nil, "wun" => "duh"
152
- req.POST.should.be.empty
153
- req.params.should.equal "foo" => "bar", "quux" => "b", "la" => nil, "wun" => "duh"
249
+ it "use semi-colons as separators for query strings in GET" do
250
+ req = make_request(Rack::MockRequest.env_for("/?foo=bar&quux=b;la;wun=duh"))
251
+ req.query_string.must_equal "foo=bar&quux=b;la;wun=duh"
252
+ req.GET.must_equal "foo" => "bar", "quux" => "b", "la" => nil, "wun" => "duh"
253
+ req.POST.must_be :empty?
254
+ req.params.must_equal "foo" => "bar", "quux" => "b", "la" => nil, "wun" => "duh"
154
255
  end
155
256
 
156
- should "limit the keys from the GET query string" do
257
+ it "limit the keys from the GET query string" do
157
258
  env = Rack::MockRequest.env_for("/?foo=bar")
158
259
 
159
260
  old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
160
261
  begin
161
- req = Rack::Request.new(env)
162
- lambda { req.GET }.should.raise(RangeError)
262
+ req = make_request(env)
263
+ lambda { req.GET }.must_raise RangeError
163
264
  ensure
164
265
  Rack::Utils.key_space_limit = old
165
266
  end
166
267
  end
167
268
 
168
- should "limit the key size per nested params hash" do
269
+ it "limit the key size per nested params hash" do
169
270
  nested_query = Rack::MockRequest.env_for("/?foo%5Bbar%5D%5Bbaz%5D%5Bqux%5D=1")
170
271
  plain_query = Rack::MockRequest.env_for("/?foo_bar__baz__qux_=1")
171
272
 
172
273
  old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 3
173
274
  begin
174
- lambda { Rack::Request.new(nested_query).GET }.should.not.raise(RangeError)
175
- lambda { Rack::Request.new(plain_query).GET }.should.raise(RangeError)
275
+ exp = {"foo"=>{"bar"=>{"baz"=>{"qux"=>"1"}}}}
276
+ make_request(nested_query).GET.must_equal exp
277
+ lambda { make_request(plain_query).GET }.must_raise RangeError
176
278
  ensure
177
279
  Rack::Utils.key_space_limit = old
178
280
  end
179
281
  end
180
282
 
181
- should "not unify GET and POST when calling params" do
283
+ it "not unify GET and POST when calling params" do
182
284
  mr = Rack::MockRequest.env_for("/?foo=quux",
183
285
  "REQUEST_METHOD" => 'POST',
184
286
  :input => "foo=bar&quux=bla"
185
287
  )
186
- req = Rack::Request.new mr
288
+ req = make_request mr
187
289
 
188
290
  req.params
189
291
 
190
- req.GET.should.equal "foo" => "quux"
191
- req.POST.should.equal "foo" => "bar", "quux" => "bla"
192
- req.params.should.equal req.GET.merge(req.POST)
292
+ req.GET.must_equal "foo" => "quux"
293
+ req.POST.must_equal "foo" => "bar", "quux" => "bla"
294
+ req.params.must_equal req.GET.merge(req.POST)
193
295
  end
194
296
 
195
- should "raise if input params has invalid %-encoding" do
297
+ it "use the query_parser's params_class for multipart params" do
298
+ c = Class.new(Rack::QueryParser::Params) do
299
+ def initialize(*)
300
+ super
301
+ @params = Hash.new{|h,k| h[k.to_s] if k.is_a?(Symbol)}
302
+ end
303
+ end
304
+ parser = Rack::QueryParser.new(c, 65536, 100)
305
+ c = Class.new(Rack::Request) do
306
+ define_method(:query_parser) do
307
+ parser
308
+ end
309
+ end
310
+ mr = Rack::MockRequest.env_for("/?foo=quux",
311
+ "REQUEST_METHOD" => 'POST',
312
+ :input => "foo=bar&quux=bla"
313
+ )
314
+ req = c.new mr
315
+
316
+ req.params
317
+
318
+ req.GET[:foo].must_equal "quux"
319
+ req.POST[:foo].must_equal "bar"
320
+ req.POST[:quux].must_equal "bla"
321
+ req.params[:foo].must_equal "bar"
322
+ req.params[:quux].must_equal "bla"
323
+ end
324
+
325
+ it "raise if input params has invalid %-encoding" do
196
326
  mr = Rack::MockRequest.env_for("/?foo=quux",
197
327
  "REQUEST_METHOD" => 'POST',
198
328
  :input => "a%=1"
199
329
  )
200
- req = Rack::Request.new mr
330
+ req = make_request mr
201
331
 
202
- lambda { req.POST }.
203
- should.raise(Rack::Utils::InvalidParameterError).
204
- message.should.equal "invalid %-encoding (a%)"
332
+ lambda { req.POST }.must_raise(Rack::Utils::InvalidParameterError).
333
+ message.must_equal "invalid %-encoding (a%)"
205
334
  end
206
335
 
207
- should "raise if rack.input is missing" do
208
- req = Rack::Request.new({})
209
- lambda { req.POST }.should.raise(RuntimeError)
336
+ it "raise if rack.input is missing" do
337
+ req = make_request({})
338
+ lambda { req.POST }.must_raise RuntimeError
210
339
  end
211
340
 
212
- should "parse POST data when method is POST and no Content-Type given" do
213
- req = Rack::Request.new \
341
+ it "parse POST data when method is POST and no Content-Type given" do
342
+ req = make_request \
214
343
  Rack::MockRequest.env_for("/?foo=quux",
215
344
  "REQUEST_METHOD" => 'POST',
216
345
  :input => "foo=bar&quux=bla")
217
- req.content_type.should.be.nil
218
- req.media_type.should.be.nil
219
- req.query_string.should.equal "foo=quux"
220
- req.GET.should.equal "foo" => "quux"
221
- req.POST.should.equal "foo" => "bar", "quux" => "bla"
222
- req.params.should.equal "foo" => "bar", "quux" => "bla"
346
+ req.content_type.must_be_nil
347
+ req.media_type.must_be_nil
348
+ req.query_string.must_equal "foo=quux"
349
+ req.GET.must_equal "foo" => "quux"
350
+ req.POST.must_equal "foo" => "bar", "quux" => "bla"
351
+ req.params.must_equal "foo" => "bar", "quux" => "bla"
223
352
  end
224
353
 
225
- should "limit the keys from the POST form data" do
354
+ it "limit the keys from the POST form data" do
226
355
  env = Rack::MockRequest.env_for("",
227
356
  "REQUEST_METHOD" => 'POST',
228
357
  :input => "foo=bar&quux=bla")
229
358
 
230
359
  old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
231
360
  begin
232
- req = Rack::Request.new(env)
233
- lambda { req.POST }.should.raise(RangeError)
361
+ req = make_request(env)
362
+ lambda { req.POST }.must_raise RangeError
234
363
  ensure
235
364
  Rack::Utils.key_space_limit = old
236
365
  end
237
366
  end
238
367
 
239
- should "parse POST data with explicit content type regardless of method" do
240
- req = Rack::Request.new \
368
+ it "parse POST data with explicit content type regardless of method" do
369
+ req = make_request \
241
370
  Rack::MockRequest.env_for("/",
242
371
  "CONTENT_TYPE" => 'application/x-www-form-urlencoded;foo=bar',
243
372
  :input => "foo=bar&quux=bla")
244
- req.content_type.should.equal 'application/x-www-form-urlencoded;foo=bar'
245
- req.media_type.should.equal 'application/x-www-form-urlencoded'
246
- req.media_type_params['foo'].should.equal 'bar'
247
- req.POST.should.equal "foo" => "bar", "quux" => "bla"
248
- req.params.should.equal "foo" => "bar", "quux" => "bla"
373
+ req.content_type.must_equal 'application/x-www-form-urlencoded;foo=bar'
374
+ req.media_type.must_equal 'application/x-www-form-urlencoded'
375
+ req.media_type_params['foo'].must_equal 'bar'
376
+ req.POST.must_equal "foo" => "bar", "quux" => "bla"
377
+ req.params.must_equal "foo" => "bar", "quux" => "bla"
249
378
  end
250
379
 
251
- should "not parse POST data when media type is not form-data" do
252
- req = Rack::Request.new \
380
+ it "not parse POST data when media type is not form-data" do
381
+ req = make_request \
253
382
  Rack::MockRequest.env_for("/?foo=quux",
254
383
  "REQUEST_METHOD" => 'POST',
255
384
  "CONTENT_TYPE" => 'text/plain;charset=utf-8',
256
385
  :input => "foo=bar&quux=bla")
257
- req.content_type.should.equal 'text/plain;charset=utf-8'
258
- req.media_type.should.equal 'text/plain'
259
- req.media_type_params['charset'].should.equal 'utf-8'
260
- req.POST.should.be.empty
261
- req.params.should.equal "foo" => "quux"
262
- req.body.read.should.equal "foo=bar&quux=bla"
386
+ req.content_type.must_equal 'text/plain;charset=utf-8'
387
+ req.media_type.must_equal 'text/plain'
388
+ req.media_type_params['charset'].must_equal 'utf-8'
389
+ req.POST.must_be :empty?
390
+ req.params.must_equal "foo" => "quux"
391
+ req.body.read.must_equal "foo=bar&quux=bla"
263
392
  end
264
393
 
265
- should "parse POST data on PUT when media type is form-data" do
266
- req = Rack::Request.new \
394
+ it "parse POST data on PUT when media type is form-data" do
395
+ req = make_request \
267
396
  Rack::MockRequest.env_for("/?foo=quux",
268
397
  "REQUEST_METHOD" => 'PUT',
269
398
  "CONTENT_TYPE" => 'application/x-www-form-urlencoded',
270
399
  :input => "foo=bar&quux=bla")
271
- req.POST.should.equal "foo" => "bar", "quux" => "bla"
272
- req.body.read.should.equal "foo=bar&quux=bla"
400
+ req.POST.must_equal "foo" => "bar", "quux" => "bla"
401
+ req.body.read.must_equal "foo=bar&quux=bla"
273
402
  end
274
403
 
275
- should "rewind input after parsing POST data" do
404
+ it "rewind input after parsing POST data" do
276
405
  input = StringIO.new("foo=bar&quux=bla")
277
- req = Rack::Request.new \
406
+ req = make_request \
278
407
  Rack::MockRequest.env_for("/",
279
408
  "CONTENT_TYPE" => 'application/x-www-form-urlencoded;foo=bar',
280
409
  :input => input)
281
- req.params.should.equal "foo" => "bar", "quux" => "bla"
282
- input.read.should.equal "foo=bar&quux=bla"
410
+ req.params.must_equal "foo" => "bar", "quux" => "bla"
411
+ input.read.must_equal "foo=bar&quux=bla"
283
412
  end
284
413
 
285
- should "clean up Safari's ajax POST body" do
286
- req = Rack::Request.new \
414
+ it "safely accepts POST requests with empty body" do
415
+ mr = Rack::MockRequest.env_for("/",
416
+ "REQUEST_METHOD" => "POST",
417
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
418
+ "CONTENT_LENGTH" => '0',
419
+ :input => nil)
420
+
421
+ req = make_request mr
422
+ req.query_string.must_equal ""
423
+ req.GET.must_be :empty?
424
+ req.POST.must_be :empty?
425
+ req.params.must_equal({})
426
+ end
427
+
428
+ it "clean up Safari's ajax POST body" do
429
+ req = make_request \
287
430
  Rack::MockRequest.env_for("/",
288
431
  'REQUEST_METHOD' => 'POST', :input => "foo=bar&quux=bla\0")
289
- req.POST.should.equal "foo" => "bar", "quux" => "bla"
432
+ req.POST.must_equal "foo" => "bar", "quux" => "bla"
290
433
  end
291
434
 
292
- should "get value by key from params with #[]" do
293
- req = Rack::Request.new \
435
+ it "get value by key from params with #[]" do
436
+ req = make_request \
294
437
  Rack::MockRequest.env_for("?foo=quux")
295
- req['foo'].should.equal 'quux'
296
- req[:foo].should.equal 'quux'
438
+ req['foo'].must_equal 'quux'
439
+ req[:foo].must_equal 'quux'
297
440
  end
298
441
 
299
- should "set value to key on params with #[]=" do
300
- req = Rack::Request.new \
442
+ it "set value to key on params with #[]=" do
443
+ req = make_request \
301
444
  Rack::MockRequest.env_for("?foo=duh")
302
- req['foo'].should.equal 'duh'
303
- req[:foo].should.equal 'duh'
304
- req.params.should.equal 'foo' => 'duh'
445
+ req['foo'].must_equal 'duh'
446
+ req[:foo].must_equal 'duh'
447
+ req.params.must_equal 'foo' => 'duh'
448
+
449
+ if req.delegate?
450
+ skip "delegate requests don't cache params, so mutations have no impact"
451
+ end
305
452
 
306
453
  req['foo'] = 'bar'
307
- req.params.should.equal 'foo' => 'bar'
308
- req['foo'].should.equal 'bar'
309
- req[:foo].should.equal 'bar'
454
+ req.params.must_equal 'foo' => 'bar'
455
+ req['foo'].must_equal 'bar'
456
+ req[:foo].must_equal 'bar'
310
457
 
311
458
  req[:foo] = 'jaz'
312
- req.params.should.equal 'foo' => 'jaz'
313
- req['foo'].should.equal 'jaz'
314
- req[:foo].should.equal 'jaz'
459
+ req.params.must_equal 'foo' => 'jaz'
460
+ req['foo'].must_equal 'jaz'
461
+ req[:foo].must_equal 'jaz'
315
462
  end
316
463
 
317
- should "return values for the keys in the order given from values_at" do
318
- req = Rack::Request.new \
464
+ it "return values for the keys in the order given from values_at" do
465
+ req = make_request \
319
466
  Rack::MockRequest.env_for("?foo=baz&wun=der&bar=ful")
320
- req.values_at('foo').should.equal ['baz']
321
- req.values_at('foo', 'wun').should.equal ['baz', 'der']
322
- req.values_at('bar', 'foo', 'wun').should.equal ['ful', 'baz', 'der']
467
+ req.values_at('foo').must_equal ['baz']
468
+ req.values_at('foo', 'wun').must_equal ['baz', 'der']
469
+ req.values_at('bar', 'foo', 'wun').must_equal ['ful', 'baz', 'der']
323
470
  end
324
471
 
325
- should "extract referrer correctly" do
326
- req = Rack::Request.new \
472
+ it "extract referrer correctly" do
473
+ req = make_request \
327
474
  Rack::MockRequest.env_for("/", "HTTP_REFERER" => "/some/path")
328
- req.referer.should.equal "/some/path"
475
+ req.referer.must_equal "/some/path"
329
476
 
330
- req = Rack::Request.new \
477
+ req = make_request \
331
478
  Rack::MockRequest.env_for("/")
332
- req.referer.should.equal nil
479
+ req.referer.must_be_nil
333
480
  end
334
481
 
335
- should "extract user agent correctly" do
336
- req = Rack::Request.new \
482
+ it "extract user agent correctly" do
483
+ req = make_request \
337
484
  Rack::MockRequest.env_for("/", "HTTP_USER_AGENT" => "Mozilla/4.0 (compatible)")
338
- req.user_agent.should.equal "Mozilla/4.0 (compatible)"
485
+ req.user_agent.must_equal "Mozilla/4.0 (compatible)"
339
486
 
340
- req = Rack::Request.new \
487
+ req = make_request \
341
488
  Rack::MockRequest.env_for("/")
342
- req.user_agent.should.equal nil
489
+ req.user_agent.must_be_nil
343
490
  end
344
491
 
345
- should "treat missing content type as nil" do
346
- req = Rack::Request.new \
492
+ it "treat missing content type as nil" do
493
+ req = make_request \
347
494
  Rack::MockRequest.env_for("/")
348
- req.content_type.should.equal nil
495
+ req.content_type.must_be_nil
349
496
  end
350
497
 
351
- should "treat empty content type as nil" do
352
- req = Rack::Request.new \
498
+ it "treat empty content type as nil" do
499
+ req = make_request \
353
500
  Rack::MockRequest.env_for("/", "CONTENT_TYPE" => "")
354
- req.content_type.should.equal nil
501
+ req.content_type.must_be_nil
355
502
  end
356
503
 
357
- should "return nil media type for empty content type" do
358
- req = Rack::Request.new \
504
+ it "return nil media type for empty content type" do
505
+ req = make_request \
359
506
  Rack::MockRequest.env_for("/", "CONTENT_TYPE" => "")
360
- req.media_type.should.equal nil
507
+ req.media_type.must_be_nil
361
508
  end
362
509
 
363
- should "cache, but invalidates the cache" do
364
- req = Rack::Request.new \
510
+ it "cache, but invalidates the cache" do
511
+ req = make_request \
365
512
  Rack::MockRequest.env_for("/?foo=quux",
366
513
  "CONTENT_TYPE" => "application/x-www-form-urlencoded",
367
514
  :input => "foo=bar&quux=bla")
368
- req.GET.should.equal "foo" => "quux"
369
- req.GET.should.equal "foo" => "quux"
370
- req.env["QUERY_STRING"] = "bla=foo"
371
- req.GET.should.equal "bla" => "foo"
372
- req.GET.should.equal "bla" => "foo"
515
+ req.GET.must_equal "foo" => "quux"
516
+ req.GET.must_equal "foo" => "quux"
517
+ req.set_header("QUERY_STRING", "bla=foo")
518
+ req.GET.must_equal "bla" => "foo"
519
+ req.GET.must_equal "bla" => "foo"
373
520
 
374
- req.POST.should.equal "foo" => "bar", "quux" => "bla"
375
- req.POST.should.equal "foo" => "bar", "quux" => "bla"
376
- req.env["rack.input"] = StringIO.new("foo=bla&quux=bar")
377
- req.POST.should.equal "foo" => "bla", "quux" => "bar"
378
- req.POST.should.equal "foo" => "bla", "quux" => "bar"
521
+ req.POST.must_equal "foo" => "bar", "quux" => "bla"
522
+ req.POST.must_equal "foo" => "bar", "quux" => "bla"
523
+ req.set_header("rack.input", StringIO.new("foo=bla&quux=bar"))
524
+ req.POST.must_equal "foo" => "bla", "quux" => "bar"
525
+ req.POST.must_equal "foo" => "bla", "quux" => "bar"
379
526
  end
380
527
 
381
- should "figure out if called via XHR" do
382
- req = Rack::Request.new(Rack::MockRequest.env_for(""))
383
- req.should.not.be.xhr
528
+ it "figure out if called via XHR" do
529
+ req = make_request(Rack::MockRequest.env_for(""))
530
+ req.wont_be :xhr?
384
531
 
385
- req = Rack::Request.new \
532
+ req = make_request \
386
533
  Rack::MockRequest.env_for("", "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest")
387
- req.should.be.xhr
534
+ req.must_be :xhr?
388
535
  end
389
536
 
390
- should "ssl detection" do
391
- request = Rack::Request.new(Rack::MockRequest.env_for("/"))
392
- request.scheme.should.equal "http"
393
- request.should.not.be.ssl?
537
+ it "ssl detection" do
538
+ request = make_request(Rack::MockRequest.env_for("/"))
539
+ request.scheme.must_equal "http"
540
+ request.wont_be :ssl?
394
541
 
395
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTPS' => 'on'))
396
- request.scheme.should.equal "https"
397
- request.should.be.ssl?
542
+ request = make_request(Rack::MockRequest.env_for("/", 'HTTPS' => 'on'))
543
+ request.scheme.must_equal "https"
544
+ request.must_be :ssl?
398
545
 
399
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'rack.url_scheme' => 'https'))
400
- request.scheme.should.equal "https"
401
- request.should.be.ssl?
546
+ request = make_request(Rack::MockRequest.env_for("/", 'rack.url_scheme' => 'https'))
547
+ request.scheme.must_equal "https"
548
+ request.must_be :ssl?
402
549
 
403
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_HOST' => 'www.example.org:8080'))
404
- request.scheme.should.equal "http"
405
- request.should.not.be.ssl?
550
+ request = make_request(Rack::MockRequest.env_for("/", 'HTTP_HOST' => 'www.example.org:8080'))
551
+ request.scheme.must_equal "http"
552
+ request.wont_be :ssl?
406
553
 
407
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_HOST' => 'www.example.org:8443', 'HTTPS' => 'on'))
408
- request.scheme.should.equal "https"
409
- request.should.be.ssl?
554
+ request = make_request(Rack::MockRequest.env_for("/", 'HTTP_HOST' => 'www.example.org:8443', 'HTTPS' => 'on'))
555
+ request.scheme.must_equal "https"
556
+ request.must_be :ssl?
410
557
 
411
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_HOST' => 'www.example.org:8443', 'HTTP_X_FORWARDED_SSL' => 'on'))
412
- request.scheme.should.equal "https"
413
- request.should.be.ssl?
558
+ request = make_request(Rack::MockRequest.env_for("/", 'HTTP_HOST' => 'www.example.org:8443', 'HTTP_X_FORWARDED_SSL' => 'on'))
559
+ request.scheme.must_equal "https"
560
+ request.must_be :ssl?
414
561
 
415
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_SCHEME' => 'https'))
416
- request.scheme.should.equal "https"
417
- request.should.be.ssl?
562
+ request = make_request(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_SCHEME' => 'https'))
563
+ request.scheme.must_equal "https"
564
+ request.must_be :ssl?
418
565
 
419
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_PROTO' => 'https'))
420
- request.scheme.should.equal "https"
421
- request.should.be.ssl?
566
+ request = make_request(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_PROTO' => 'https'))
567
+ request.scheme.must_equal "https"
568
+ request.must_be :ssl?
422
569
 
423
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_PROTO' => 'https, http, http'))
424
- request.scheme.should.equal "https"
425
- request.should.be.ssl?
570
+ request = make_request(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_PROTO' => 'https, http, http'))
571
+ request.scheme.must_equal "https"
572
+ request.must_be :ssl?
426
573
  end
427
574
 
428
- should "prevent scheme abuse" do
429
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_SCHEME' => 'a."><script>alert(1)</script>'))
430
- request.scheme.should.not.equal 'a."><script>alert(1)</script>'
575
+ it "prevents scheme abuse" do
576
+ request = make_request(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_SCHEME' => 'a."><script>alert(1)</script>'))
577
+ request.scheme.must_equal 'http'
431
578
  end
432
579
 
433
- should "parse cookies" do
434
- req = Rack::Request.new \
580
+ it "parse cookies" do
581
+ req = make_request \
435
582
  Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m")
436
- req.cookies.should.equal "foo" => "bar", "quux" => "h&m"
437
- req.cookies.should.equal "foo" => "bar", "quux" => "h&m"
438
- req.env.delete("HTTP_COOKIE")
439
- req.cookies.should.equal({})
583
+ req.cookies.must_equal "foo" => "bar", "quux" => "h&m"
584
+ req.cookies.must_equal "foo" => "bar", "quux" => "h&m"
585
+ req.delete_header("HTTP_COOKIE")
586
+ req.cookies.must_equal({})
440
587
  end
441
588
 
442
- should "always return the same hash object" do
443
- req = Rack::Request.new \
589
+ it "always return the same hash object" do
590
+ req = make_request \
444
591
  Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m")
445
592
  hash = req.cookies
446
593
  req.env.delete("HTTP_COOKIE")
447
- req.cookies.should.equal(hash)
594
+ req.cookies.must_equal hash
448
595
  req.env["HTTP_COOKIE"] = "zoo=m"
449
- req.cookies.should.equal(hash)
596
+ req.cookies.must_equal hash
450
597
  end
451
598
 
452
- should "modify the cookies hash in place" do
453
- req = Rack::Request.new(Rack::MockRequest.env_for(""))
454
- req.cookies.should.equal({})
599
+ it "modify the cookies hash in place" do
600
+ req = make_request(Rack::MockRequest.env_for(""))
601
+ req.cookies.must_equal({})
455
602
  req.cookies['foo'] = 'bar'
456
- req.cookies.should.equal 'foo' => 'bar'
603
+ req.cookies.must_equal 'foo' => 'bar'
457
604
  end
458
605
 
459
- should "not modify the params hash in place" do
606
+ it "not modify the params hash in place" do
460
607
  e = Rack::MockRequest.env_for("")
461
- req1 = Rack::Request.new(e)
462
- req1.params.should.equal({})
608
+ req1 = make_request(e)
609
+ if req1.delegate?
610
+ skip "delegate requests don't cache params, so mutations have no impact"
611
+ end
612
+ req1.params.must_equal({})
463
613
  req1.params['foo'] = 'bar'
464
- req1.params.should.equal 'foo' => 'bar'
465
- req2 = Rack::Request.new(e)
466
- req2.params.should.equal({})
614
+ req1.params.must_equal 'foo' => 'bar'
615
+ req2 = make_request(e)
616
+ req2.params.must_equal({})
467
617
  end
468
618
 
469
- should "modify params hash if param is in GET" do
619
+ it "modify params hash if param is in GET" do
470
620
  e = Rack::MockRequest.env_for("?foo=duh")
471
- req1 = Rack::Request.new(e)
472
- req1.params.should.equal 'foo' => 'duh'
621
+ req1 = make_request(e)
622
+ req1.params.must_equal 'foo' => 'duh'
473
623
  req1.update_param 'foo', 'bar'
474
- req1.params.should.equal 'foo' => 'bar'
475
- req2 = Rack::Request.new(e)
476
- req2.params.should.equal 'foo' => 'bar'
624
+ req1.params.must_equal 'foo' => 'bar'
625
+ req2 = make_request(e)
626
+ req2.params.must_equal 'foo' => 'bar'
477
627
  end
478
628
 
479
- should "modify params hash if param is in POST" do
629
+ it "modify params hash if param is in POST" do
480
630
  e = Rack::MockRequest.env_for("", "REQUEST_METHOD" => 'POST', :input => 'foo=duh')
481
- req1 = Rack::Request.new(e)
482
- req1.params.should.equal 'foo' => 'duh'
631
+ req1 = make_request(e)
632
+ req1.params.must_equal 'foo' => 'duh'
483
633
  req1.update_param 'foo', 'bar'
484
- req1.params.should.equal 'foo' => 'bar'
485
- req2 = Rack::Request.new(e)
486
- req2.params.should.equal 'foo' => 'bar'
634
+ req1.params.must_equal 'foo' => 'bar'
635
+ req2 = make_request(e)
636
+ req2.params.must_equal 'foo' => 'bar'
487
637
  end
488
638
 
489
- should "modify params hash, even if param didn't exist before" do
639
+ it "modify params hash, even if param didn't exist before" do
490
640
  e = Rack::MockRequest.env_for("")
491
- req1 = Rack::Request.new(e)
492
- req1.params.should.equal({})
641
+ req1 = make_request(e)
642
+ req1.params.must_equal({})
493
643
  req1.update_param 'foo', 'bar'
494
- req1.params.should.equal 'foo' => 'bar'
495
- req2 = Rack::Request.new(e)
496
- req2.params.should.equal 'foo' => 'bar'
644
+ req1.params.must_equal 'foo' => 'bar'
645
+ req2 = make_request(e)
646
+ req2.params.must_equal 'foo' => 'bar'
497
647
  end
498
648
 
499
- should "modify params hash by changing only GET" do
649
+ it "modify params hash by changing only GET" do
500
650
  e = Rack::MockRequest.env_for("?foo=duhget")
501
- req = Rack::Request.new(e)
502
- req.GET.should.equal 'foo' => 'duhget'
503
- req.POST.should.equal({})
651
+ req = make_request(e)
652
+ req.GET.must_equal 'foo' => 'duhget'
653
+ req.POST.must_equal({})
504
654
  req.update_param 'foo', 'bar'
505
- req.GET.should.equal 'foo' => 'bar'
506
- req.POST.should.equal({})
655
+ req.GET.must_equal 'foo' => 'bar'
656
+ req.POST.must_equal({})
507
657
  end
508
658
 
509
- should "modify params hash by changing only POST" do
659
+ it "modify params hash by changing only POST" do
510
660
  e = Rack::MockRequest.env_for("", "REQUEST_METHOD" => 'POST', :input => "foo=duhpost")
511
- req = Rack::Request.new(e)
512
- req.GET.should.equal({})
513
- req.POST.should.equal 'foo' => 'duhpost'
661
+ req = make_request(e)
662
+ req.GET.must_equal({})
663
+ req.POST.must_equal 'foo' => 'duhpost'
514
664
  req.update_param 'foo', 'bar'
515
- req.GET.should.equal({})
516
- req.POST.should.equal 'foo' => 'bar'
665
+ req.GET.must_equal({})
666
+ req.POST.must_equal 'foo' => 'bar'
517
667
  end
518
668
 
519
- should "modify params hash, even if param is defined in both POST and GET" do
669
+ it "modify params hash, even if param is defined in both POST and GET" do
520
670
  e = Rack::MockRequest.env_for("?foo=duhget", "REQUEST_METHOD" => 'POST', :input => "foo=duhpost")
521
- req1 = Rack::Request.new(e)
522
- req1.GET.should.equal 'foo' => 'duhget'
523
- req1.POST.should.equal 'foo' => 'duhpost'
524
- req1.params.should.equal 'foo' => 'duhpost'
671
+ req1 = make_request(e)
672
+ req1.GET.must_equal 'foo' => 'duhget'
673
+ req1.POST.must_equal 'foo' => 'duhpost'
674
+ req1.params.must_equal 'foo' => 'duhpost'
525
675
  req1.update_param 'foo', 'bar'
526
- req1.GET.should.equal 'foo' => 'bar'
527
- req1.POST.should.equal 'foo' => 'bar'
528
- req1.params.should.equal 'foo' => 'bar'
529
- req2 = Rack::Request.new(e)
530
- req2.GET.should.equal 'foo' => 'bar'
531
- req2.POST.should.equal 'foo' => 'bar'
532
- req2.params.should.equal 'foo' => 'bar'
533
- req2.params.should.equal 'foo' => 'bar'
676
+ req1.GET.must_equal 'foo' => 'bar'
677
+ req1.POST.must_equal 'foo' => 'bar'
678
+ req1.params.must_equal 'foo' => 'bar'
679
+ req2 = make_request(e)
680
+ req2.GET.must_equal 'foo' => 'bar'
681
+ req2.POST.must_equal 'foo' => 'bar'
682
+ req2.params.must_equal 'foo' => 'bar'
683
+ req2.params.must_equal 'foo' => 'bar'
534
684
  end
535
685
 
536
- should "allow deleting from params hash if param is in GET" do
686
+ it "allow deleting from params hash if param is in GET" do
537
687
  e = Rack::MockRequest.env_for("?foo=bar")
538
- req1 = Rack::Request.new(e)
539
- req1.params.should.equal 'foo' => 'bar'
540
- req1.delete_param('foo').should.equal 'bar'
541
- req1.params.should.equal({})
542
- req2 = Rack::Request.new(e)
543
- req2.params.should.equal({})
688
+ req1 = make_request(e)
689
+ req1.params.must_equal 'foo' => 'bar'
690
+ req1.delete_param('foo').must_equal 'bar'
691
+ req1.params.must_equal({})
692
+ req2 = make_request(e)
693
+ req2.params.must_equal({})
544
694
  end
545
695
 
546
- should "allow deleting from params hash if param is in POST" do
696
+ it "allow deleting from params hash if param is in POST" do
547
697
  e = Rack::MockRequest.env_for("", "REQUEST_METHOD" => 'POST', :input => 'foo=bar')
548
- req1 = Rack::Request.new(e)
549
- req1.params.should.equal 'foo' => 'bar'
550
- req1.delete_param('foo').should.equal 'bar'
551
- req1.params.should.equal({})
552
- req2 = Rack::Request.new(e)
553
- req2.params.should.equal({})
698
+ req1 = make_request(e)
699
+ req1.params.must_equal 'foo' => 'bar'
700
+ req1.delete_param('foo').must_equal 'bar'
701
+ req1.params.must_equal({})
702
+ req2 = make_request(e)
703
+ req2.params.must_equal({})
554
704
  end
555
705
 
556
- should "pass through non-uri escaped cookies as-is" do
557
- req = Rack::Request.new Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=%")
558
- req.cookies["foo"].should == "%"
706
+ it "pass through non-uri escaped cookies as-is" do
707
+ req = make_request Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=%")
708
+ req.cookies["foo"].must_equal "%"
559
709
  end
560
710
 
561
- should "parse cookies according to RFC 2109" do
562
- req = Rack::Request.new \
711
+ it "parse cookies according to RFC 2109" do
712
+ req = make_request \
563
713
  Rack::MockRequest.env_for('', 'HTTP_COOKIE' => 'foo=bar;foo=car')
564
- req.cookies.should.equal 'foo' => 'bar'
714
+ req.cookies.must_equal 'foo' => 'bar'
565
715
  end
566
716
 
567
- should 'parse cookies with quotes' do
568
- req = Rack::Request.new Rack::MockRequest.env_for('', {
717
+ it 'parse cookies with quotes' do
718
+ req = make_request Rack::MockRequest.env_for('', {
569
719
  'HTTP_COOKIE' => '$Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"; Part_Number="Rocket_Launcher_0001"; $Path="/acme"'
570
720
  })
571
- req.cookies.should.equal({
721
+ req.cookies.must_equal({
572
722
  '$Version' => '"1"',
573
723
  'Customer' => '"WILE_E_COYOTE"',
574
724
  '$Path' => '"/acme"',
@@ -576,88 +726,88 @@ describe Rack::Request do
576
726
  })
577
727
  end
578
728
 
579
- should "provide setters" do
580
- req = Rack::Request.new(e=Rack::MockRequest.env_for(""))
581
- req.script_name.should.equal ""
729
+ it "provide setters" do
730
+ req = make_request(e=Rack::MockRequest.env_for(""))
731
+ req.script_name.must_equal ""
582
732
  req.script_name = "/foo"
583
- req.script_name.should.equal "/foo"
584
- e["SCRIPT_NAME"].should.equal "/foo"
733
+ req.script_name.must_equal "/foo"
734
+ e["SCRIPT_NAME"].must_equal "/foo"
585
735
 
586
- req.path_info.should.equal "/"
736
+ req.path_info.must_equal "/"
587
737
  req.path_info = "/foo"
588
- req.path_info.should.equal "/foo"
589
- e["PATH_INFO"].should.equal "/foo"
590
- end
591
-
592
- should "provide the original env" do
593
- req = Rack::Request.new(e = Rack::MockRequest.env_for(""))
594
- req.env.should == e
595
- end
596
-
597
- should "restore the base URL" do
598
- Rack::Request.new(Rack::MockRequest.env_for("")).base_url.
599
- should.equal "http://example.org"
600
- Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).base_url.
601
- should.equal "http://example.org"
602
- end
603
-
604
- should "restore the URL" do
605
- Rack::Request.new(Rack::MockRequest.env_for("")).url.
606
- should.equal "http://example.org/"
607
- Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).url.
608
- should.equal "http://example.org/foo/"
609
- Rack::Request.new(Rack::MockRequest.env_for("/foo")).url.
610
- should.equal "http://example.org/foo"
611
- Rack::Request.new(Rack::MockRequest.env_for("?foo")).url.
612
- should.equal "http://example.org/?foo"
613
- Rack::Request.new(Rack::MockRequest.env_for("http://example.org:8080/")).url.
614
- should.equal "http://example.org:8080/"
615
- Rack::Request.new(Rack::MockRequest.env_for("https://example.org/")).url.
616
- should.equal "https://example.org/"
617
- Rack::Request.new(Rack::MockRequest.env_for("coffee://example.org/")).url.
618
- should.equal "coffee://example.org/"
619
- Rack::Request.new(Rack::MockRequest.env_for("coffee://example.org:443/")).url.
620
- should.equal "coffee://example.org:443/"
621
- Rack::Request.new(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).url.
622
- should.equal "https://example.com:8080/foo?foo"
623
- end
624
-
625
- should "restore the full path" do
626
- Rack::Request.new(Rack::MockRequest.env_for("")).fullpath.
627
- should.equal "/"
628
- Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).fullpath.
629
- should.equal "/foo/"
630
- Rack::Request.new(Rack::MockRequest.env_for("/foo")).fullpath.
631
- should.equal "/foo"
632
- Rack::Request.new(Rack::MockRequest.env_for("?foo")).fullpath.
633
- should.equal "/?foo"
634
- Rack::Request.new(Rack::MockRequest.env_for("http://example.org:8080/")).fullpath.
635
- should.equal "/"
636
- Rack::Request.new(Rack::MockRequest.env_for("https://example.org/")).fullpath.
637
- should.equal "/"
638
-
639
- Rack::Request.new(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).fullpath.
640
- should.equal "/foo?foo"
641
- end
642
-
643
- should "handle multiple media type parameters" do
644
- req = Rack::Request.new \
738
+ req.path_info.must_equal "/foo"
739
+ e["PATH_INFO"].must_equal "/foo"
740
+ end
741
+
742
+ it "provide the original env" do
743
+ req = make_request(e = Rack::MockRequest.env_for(""))
744
+ req.env.must_equal e
745
+ end
746
+
747
+ it "restore the base URL" do
748
+ make_request(Rack::MockRequest.env_for("")).base_url.
749
+ must_equal "http://example.org"
750
+ make_request(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).base_url.
751
+ must_equal "http://example.org"
752
+ end
753
+
754
+ it "restore the URL" do
755
+ make_request(Rack::MockRequest.env_for("")).url.
756
+ must_equal "http://example.org/"
757
+ make_request(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).url.
758
+ must_equal "http://example.org/foo/"
759
+ make_request(Rack::MockRequest.env_for("/foo")).url.
760
+ must_equal "http://example.org/foo"
761
+ make_request(Rack::MockRequest.env_for("?foo")).url.
762
+ must_equal "http://example.org/?foo"
763
+ make_request(Rack::MockRequest.env_for("http://example.org:8080/")).url.
764
+ must_equal "http://example.org:8080/"
765
+ make_request(Rack::MockRequest.env_for("https://example.org/")).url.
766
+ must_equal "https://example.org/"
767
+ make_request(Rack::MockRequest.env_for("coffee://example.org/")).url.
768
+ must_equal "coffee://example.org/"
769
+ make_request(Rack::MockRequest.env_for("coffee://example.org:443/")).url.
770
+ must_equal "coffee://example.org:443/"
771
+ make_request(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).url.
772
+ must_equal "https://example.com:8080/foo?foo"
773
+ end
774
+
775
+ it "restore the full path" do
776
+ make_request(Rack::MockRequest.env_for("")).fullpath.
777
+ must_equal "/"
778
+ make_request(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).fullpath.
779
+ must_equal "/foo/"
780
+ make_request(Rack::MockRequest.env_for("/foo")).fullpath.
781
+ must_equal "/foo"
782
+ make_request(Rack::MockRequest.env_for("?foo")).fullpath.
783
+ must_equal "/?foo"
784
+ make_request(Rack::MockRequest.env_for("http://example.org:8080/")).fullpath.
785
+ must_equal "/"
786
+ make_request(Rack::MockRequest.env_for("https://example.org/")).fullpath.
787
+ must_equal "/"
788
+
789
+ make_request(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).fullpath.
790
+ must_equal "/foo?foo"
791
+ end
792
+
793
+ it "handle multiple media type parameters" do
794
+ req = make_request \
645
795
  Rack::MockRequest.env_for("/",
646
796
  "CONTENT_TYPE" => 'text/plain; foo=BAR,baz=bizzle dizzle;BLING=bam;blong="boo";zump="zoo\"o";weird=lol"')
647
- req.should.not.be.form_data
648
- req.media_type_params.should.include 'foo'
649
- req.media_type_params['foo'].should.equal 'BAR'
650
- req.media_type_params.should.include 'baz'
651
- req.media_type_params['baz'].should.equal 'bizzle dizzle'
652
- req.media_type_params.should.not.include 'BLING'
653
- req.media_type_params.should.include 'bling'
654
- req.media_type_params['bling'].should.equal 'bam'
655
- req.media_type_params['blong'].should.equal 'boo'
656
- req.media_type_params['zump'].should.equal 'zoo\"o'
657
- req.media_type_params['weird'].should.equal 'lol"'
658
- end
659
-
660
- should "parse with junk before boundry" do
797
+ req.wont_be :form_data?
798
+ req.media_type_params.must_include 'foo'
799
+ req.media_type_params['foo'].must_equal 'BAR'
800
+ req.media_type_params.must_include 'baz'
801
+ req.media_type_params['baz'].must_equal 'bizzle dizzle'
802
+ req.media_type_params.wont_include 'BLING'
803
+ req.media_type_params.must_include 'bling'
804
+ req.media_type_params['bling'].must_equal 'bam'
805
+ req.media_type_params['blong'].must_equal 'boo'
806
+ req.media_type_params['zump'].must_equal 'zoo\"o'
807
+ req.media_type_params['weird'].must_equal 'lol"'
808
+ end
809
+
810
+ it "parse with junk before boundary" do
661
811
  # Adapted from RFC 1867.
662
812
  input = <<EOF
663
813
  blah blah\r
@@ -674,31 +824,31 @@ Content-Transfer-Encoding: base64\r
674
824
  /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
675
825
  --AaB03x--\r
676
826
  EOF
677
- req = Rack::Request.new Rack::MockRequest.env_for("/",
827
+ req = make_request Rack::MockRequest.env_for("/",
678
828
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
679
829
  "CONTENT_LENGTH" => input.size,
680
830
  :input => input)
681
831
 
682
- req.POST.should.include "fileupload"
683
- req.POST.should.include "reply"
832
+ req.POST.must_include "fileupload"
833
+ req.POST.must_include "reply"
684
834
 
685
- req.should.be.form_data
686
- req.content_length.should.equal input.size
687
- req.media_type.should.equal 'multipart/form-data'
688
- req.media_type_params.should.include 'boundary'
689
- req.media_type_params['boundary'].should.equal 'AaB03x'
835
+ req.must_be :form_data?
836
+ req.content_length.must_equal input.size
837
+ req.media_type.must_equal 'multipart/form-data'
838
+ req.media_type_params.must_include 'boundary'
839
+ req.media_type_params['boundary'].must_equal 'AaB03x'
690
840
 
691
- req.POST["reply"].should.equal "yes"
841
+ req.POST["reply"].must_equal "yes"
692
842
 
693
843
  f = req.POST["fileupload"]
694
- f.should.be.kind_of Hash
695
- f[:type].should.equal "image/jpeg"
696
- f[:filename].should.equal "dj.jpg"
697
- f.should.include :tempfile
698
- f[:tempfile].size.should.equal 76
844
+ f.must_be_kind_of Hash
845
+ f[:type].must_equal "image/jpeg"
846
+ f[:filename].must_equal "dj.jpg"
847
+ f.must_include :tempfile
848
+ f[:tempfile].size.must_equal 76
699
849
  end
700
850
 
701
- should "not infinite loop with a malformed HTTP request" do
851
+ it "not infinite loop with a malformed HTTP request" do
702
852
  # Adapted from RFC 1867.
703
853
  input = <<EOF
704
854
  --AaB03x
@@ -713,16 +863,16 @@ Content-Transfer-Encoding: base64
713
863
  /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
714
864
  --AaB03x--
715
865
  EOF
716
- req = Rack::Request.new Rack::MockRequest.env_for("/",
866
+ req = make_request Rack::MockRequest.env_for("/",
717
867
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
718
868
  "CONTENT_LENGTH" => input.size,
719
869
  :input => input)
720
870
 
721
- lambda{req.POST}.should.raise(EOFError)
871
+ lambda{req.POST}.must_raise EOFError
722
872
  end
723
873
 
724
874
 
725
- should "parse multipart form data" do
875
+ it "parse multipart form data" do
726
876
  # Adapted from RFC 1867.
727
877
  input = <<EOF
728
878
  --AaB03x\r
@@ -737,47 +887,73 @@ Content-Transfer-Encoding: base64\r
737
887
  /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
738
888
  --AaB03x--\r
739
889
  EOF
740
- req = Rack::Request.new Rack::MockRequest.env_for("/",
890
+ req = make_request Rack::MockRequest.env_for("/",
741
891
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
742
892
  "CONTENT_LENGTH" => input.size,
743
893
  :input => input)
744
894
 
745
- req.POST.should.include "fileupload"
746
- req.POST.should.include "reply"
895
+ req.POST.must_include "fileupload"
896
+ req.POST.must_include "reply"
747
897
 
748
- req.should.be.form_data
749
- req.content_length.should.equal input.size
750
- req.media_type.should.equal 'multipart/form-data'
751
- req.media_type_params.should.include 'boundary'
752
- req.media_type_params['boundary'].should.equal 'AaB03x'
898
+ req.must_be :form_data?
899
+ req.content_length.must_equal input.size
900
+ req.media_type.must_equal 'multipart/form-data'
901
+ req.media_type_params.must_include 'boundary'
902
+ req.media_type_params['boundary'].must_equal 'AaB03x'
753
903
 
754
- req.POST["reply"].should.equal "yes"
904
+ req.POST["reply"].must_equal "yes"
755
905
 
756
906
  f = req.POST["fileupload"]
757
- f.should.be.kind_of Hash
758
- f[:type].should.equal "image/jpeg"
759
- f[:filename].should.equal "dj.jpg"
760
- f.should.include :tempfile
761
- f[:tempfile].size.should.equal 76
907
+ f.must_be_kind_of Hash
908
+ f[:type].must_equal "image/jpeg"
909
+ f[:filename].must_equal "dj.jpg"
910
+ f.must_include :tempfile
911
+ f[:tempfile].size.must_equal 76
912
+ end
913
+
914
+ it "MultipartPartLimitError when request has too many multipart parts if limit set" do
915
+ begin
916
+ data = 10000.times.map { "--AaB03x\r\nContent-Type: text/plain\r\nContent-Disposition: attachment; name=#{SecureRandom.hex(10)}; filename=#{SecureRandom.hex(10)}\r\n\r\ncontents\r\n" }.join("\r\n")
917
+ data += "--AaB03x--\r"
918
+
919
+ options = {
920
+ "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
921
+ "CONTENT_LENGTH" => data.length.to_s,
922
+ :input => StringIO.new(data)
923
+ }
924
+
925
+ request = make_request Rack::MockRequest.env_for("/", options)
926
+ lambda { request.POST }.must_raise Rack::Multipart::MultipartPartLimitError
927
+ end
762
928
  end
763
929
 
764
- should "MultipartPartLimitError when request has too many multipart parts if limit set" do
930
+ it 'closes tempfiles it created in the case of too many created' do
765
931
  begin
766
932
  data = 10000.times.map { "--AaB03x\r\nContent-Type: text/plain\r\nContent-Disposition: attachment; name=#{SecureRandom.hex(10)}; filename=#{SecureRandom.hex(10)}\r\n\r\ncontents\r\n" }.join("\r\n")
767
933
  data += "--AaB03x--\r"
768
934
 
935
+ files = []
769
936
  options = {
770
937
  "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
771
938
  "CONTENT_LENGTH" => data.length.to_s,
939
+ Rack::RACK_MULTIPART_TEMPFILE_FACTORY => lambda { |filename, content_type|
940
+ file = Tempfile.new(["RackMultipart", ::File.extname(filename)])
941
+ files << file
942
+ file
943
+ },
772
944
  :input => StringIO.new(data)
773
945
  }
774
946
 
775
- request = Rack::Request.new Rack::MockRequest.env_for("/", options)
776
- lambda { request.POST }.should.raise(Rack::Multipart::MultipartPartLimitError)
947
+ request = make_request Rack::MockRequest.env_for("/", options)
948
+ assert_raises(Rack::Multipart::MultipartPartLimitError) do
949
+ request.POST
950
+ end
951
+ refute_predicate files, :empty?
952
+ files.each { |f| assert_predicate f, :closed? }
777
953
  end
778
954
  end
779
955
 
780
- should "parse big multipart form data" do
956
+ it "parse big multipart form data" do
781
957
  input = <<EOF
782
958
  --AaB03x\r
783
959
  content-disposition: form-data; name="huge"; filename="huge"\r
@@ -789,17 +965,17 @@ content-disposition: form-data; name="mean"; filename="mean"\r
789
965
  --AaB03xha\r
790
966
  --AaB03x--\r
791
967
  EOF
792
- req = Rack::Request.new Rack::MockRequest.env_for("/",
968
+ req = make_request Rack::MockRequest.env_for("/",
793
969
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
794
970
  "CONTENT_LENGTH" => input.size,
795
971
  :input => input)
796
972
 
797
- req.POST["huge"][:tempfile].size.should.equal 32768
798
- req.POST["mean"][:tempfile].size.should.equal 10
799
- req.POST["mean"][:tempfile].read.should.equal "--AaB03xha"
973
+ req.POST["huge"][:tempfile].size.must_equal 32768
974
+ req.POST["mean"][:tempfile].size.must_equal 10
975
+ req.POST["mean"][:tempfile].read.must_equal "--AaB03xha"
800
976
  end
801
977
 
802
- should "record tempfiles from multipart form data in env[rack.tempfiles]" do
978
+ it "record tempfiles from multipart form data in env[rack.tempfiles]" do
803
979
  input = <<EOF
804
980
  --AaB03x\r
805
981
  content-disposition: form-data; name="fileupload"; filename="foo.jpg"\r
@@ -819,22 +995,22 @@ EOF
819
995
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
820
996
  "CONTENT_LENGTH" => input.size,
821
997
  :input => input)
822
- req = Rack::Request.new(env)
998
+ req = make_request(env)
823
999
  req.params
824
- env['rack.tempfiles'].size.should.equal(2)
1000
+ env['rack.tempfiles'].size.must_equal 2
825
1001
  end
826
1002
 
827
- should "detect invalid multipart form data" do
1003
+ it "detect invalid multipart form data" do
828
1004
  input = <<EOF
829
1005
  --AaB03x\r
830
1006
  content-disposition: form-data; name="huge"; filename="huge"\r
831
1007
  EOF
832
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1008
+ req = make_request Rack::MockRequest.env_for("/",
833
1009
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
834
1010
  "CONTENT_LENGTH" => input.size,
835
1011
  :input => input)
836
1012
 
837
- lambda { req.POST }.should.raise(EOFError)
1013
+ lambda { req.POST }.must_raise EOFError
838
1014
 
839
1015
  input = <<EOF
840
1016
  --AaB03x\r
@@ -842,12 +1018,12 @@ content-disposition: form-data; name="huge"; filename="huge"\r
842
1018
  \r
843
1019
  foo\r
844
1020
  EOF
845
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1021
+ req = make_request Rack::MockRequest.env_for("/",
846
1022
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
847
1023
  "CONTENT_LENGTH" => input.size,
848
1024
  :input => input)
849
1025
 
850
- lambda { req.POST }.should.raise(EOFError)
1026
+ lambda { req.POST }.must_raise EOFError
851
1027
 
852
1028
  input = <<EOF
853
1029
  --AaB03x\r
@@ -855,29 +1031,29 @@ content-disposition: form-data; name="huge"; filename="huge"\r
855
1031
  \r
856
1032
  foo\r
857
1033
  EOF
858
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1034
+ req = make_request Rack::MockRequest.env_for("/",
859
1035
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
860
1036
  "CONTENT_LENGTH" => input.size,
861
1037
  :input => input)
862
1038
 
863
- lambda { req.POST }.should.raise(EOFError)
1039
+ lambda { req.POST }.must_raise EOFError
864
1040
  end
865
1041
 
866
- should "consistently raise EOFError on bad multipart form data" do
1042
+ it "consistently raise EOFError on bad multipart form data" do
867
1043
  input = <<EOF
868
1044
  --AaB03x\r
869
1045
  content-disposition: form-data; name="huge"; filename="huge"\r
870
1046
  EOF
871
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1047
+ req = make_request Rack::MockRequest.env_for("/",
872
1048
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
873
1049
  "CONTENT_LENGTH" => input.size,
874
1050
  :input => input)
875
1051
 
876
- lambda { req.POST }.should.raise(EOFError)
877
- lambda { req.POST }.should.raise(EOFError)
1052
+ lambda { req.POST }.must_raise EOFError
1053
+ lambda { req.POST }.must_raise EOFError
878
1054
  end
879
1055
 
880
- should "correctly parse the part name from Content-Id header" do
1056
+ it "correctly parse the part name from Content-Id header" do
881
1057
  input = <<EOF
882
1058
  --AaB03x\r
883
1059
  Content-Type: text/xml; charset=utf-8\r
@@ -887,20 +1063,15 @@ Content-Transfer-Encoding: 7bit\r
887
1063
  foo\r
888
1064
  --AaB03x--\r
889
1065
  EOF
890
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1066
+ req = make_request Rack::MockRequest.env_for("/",
891
1067
  "CONTENT_TYPE" => "multipart/related, boundary=AaB03x",
892
1068
  "CONTENT_LENGTH" => input.size,
893
1069
  :input => input)
894
1070
 
895
- req.params.keys.should.equal ["<soap-start>"]
1071
+ req.params.keys.must_equal ["<soap-start>"]
896
1072
  end
897
1073
 
898
- should "not try to interpret binary as utf8" do
899
- if /regexp/.respond_to?(:kcode) # < 1.9
900
- begin
901
- original_kcode = $KCODE
902
- $KCODE='UTF8'
903
-
1074
+ it "not try to interpret binary as utf8" do
904
1075
  input = <<EOF
905
1076
  --AaB03x\r
906
1077
  content-disposition: form-data; name="fileupload"; filename="junk.a"\r
@@ -910,77 +1081,33 @@ content-type: application/octet-stream\r
910
1081
  --AaB03x--\r
911
1082
  EOF
912
1083
 
913
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1084
+ req = make_request Rack::MockRequest.env_for("/",
914
1085
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
915
1086
  "CONTENT_LENGTH" => input.size,
916
1087
  :input => input)
917
1088
 
918
- lambda{req.POST}.should.not.raise(EOFError)
919
- req.POST["fileupload"][:tempfile].size.should.equal 4
920
- ensure
921
- $KCODE = original_kcode
922
- end
923
- else # >= 1.9
924
- input = <<EOF
925
- --AaB03x\r
926
- content-disposition: form-data; name="fileupload"; filename="junk.a"\r
927
- content-type: application/octet-stream\r
928
- \r
929
- #{[0x36,0xCF,0x0A,0xF8].pack('c*')}\r
930
- --AaB03x--\r
931
- EOF
932
-
933
- req = Rack::Request.new Rack::MockRequest.env_for("/",
934
- "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
935
- "CONTENT_LENGTH" => input.size,
936
- :input => input)
937
-
938
- lambda{req.POST}.should.not.raise(EOFError)
939
- req.POST["fileupload"][:tempfile].size.should.equal 4
940
- end
1089
+ req.POST["fileupload"][:tempfile].size.must_equal 4
941
1090
  end
942
1091
 
943
- should "work around buggy 1.8.* Tempfile equality" do
944
- input = <<EOF
945
- --AaB03x\r
946
- content-disposition: form-data; name="huge"; filename="huge"\r
947
- \r
948
- foo\r
949
- --AaB03x--
950
- EOF
951
-
952
- rack_input = Tempfile.new("rackspec")
953
- rack_input.write(input)
954
- rack_input.rewind
955
-
956
- req = Rack::Request.new Rack::MockRequest.env_for("/",
957
- "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
958
- "CONTENT_LENGTH" => input.size,
959
- :input => rack_input)
960
-
961
- lambda{ req.POST }.should.not.raise
962
- lambda{ req.POST }.should.not.raise("input re-processed!")
963
- end
964
-
965
- should "use form_hash when form_input is a Tempfile" do
1092
+ it "use form_hash when form_input is a Tempfile" do
966
1093
  input = "{foo: 'bar'}"
967
1094
 
968
1095
  rack_input = Tempfile.new("rackspec")
969
1096
  rack_input.write(input)
970
1097
  rack_input.rewind
971
1098
 
972
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1099
+ req = make_request Rack::MockRequest.env_for("/",
973
1100
  "rack.request.form_hash" => {'foo' => 'bar'},
974
1101
  "rack.request.form_input" => rack_input,
975
1102
  :input => rack_input)
976
1103
 
977
- req.POST.should.equal(req.env['rack.request.form_hash'])
1104
+ req.POST.must_equal req.env['rack.request.form_hash']
978
1105
  end
979
1106
 
980
- should "conform to the Rack spec" do
1107
+ it "conform to the Rack spec" do
981
1108
  app = lambda { |env|
982
- content = Rack::Request.new(env).POST["file"].inspect
983
- size = content.respond_to?(:bytesize) ? content.bytesize : content.size
1109
+ content = make_request(env).POST["file"].inspect
1110
+ size = content.bytesize
984
1111
  [200, {"Content-Type" => "text/html", "Content-Length" => size.to_s}, [content]]
985
1112
  }
986
1113
 
@@ -997,149 +1124,151 @@ Content-Transfer-Encoding: base64\r
997
1124
  /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
998
1125
  --AaB03x--\r
999
1126
  EOF
1000
- input.force_encoding("ASCII-8BIT") if input.respond_to? :force_encoding
1127
+ input.force_encoding(Encoding::ASCII_8BIT)
1001
1128
  res = Rack::MockRequest.new(Rack::Lint.new(app)).get "/",
1002
1129
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
1003
1130
  "CONTENT_LENGTH" => input.size.to_s, "rack.input" => StringIO.new(input)
1004
1131
 
1005
- res.should.be.ok
1132
+ res.must_be :ok?
1006
1133
  end
1007
1134
 
1008
- should "parse Accept-Encoding correctly" do
1135
+ it "parse Accept-Encoding correctly" do
1009
1136
  parser = lambda do |x|
1010
- Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => x)).accept_encoding
1137
+ make_request(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => x)).accept_encoding
1011
1138
  end
1012
1139
 
1013
- parser.call(nil).should.equal([])
1140
+ parser.call(nil).must_equal []
1014
1141
 
1015
- parser.call("compress, gzip").should.equal([["compress", 1.0], ["gzip", 1.0]])
1016
- parser.call("").should.equal([])
1017
- parser.call("*").should.equal([["*", 1.0]])
1018
- parser.call("compress;q=0.5, gzip;q=1.0").should.equal([["compress", 0.5], ["gzip", 1.0]])
1019
- parser.call("gzip;q=1.0, identity; q=0.5, *;q=0").should.equal([["gzip", 1.0], ["identity", 0.5], ["*", 0] ])
1142
+ parser.call("compress, gzip").must_equal [["compress", 1.0], ["gzip", 1.0]]
1143
+ parser.call("").must_equal []
1144
+ parser.call("*").must_equal [["*", 1.0]]
1145
+ parser.call("compress;q=0.5, gzip;q=1.0").must_equal [["compress", 0.5], ["gzip", 1.0]]
1146
+ parser.call("gzip;q=1.0, identity; q=0.5, *;q=0").must_equal [["gzip", 1.0], ["identity", 0.5], ["*", 0] ]
1020
1147
 
1021
- parser.call("gzip ; q=0.9").should.equal([["gzip", 0.9]])
1022
- parser.call("gzip ; deflate").should.equal([["gzip", 1.0]])
1148
+ parser.call("gzip ; q=0.9").must_equal [["gzip", 0.9]]
1149
+ parser.call("gzip ; deflate").must_equal [["gzip", 1.0]]
1023
1150
  end
1024
1151
 
1025
- should "parse Accept-Language correctly" do
1152
+ it "parse Accept-Language correctly" do
1026
1153
  parser = lambda do |x|
1027
- Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_LANGUAGE" => x)).accept_language
1154
+ make_request(Rack::MockRequest.env_for("", "HTTP_ACCEPT_LANGUAGE" => x)).accept_language
1028
1155
  end
1029
1156
 
1030
- parser.call(nil).should.equal([])
1157
+ parser.call(nil).must_equal []
1031
1158
 
1032
- parser.call("fr, en").should.equal([["fr", 1.0], ["en", 1.0]])
1033
- parser.call("").should.equal([])
1034
- parser.call("*").should.equal([["*", 1.0]])
1035
- parser.call("fr;q=0.5, en;q=1.0").should.equal([["fr", 0.5], ["en", 1.0]])
1036
- parser.call("fr;q=1.0, en; q=0.5, *;q=0").should.equal([["fr", 1.0], ["en", 0.5], ["*", 0] ])
1159
+ parser.call("fr, en").must_equal [["fr", 1.0], ["en", 1.0]]
1160
+ parser.call("").must_equal []
1161
+ parser.call("*").must_equal [["*", 1.0]]
1162
+ parser.call("fr;q=0.5, en;q=1.0").must_equal [["fr", 0.5], ["en", 1.0]]
1163
+ parser.call("fr;q=1.0, en; q=0.5, *;q=0").must_equal [["fr", 1.0], ["en", 0.5], ["*", 0] ]
1037
1164
 
1038
- parser.call("fr ; q=0.9").should.equal([["fr", 0.9]])
1039
- parser.call("fr").should.equal([["fr", 1.0]])
1165
+ parser.call("fr ; q=0.9").must_equal [["fr", 0.9]]
1166
+ parser.call("fr").must_equal [["fr", 1.0]]
1040
1167
  end
1041
1168
 
1042
- ip_app = lambda { |env|
1043
- request = Rack::Request.new(env)
1044
- response = Rack::Response.new
1045
- response.write request.ip
1046
- response.finish
1047
- }
1169
+ def ip_app
1170
+ lambda { |env|
1171
+ request = make_request(env)
1172
+ response = Rack::Response.new
1173
+ response.write request.ip
1174
+ response.finish
1175
+ }
1176
+ end
1048
1177
 
1049
- should 'provide ip information' do
1178
+ it 'provide ip information' do
1050
1179
  mock = Rack::MockRequest.new(Rack::Lint.new(ip_app))
1051
1180
 
1052
1181
  res = mock.get '/', 'REMOTE_ADDR' => '1.2.3.4'
1053
- res.body.should.equal '1.2.3.4'
1182
+ res.body.must_equal '1.2.3.4'
1054
1183
 
1055
1184
  res = mock.get '/', 'REMOTE_ADDR' => 'fe80::202:b3ff:fe1e:8329'
1056
- res.body.should.equal 'fe80::202:b3ff:fe1e:8329'
1185
+ res.body.must_equal 'fe80::202:b3ff:fe1e:8329'
1057
1186
 
1058
1187
  res = mock.get '/', 'REMOTE_ADDR' => '1.2.3.4,3.4.5.6'
1059
- res.body.should.equal '1.2.3.4'
1188
+ res.body.must_equal '1.2.3.4'
1060
1189
  end
1061
1190
 
1062
- should 'deals with proxies' do
1191
+ it 'deals with proxies' do
1063
1192
  mock = Rack::MockRequest.new(Rack::Lint.new(ip_app))
1064
1193
 
1065
1194
  res = mock.get '/',
1066
1195
  'REMOTE_ADDR' => '1.2.3.4',
1067
1196
  'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
1068
- res.body.should.equal '1.2.3.4'
1197
+ res.body.must_equal '1.2.3.4'
1069
1198
 
1070
1199
  res = mock.get '/',
1071
1200
  'REMOTE_ADDR' => '1.2.3.4',
1072
1201
  'HTTP_X_FORWARDED_FOR' => 'unknown'
1073
- res.body.should.equal '1.2.3.4'
1202
+ res.body.must_equal '1.2.3.4'
1074
1203
 
1075
1204
  res = mock.get '/',
1076
1205
  'REMOTE_ADDR' => '127.0.0.1',
1077
1206
  'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
1078
- res.body.should.equal '3.4.5.6'
1207
+ res.body.must_equal '3.4.5.6'
1079
1208
 
1080
1209
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => 'unknown,3.4.5.6'
1081
- res.body.should.equal '3.4.5.6'
1210
+ res.body.must_equal '3.4.5.6'
1082
1211
 
1083
1212
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '192.168.0.1,3.4.5.6'
1084
- res.body.should.equal '3.4.5.6'
1213
+ res.body.must_equal '3.4.5.6'
1085
1214
 
1086
1215
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '10.0.0.1,3.4.5.6'
1087
- res.body.should.equal '3.4.5.6'
1216
+ res.body.must_equal '3.4.5.6'
1088
1217
 
1089
1218
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '10.0.0.1, 10.0.0.1, 3.4.5.6'
1090
- res.body.should.equal '3.4.5.6'
1219
+ res.body.must_equal '3.4.5.6'
1091
1220
 
1092
1221
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '127.0.0.1, 3.4.5.6'
1093
- res.body.should.equal '3.4.5.6'
1222
+ res.body.must_equal '3.4.5.6'
1094
1223
 
1095
1224
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => 'unknown,192.168.0.1'
1096
- res.body.should.equal 'unknown'
1225
+ res.body.must_equal 'unknown'
1097
1226
 
1098
1227
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => 'other,unknown,192.168.0.1'
1099
- res.body.should.equal 'unknown'
1228
+ res.body.must_equal 'unknown'
1100
1229
 
1101
1230
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => 'unknown,localhost,192.168.0.1'
1102
- res.body.should.equal 'unknown'
1231
+ res.body.must_equal 'unknown'
1103
1232
 
1104
1233
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '9.9.9.9, 3.4.5.6, 10.0.0.1, 172.31.4.4'
1105
- res.body.should.equal '3.4.5.6'
1234
+ res.body.must_equal '3.4.5.6'
1106
1235
 
1107
1236
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '::1,2620:0:1c00:0:812c:9583:754b:ca11'
1108
- res.body.should.equal '2620:0:1c00:0:812c:9583:754b:ca11'
1237
+ res.body.must_equal '2620:0:1c00:0:812c:9583:754b:ca11'
1109
1238
 
1110
1239
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '2620:0:1c00:0:812c:9583:754b:ca11,::1'
1111
- res.body.should.equal '2620:0:1c00:0:812c:9583:754b:ca11'
1240
+ res.body.must_equal '2620:0:1c00:0:812c:9583:754b:ca11'
1112
1241
 
1113
1242
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => 'fd5b:982e:9130:247f:0000:0000:0000:0000,2620:0:1c00:0:812c:9583:754b:ca11'
1114
- res.body.should.equal '2620:0:1c00:0:812c:9583:754b:ca11'
1243
+ res.body.must_equal '2620:0:1c00:0:812c:9583:754b:ca11'
1115
1244
 
1116
1245
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '2620:0:1c00:0:812c:9583:754b:ca11,fd5b:982e:9130:247f:0000:0000:0000:0000'
1117
- res.body.should.equal '2620:0:1c00:0:812c:9583:754b:ca11'
1246
+ res.body.must_equal '2620:0:1c00:0:812c:9583:754b:ca11'
1118
1247
 
1119
1248
  res = mock.get '/',
1120
1249
  'HTTP_X_FORWARDED_FOR' => '1.1.1.1, 127.0.0.1',
1121
1250
  'HTTP_CLIENT_IP' => '1.1.1.1'
1122
- res.body.should.equal '1.1.1.1'
1251
+ res.body.must_equal '1.1.1.1'
1123
1252
 
1124
1253
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '8.8.8.8, 9.9.9.9'
1125
- res.body.should.equal '9.9.9.9'
1254
+ res.body.must_equal '9.9.9.9'
1126
1255
 
1127
1256
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '8.8.8.8, fe80::202:b3ff:fe1e:8329'
1128
- res.body.should.equal 'fe80::202:b3ff:fe1e:8329'
1257
+ res.body.must_equal 'fe80::202:b3ff:fe1e:8329'
1129
1258
 
1130
1259
  # Unix Sockets
1131
1260
  res = mock.get '/',
1132
1261
  'REMOTE_ADDR' => 'unix',
1133
1262
  'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
1134
- res.body.should.equal '3.4.5.6'
1263
+ res.body.must_equal '3.4.5.6'
1135
1264
 
1136
1265
  res = mock.get '/',
1137
1266
  'REMOTE_ADDR' => 'unix:/tmp/foo',
1138
1267
  'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
1139
- res.body.should.equal '3.4.5.6'
1268
+ res.body.must_equal '3.4.5.6'
1140
1269
  end
1141
1270
 
1142
- should "not allow IP spoofing via Client-IP and X-Forwarded-For headers" do
1271
+ it "not allow IP spoofing via Client-IP and X-Forwarded-For headers" do
1143
1272
  mock = Rack::MockRequest.new(Rack::Lint.new(ip_app))
1144
1273
 
1145
1274
  # IP Spoofing attempt:
@@ -1154,31 +1283,45 @@ EOF
1154
1283
  res = mock.get '/',
1155
1284
  'HTTP_X_FORWARDED_FOR' => '6.6.6.6, 2.2.2.3, 192.168.0.7',
1156
1285
  'HTTP_CLIENT_IP' => '6.6.6.6'
1157
- res.body.should.equal '2.2.2.3'
1158
- end
1159
-
1160
- should "regard local addresses as proxies" do
1161
- req = Rack::Request.new(Rack::MockRequest.env_for("/"))
1162
- req.trusted_proxy?('127.0.0.1').should.equal 0
1163
- req.trusted_proxy?('10.0.0.1').should.equal 0
1164
- req.trusted_proxy?('172.16.0.1').should.equal 0
1165
- req.trusted_proxy?('172.20.0.1').should.equal 0
1166
- req.trusted_proxy?('172.30.0.1').should.equal 0
1167
- req.trusted_proxy?('172.31.0.1').should.equal 0
1168
- req.trusted_proxy?('192.168.0.1').should.equal 0
1169
- req.trusted_proxy?('::1').should.equal 0
1170
- req.trusted_proxy?('fd00::').should.equal 0
1171
- req.trusted_proxy?('localhost').should.equal 0
1172
- req.trusted_proxy?('unix').should.equal 0
1173
- req.trusted_proxy?('unix:/tmp/sock').should.equal 0
1174
-
1175
- req.trusted_proxy?("unix.example.org").should.equal nil
1176
- req.trusted_proxy?("example.org\n127.0.0.1").should.equal nil
1177
- req.trusted_proxy?("127.0.0.1\nexample.org").should.equal nil
1178
- req.trusted_proxy?("11.0.0.1").should.equal nil
1179
- req.trusted_proxy?("172.15.0.1").should.equal nil
1180
- req.trusted_proxy?("172.32.0.1").should.equal nil
1181
- req.trusted_proxy?("2001:470:1f0b:18f8::1").should.equal nil
1286
+ res.body.must_equal '2.2.2.3'
1287
+ end
1288
+
1289
+ it "preserves ip for trusted proxy chain" do
1290
+ mock = Rack::MockRequest.new(Rack::Lint.new(ip_app))
1291
+ res = mock.get '/',
1292
+ 'HTTP_X_FORWARDED_FOR' => '192.168.0.11, 192.168.0.7',
1293
+ 'HTTP_CLIENT_IP' => '127.0.0.1'
1294
+ res.body.must_equal '192.168.0.11'
1295
+
1296
+ end
1297
+
1298
+ it "regards local addresses as proxies" do
1299
+ req = make_request(Rack::MockRequest.env_for("/"))
1300
+ req.trusted_proxy?('127.0.0.1').must_equal 0
1301
+ req.trusted_proxy?('10.0.0.1').must_equal 0
1302
+ req.trusted_proxy?('172.16.0.1').must_equal 0
1303
+ req.trusted_proxy?('172.20.0.1').must_equal 0
1304
+ req.trusted_proxy?('172.30.0.1').must_equal 0
1305
+ req.trusted_proxy?('172.31.0.1').must_equal 0
1306
+ req.trusted_proxy?('192.168.0.1').must_equal 0
1307
+ req.trusted_proxy?('::1').must_equal 0
1308
+ req.trusted_proxy?('fd00::').must_equal 0
1309
+ req.trusted_proxy?('localhost').must_equal 0
1310
+ req.trusted_proxy?('unix').must_equal 0
1311
+ req.trusted_proxy?('unix:/tmp/sock').must_equal 0
1312
+
1313
+ req.trusted_proxy?("unix.example.org").must_be_nil
1314
+ req.trusted_proxy?("example.org\n127.0.0.1").must_be_nil
1315
+ req.trusted_proxy?("127.0.0.1\nexample.org").must_be_nil
1316
+ req.trusted_proxy?("11.0.0.1").must_be_nil
1317
+ req.trusted_proxy?("172.15.0.1").must_be_nil
1318
+ req.trusted_proxy?("172.32.0.1").must_be_nil
1319
+ req.trusted_proxy?("2001:470:1f0b:18f8::1").must_be_nil
1320
+ end
1321
+
1322
+ it "sets the default session to an empty hash" do
1323
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
1324
+ assert_equal Hash.new, req.session
1182
1325
  end
1183
1326
 
1184
1327
  class MyRequest < Rack::Request
@@ -1187,46 +1330,78 @@ EOF
1187
1330
  end
1188
1331
  end
1189
1332
 
1190
- should "allow subclass request to be instantiated after parent request" do
1333
+ it "allow subclass request to be instantiated after parent request" do
1191
1334
  env = Rack::MockRequest.env_for("/?foo=bar")
1192
1335
 
1193
- req1 = Rack::Request.new(env)
1194
- req1.GET.should.equal "foo" => "bar"
1195
- req1.params.should.equal "foo" => "bar"
1336
+ req1 = make_request(env)
1337
+ req1.GET.must_equal "foo" => "bar"
1338
+ req1.params.must_equal "foo" => "bar"
1196
1339
 
1197
1340
  req2 = MyRequest.new(env)
1198
- req2.GET.should.equal "foo" => "bar"
1199
- req2.params.should.equal :foo => "bar"
1341
+ req2.GET.must_equal "foo" => "bar"
1342
+ req2.params.must_equal :foo => "bar"
1200
1343
  end
1201
1344
 
1202
- should "allow parent request to be instantiated after subclass request" do
1345
+ it "allow parent request to be instantiated after subclass request" do
1203
1346
  env = Rack::MockRequest.env_for("/?foo=bar")
1204
1347
 
1205
1348
  req1 = MyRequest.new(env)
1206
- req1.GET.should.equal "foo" => "bar"
1207
- req1.params.should.equal :foo => "bar"
1349
+ req1.GET.must_equal "foo" => "bar"
1350
+ req1.params.must_equal :foo => "bar"
1208
1351
 
1209
- req2 = Rack::Request.new(env)
1210
- req2.GET.should.equal "foo" => "bar"
1211
- req2.params.should.equal "foo" => "bar"
1352
+ req2 = make_request(env)
1353
+ req2.GET.must_equal "foo" => "bar"
1354
+ req2.params.must_equal "foo" => "bar"
1212
1355
  end
1213
1356
 
1214
- should "raise TypeError every time if request parameters are broken" do
1357
+ it "raise TypeError every time if request parameters are broken" do
1215
1358
  broken_query = Rack::MockRequest.env_for("/?foo%5B%5D=0&foo%5Bbar%5D=1")
1216
- req = Rack::Request.new(broken_query)
1217
- lambda{req.GET}.should.raise(TypeError)
1218
- lambda{req.params}.should.raise(TypeError)
1359
+ req = make_request(broken_query)
1360
+ lambda{req.GET}.must_raise TypeError
1361
+ lambda{req.params}.must_raise TypeError
1219
1362
  end
1220
1363
 
1221
1364
  (0x20...0x7E).collect { |a|
1222
1365
  b = a.chr
1223
1366
  c = CGI.escape(b)
1224
- should "not strip '#{a}' => '#{c}' => '#{b}' escaped character from parameters when accessed as string" do
1367
+ it "not strip '#{a}' => '#{c}' => '#{b}' escaped character from parameters when accessed as string" do
1225
1368
  url = "/?foo=#{c}bar#{c}"
1226
1369
  env = Rack::MockRequest.env_for(url)
1227
- req2 = Rack::Request.new(env)
1228
- req2.GET.should.equal "foo" => "#{b}bar#{b}"
1229
- req2.params.should.equal "foo" => "#{b}bar#{b}"
1370
+ req2 = make_request(env)
1371
+ req2.GET.must_equal "foo" => "#{b}bar#{b}"
1372
+ req2.params.must_equal "foo" => "#{b}bar#{b}"
1230
1373
  end
1231
1374
  }
1375
+
1376
+ class NonDelegate < Rack::Request
1377
+ def delegate?; false; end
1378
+ end
1379
+
1380
+ def make_request(env)
1381
+ NonDelegate.new env
1382
+ end
1383
+
1384
+ class TestProxyRequest < RackRequestTest
1385
+ class DelegateRequest
1386
+ include Rack::Request::Helpers
1387
+ extend Forwardable
1388
+
1389
+ def_delegators :@req, :has_header?, :get_header, :fetch_header,
1390
+ :each_header, :set_header, :add_header, :delete_header
1391
+
1392
+ def_delegators :@req, :[], :[]=, :values_at
1393
+
1394
+ def initialize(req)
1395
+ @req = req
1396
+ end
1397
+
1398
+ def delegate?; true; end
1399
+
1400
+ def env; @req.env.dup; end
1401
+ end
1402
+
1403
+ def make_request(env)
1404
+ DelegateRequest.new super(env)
1405
+ end
1406
+ end
1232
1407
  end