rack 1.6.13 → 2.0.1

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 (144) hide show
  1. checksums.yaml +5 -5
  2. data/COPYING +1 -1
  3. data/HISTORY.md +138 -8
  4. data/README.rdoc +17 -25
  5. data/Rakefile +6 -14
  6. data/SPEC +8 -9
  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/{conditionalget.rb → conditional_get.rb} +0 -0
  18. data/lib/rack/content_length.rb +2 -2
  19. data/lib/rack/deflater.rb +4 -4
  20. data/lib/rack/directory.rb +66 -54
  21. data/lib/rack/etag.rb +4 -3
  22. data/lib/rack/events.rb +154 -0
  23. data/lib/rack/file.rb +63 -39
  24. data/lib/rack/handler/cgi.rb +15 -16
  25. data/lib/rack/handler/fastcgi.rb +13 -14
  26. data/lib/rack/handler/lsws.rb +11 -11
  27. data/lib/rack/handler/scgi.rb +15 -15
  28. data/lib/rack/handler/thin.rb +3 -0
  29. data/lib/rack/handler/webrick.rb +22 -24
  30. data/lib/rack/handler.rb +3 -25
  31. data/lib/rack/head.rb +15 -17
  32. data/lib/rack/lint.rb +38 -38
  33. data/lib/rack/lobster.rb +1 -1
  34. data/lib/rack/lock.rb +6 -10
  35. data/lib/rack/logger.rb +2 -2
  36. data/lib/rack/media_type.rb +38 -0
  37. data/lib/rack/{methodoverride.rb → method_override.rb} +4 -11
  38. data/lib/rack/mime.rb +18 -5
  39. data/lib/rack/mock.rb +35 -53
  40. data/lib/rack/multipart/generator.rb +5 -5
  41. data/lib/rack/multipart/parser.rb +272 -158
  42. data/lib/rack/multipart/uploaded_file.rb +1 -2
  43. data/lib/rack/multipart.rb +35 -6
  44. data/lib/rack/{nulllogger.rb → null_logger.rb} +1 -1
  45. data/lib/rack/query_parser.rb +192 -0
  46. data/lib/rack/recursive.rb +8 -8
  47. data/lib/rack/request.rb +383 -307
  48. data/lib/rack/response.rb +129 -56
  49. data/lib/rack/rewindable_input.rb +1 -12
  50. data/lib/rack/runtime.rb +10 -18
  51. data/lib/rack/sendfile.rb +5 -7
  52. data/lib/rack/server.rb +31 -25
  53. data/lib/rack/session/abstract/id.rb +95 -135
  54. data/lib/rack/session/cookie.rb +26 -28
  55. data/lib/rack/session/memcache.rb +8 -14
  56. data/lib/rack/session/pool.rb +14 -21
  57. data/lib/rack/show_exceptions.rb +386 -0
  58. data/lib/rack/{showstatus.rb → show_status.rb} +3 -3
  59. data/lib/rack/static.rb +30 -5
  60. data/lib/rack/tempfile_reaper.rb +2 -2
  61. data/lib/rack/urlmap.rb +15 -14
  62. data/lib/rack/utils.rb +135 -210
  63. data/lib/rack.rb +70 -21
  64. data/rack.gemspec +7 -5
  65. data/test/builder/an_underscore_app.rb +5 -0
  66. data/test/builder/options.ru +1 -1
  67. data/test/cgi/test.fcgi +1 -0
  68. data/test/cgi/test.gz +0 -0
  69. data/test/helper.rb +34 -0
  70. data/test/multipart/filename_with_encoded_words +7 -0
  71. data/test/multipart/{filename_with_null_byte → filename_with_single_quote} +1 -1
  72. data/test/multipart/quoted +15 -0
  73. data/test/multipart/rack-logo.png +0 -0
  74. data/test/multipart/unity3d_wwwform +11 -0
  75. data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
  76. data/test/spec_auth_basic.rb +27 -19
  77. data/test/spec_auth_digest.rb +47 -46
  78. data/test/spec_body_proxy.rb +27 -27
  79. data/test/spec_builder.rb +51 -41
  80. data/test/spec_cascade.rb +24 -22
  81. data/test/spec_cgi.rb +49 -67
  82. data/test/spec_chunked.rb +36 -34
  83. data/test/{spec_commonlogger.rb → spec_common_logger.rb} +23 -21
  84. data/test/{spec_conditionalget.rb → spec_conditional_get.rb} +29 -28
  85. data/test/spec_config.rb +3 -2
  86. data/test/spec_content_length.rb +18 -17
  87. data/test/spec_content_type.rb +13 -12
  88. data/test/spec_deflater.rb +66 -40
  89. data/test/spec_directory.rb +87 -27
  90. data/test/spec_etag.rb +32 -31
  91. data/test/spec_events.rb +133 -0
  92. data/test/spec_fastcgi.rb +50 -72
  93. data/test/spec_file.rb +107 -77
  94. data/test/spec_handler.rb +19 -34
  95. data/test/spec_head.rb +15 -14
  96. data/test/spec_lint.rb +162 -197
  97. data/test/spec_lobster.rb +24 -23
  98. data/test/spec_lock.rb +69 -39
  99. data/test/spec_logger.rb +4 -3
  100. data/test/spec_media_type.rb +42 -0
  101. data/test/spec_method_override.rb +83 -0
  102. data/test/spec_mime.rb +19 -19
  103. data/test/spec_mock.rb +196 -151
  104. data/test/spec_multipart.rb +317 -201
  105. data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
  106. data/test/spec_recursive.rb +17 -14
  107. data/test/spec_request.rb +768 -607
  108. data/test/spec_response.rb +214 -111
  109. data/test/spec_rewindable_input.rb +50 -40
  110. data/test/spec_runtime.rb +11 -10
  111. data/test/spec_sendfile.rb +30 -35
  112. data/test/spec_server.rb +78 -52
  113. data/test/spec_session_abstract_id.rb +11 -33
  114. data/test/spec_session_abstract_session_hash.rb +28 -0
  115. data/test/spec_session_cookie.rb +97 -65
  116. data/test/spec_session_memcache.rb +63 -101
  117. data/test/spec_session_pool.rb +48 -84
  118. data/test/spec_show_exceptions.rb +80 -0
  119. data/test/{spec_showstatus.rb → spec_show_status.rb} +36 -35
  120. data/test/spec_static.rb +71 -32
  121. data/test/spec_tempfile_reaper.rb +11 -10
  122. data/test/spec_thin.rb +55 -50
  123. data/test/spec_urlmap.rb +79 -78
  124. data/test/spec_utils.rb +441 -346
  125. data/test/spec_version.rb +2 -8
  126. data/test/spec_webrick.rb +91 -67
  127. data/test/static/foo.html +1 -0
  128. data/test/testrequest.rb +1 -1
  129. data/test/unregistered_handler/rack/handler/unregistered.rb +1 -1
  130. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +1 -1
  131. metadata +103 -69
  132. data/KNOWN-ISSUES +0 -44
  133. data/lib/rack/backports/uri/common_18.rb +0 -56
  134. data/lib/rack/backports/uri/common_192.rb +0 -52
  135. data/lib/rack/backports/uri/common_193.rb +0 -29
  136. data/lib/rack/handler/evented_mongrel.rb +0 -8
  137. data/lib/rack/handler/mongrel.rb +0 -106
  138. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  139. data/lib/rack/showexceptions.rb +0 -387
  140. data/lib/rack/utils/okjson.rb +0 -600
  141. data/test/spec_methodoverride.rb +0 -111
  142. data/test/spec_mongrel.rb +0 -182
  143. data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
  144. data/test/spec_showexceptions.rb +0 -98
data/test/spec_request.rb CHANGED
@@ -1,574 +1,719 @@
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
10
51
 
11
- req.body.should.respond_to? :gets
12
- req.scheme.should.equal "http"
13
- req.request_method.should.equal "GET"
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
14
67
 
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
68
+ it 'can add to multivalued headers in the env' do
69
+ req = make_request(Rack::MockRequest.env_for('http://example.com:8080/'))
21
70
 
22
- req.script_name.should.equal ""
23
- req.path_info.should.equal "/"
24
- req.query_string.should.equal ""
71
+ assert_equal '1', req.add_header('FOO', '1')
72
+ assert_equal '1', req.get_header('FOO')
25
73
 
26
- req.host.should.equal "example.com"
27
- req.port.should.equal 8080
74
+ assert_equal '1,2', req.add_header('FOO', '2')
75
+ assert_equal '1,2', req.get_header('FOO')
28
76
 
29
- req.content_length.should.equal "0"
30
- req.content_type.should.be.nil
77
+ assert_equal '1,2', req.add_header('FOO', nil)
78
+ assert_equal '1,2', req.get_header('FOO')
31
79
  end
32
80
 
33
- should "figure out the correct host" do
34
- req = Rack::Request.new \
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/"))
91
+
92
+ req.body.must_respond_to :gets
93
+ req.scheme.must_equal "http"
94
+ req.request_method.must_equal "GET"
95
+
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?
102
+
103
+ req.script_name.must_equal ""
104
+ req.path_info.must_equal "/"
105
+ req.query_string.must_equal ""
106
+
107
+ req.host.must_equal "example.com"
108
+ req.port.must_equal 8080
109
+
110
+ req.content_length.must_equal "0"
111
+ req.content_type.must_be_nil
112
+ end
113
+
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
284
+ mr = Rack::MockRequest.env_for("/?foo=quux",
285
+ "REQUEST_METHOD" => 'POST',
286
+ :input => "foo=bar&quux=bla"
287
+ )
288
+ req = make_request mr
289
+
290
+ req.params
291
+
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)
295
+ end
296
+
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
182
310
  mr = Rack::MockRequest.env_for("/?foo=quux",
183
311
  "REQUEST_METHOD" => 'POST',
184
312
  :input => "foo=bar&quux=bla"
185
313
  )
186
- req = Rack::Request.new mr
314
+ req = c.new mr
187
315
 
188
316
  req.params
189
317
 
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)
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"
193
323
  end
194
324
 
195
- should "raise if input params has invalid %-encoding" do
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_equal 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_equal 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_equal 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_equal 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_equal 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?
394
-
395
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTPS' => 'on'))
396
- request.scheme.should.equal "https"
397
- request.should.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?
398
541
 
399
- request = Rack::Request.new(Rack::MockRequest.env_for("/", 'rack.url_scheme' => 'https'))
400
- request.scheme.should.equal "https"
401
- 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?
402
545
 
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?
546
+ request = make_request(Rack::MockRequest.env_for("/", 'rack.url_scheme' => 'https'))
547
+ request.scheme.must_equal "https"
548
+ request.must_be :ssl?
406
549
 
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?
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?
410
553
 
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?
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?
414
557
 
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?
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?
418
561
 
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?
562
+ request = make_request(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_SCHEME' => 'https'))
563
+ request.scheme.must_equal "https"
564
+ request.must_be :ssl?
422
565
 
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?
426
- end
566
+ request = make_request(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_PROTO' => 'https'))
567
+ request.scheme.must_equal "https"
568
+ request.must_be :ssl?
427
569
 
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>'
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?
431
573
  end
432
574
 
433
- should "parse cookies" do
434
- req = Rack::Request.new \
575
+ it "parse cookies" do
576
+ req = make_request \
435
577
  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({})
578
+ req.cookies.must_equal "foo" => "bar", "quux" => "h&m"
579
+ req.cookies.must_equal "foo" => "bar", "quux" => "h&m"
580
+ req.delete_header("HTTP_COOKIE")
581
+ req.cookies.must_equal({})
440
582
  end
441
583
 
442
- should "always return the same hash object" do
443
- req = Rack::Request.new \
584
+ it "always return the same hash object" do
585
+ req = make_request \
444
586
  Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m")
445
587
  hash = req.cookies
446
588
  req.env.delete("HTTP_COOKIE")
447
- req.cookies.should.equal(hash)
589
+ req.cookies.must_equal hash
448
590
  req.env["HTTP_COOKIE"] = "zoo=m"
449
- req.cookies.should.equal(hash)
591
+ req.cookies.must_equal hash
450
592
  end
451
593
 
452
- should "modify the cookies hash in place" do
453
- req = Rack::Request.new(Rack::MockRequest.env_for(""))
454
- req.cookies.should.equal({})
594
+ it "modify the cookies hash in place" do
595
+ req = make_request(Rack::MockRequest.env_for(""))
596
+ req.cookies.must_equal({})
455
597
  req.cookies['foo'] = 'bar'
456
- req.cookies.should.equal 'foo' => 'bar'
598
+ req.cookies.must_equal 'foo' => 'bar'
457
599
  end
458
600
 
459
- should "not modify the params hash in place" do
601
+ it "not modify the params hash in place" do
460
602
  e = Rack::MockRequest.env_for("")
461
- req1 = Rack::Request.new(e)
462
- req1.params.should.equal({})
603
+ req1 = make_request(e)
604
+ if req1.delegate?
605
+ skip "delegate requests don't cache params, so mutations have no impact"
606
+ end
607
+ req1.params.must_equal({})
463
608
  req1.params['foo'] = 'bar'
464
- req1.params.should.equal 'foo' => 'bar'
465
- req2 = Rack::Request.new(e)
466
- req2.params.should.equal({})
609
+ req1.params.must_equal 'foo' => 'bar'
610
+ req2 = make_request(e)
611
+ req2.params.must_equal({})
467
612
  end
468
613
 
469
- should "modify params hash if param is in GET" do
614
+ it "modify params hash if param is in GET" do
470
615
  e = Rack::MockRequest.env_for("?foo=duh")
471
- req1 = Rack::Request.new(e)
472
- req1.params.should.equal 'foo' => 'duh'
616
+ req1 = make_request(e)
617
+ req1.params.must_equal 'foo' => 'duh'
473
618
  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'
619
+ req1.params.must_equal 'foo' => 'bar'
620
+ req2 = make_request(e)
621
+ req2.params.must_equal 'foo' => 'bar'
477
622
  end
478
623
 
479
- should "modify params hash if param is in POST" do
624
+ it "modify params hash if param is in POST" do
480
625
  e = Rack::MockRequest.env_for("", "REQUEST_METHOD" => 'POST', :input => 'foo=duh')
481
- req1 = Rack::Request.new(e)
482
- req1.params.should.equal 'foo' => 'duh'
626
+ req1 = make_request(e)
627
+ req1.params.must_equal 'foo' => 'duh'
483
628
  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'
629
+ req1.params.must_equal 'foo' => 'bar'
630
+ req2 = make_request(e)
631
+ req2.params.must_equal 'foo' => 'bar'
487
632
  end
488
633
 
489
- should "modify params hash, even if param didn't exist before" do
634
+ it "modify params hash, even if param didn't exist before" do
490
635
  e = Rack::MockRequest.env_for("")
491
- req1 = Rack::Request.new(e)
492
- req1.params.should.equal({})
636
+ req1 = make_request(e)
637
+ req1.params.must_equal({})
493
638
  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'
639
+ req1.params.must_equal 'foo' => 'bar'
640
+ req2 = make_request(e)
641
+ req2.params.must_equal 'foo' => 'bar'
497
642
  end
498
643
 
499
- should "modify params hash by changing only GET" do
644
+ it "modify params hash by changing only GET" do
500
645
  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({})
646
+ req = make_request(e)
647
+ req.GET.must_equal 'foo' => 'duhget'
648
+ req.POST.must_equal({})
504
649
  req.update_param 'foo', 'bar'
505
- req.GET.should.equal 'foo' => 'bar'
506
- req.POST.should.equal({})
650
+ req.GET.must_equal 'foo' => 'bar'
651
+ req.POST.must_equal({})
507
652
  end
508
653
 
509
- should "modify params hash by changing only POST" do
654
+ it "modify params hash by changing only POST" do
510
655
  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'
656
+ req = make_request(e)
657
+ req.GET.must_equal({})
658
+ req.POST.must_equal 'foo' => 'duhpost'
514
659
  req.update_param 'foo', 'bar'
515
- req.GET.should.equal({})
516
- req.POST.should.equal 'foo' => 'bar'
660
+ req.GET.must_equal({})
661
+ req.POST.must_equal 'foo' => 'bar'
517
662
  end
518
663
 
519
- should "modify params hash, even if param is defined in both POST and GET" do
664
+ it "modify params hash, even if param is defined in both POST and GET" do
520
665
  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'
666
+ req1 = make_request(e)
667
+ req1.GET.must_equal 'foo' => 'duhget'
668
+ req1.POST.must_equal 'foo' => 'duhpost'
669
+ req1.params.must_equal 'foo' => 'duhpost'
525
670
  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'
671
+ req1.GET.must_equal 'foo' => 'bar'
672
+ req1.POST.must_equal 'foo' => 'bar'
673
+ req1.params.must_equal 'foo' => 'bar'
674
+ req2 = make_request(e)
675
+ req2.GET.must_equal 'foo' => 'bar'
676
+ req2.POST.must_equal 'foo' => 'bar'
677
+ req2.params.must_equal 'foo' => 'bar'
678
+ req2.params.must_equal 'foo' => 'bar'
534
679
  end
535
680
 
536
- should "allow deleting from params hash if param is in GET" do
681
+ it "allow deleting from params hash if param is in GET" do
537
682
  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({})
683
+ req1 = make_request(e)
684
+ req1.params.must_equal 'foo' => 'bar'
685
+ req1.delete_param('foo').must_equal 'bar'
686
+ req1.params.must_equal({})
687
+ req2 = make_request(e)
688
+ req2.params.must_equal({})
544
689
  end
545
690
 
546
- should "allow deleting from params hash if param is in POST" do
691
+ it "allow deleting from params hash if param is in POST" do
547
692
  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({})
693
+ req1 = make_request(e)
694
+ req1.params.must_equal 'foo' => 'bar'
695
+ req1.delete_param('foo').must_equal 'bar'
696
+ req1.params.must_equal({})
697
+ req2 = make_request(e)
698
+ req2.params.must_equal({})
554
699
  end
555
700
 
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 == "%"
701
+ it "pass through non-uri escaped cookies as-is" do
702
+ req = make_request Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=%")
703
+ req.cookies["foo"].must_equal "%"
559
704
  end
560
705
 
561
- should "parse cookies according to RFC 2109" do
562
- req = Rack::Request.new \
706
+ it "parse cookies according to RFC 2109" do
707
+ req = make_request \
563
708
  Rack::MockRequest.env_for('', 'HTTP_COOKIE' => 'foo=bar;foo=car')
564
- req.cookies.should.equal 'foo' => 'bar'
709
+ req.cookies.must_equal 'foo' => 'bar'
565
710
  end
566
711
 
567
- should 'parse cookies with quotes' do
568
- req = Rack::Request.new Rack::MockRequest.env_for('', {
712
+ it 'parse cookies with quotes' do
713
+ req = make_request Rack::MockRequest.env_for('', {
569
714
  'HTTP_COOKIE' => '$Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"; Part_Number="Rocket_Launcher_0001"; $Path="/acme"'
570
715
  })
571
- req.cookies.should.equal({
716
+ req.cookies.must_equal({
572
717
  '$Version' => '"1"',
573
718
  'Customer' => '"WILE_E_COYOTE"',
574
719
  '$Path' => '"/acme"',
@@ -576,88 +721,88 @@ describe Rack::Request do
576
721
  })
577
722
  end
578
723
 
579
- should "provide setters" do
580
- req = Rack::Request.new(e=Rack::MockRequest.env_for(""))
581
- req.script_name.should.equal ""
724
+ it "provide setters" do
725
+ req = make_request(e=Rack::MockRequest.env_for(""))
726
+ req.script_name.must_equal ""
582
727
  req.script_name = "/foo"
583
- req.script_name.should.equal "/foo"
584
- e["SCRIPT_NAME"].should.equal "/foo"
728
+ req.script_name.must_equal "/foo"
729
+ e["SCRIPT_NAME"].must_equal "/foo"
585
730
 
586
- req.path_info.should.equal "/"
731
+ req.path_info.must_equal "/"
587
732
  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 \
733
+ req.path_info.must_equal "/foo"
734
+ e["PATH_INFO"].must_equal "/foo"
735
+ end
736
+
737
+ it "provide the original env" do
738
+ req = make_request(e = Rack::MockRequest.env_for(""))
739
+ req.env.must_equal e
740
+ end
741
+
742
+ it "restore the base URL" do
743
+ make_request(Rack::MockRequest.env_for("")).base_url.
744
+ must_equal "http://example.org"
745
+ make_request(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).base_url.
746
+ must_equal "http://example.org"
747
+ end
748
+
749
+ it "restore the URL" do
750
+ make_request(Rack::MockRequest.env_for("")).url.
751
+ must_equal "http://example.org/"
752
+ make_request(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).url.
753
+ must_equal "http://example.org/foo/"
754
+ make_request(Rack::MockRequest.env_for("/foo")).url.
755
+ must_equal "http://example.org/foo"
756
+ make_request(Rack::MockRequest.env_for("?foo")).url.
757
+ must_equal "http://example.org/?foo"
758
+ make_request(Rack::MockRequest.env_for("http://example.org:8080/")).url.
759
+ must_equal "http://example.org:8080/"
760
+ make_request(Rack::MockRequest.env_for("https://example.org/")).url.
761
+ must_equal "https://example.org/"
762
+ make_request(Rack::MockRequest.env_for("coffee://example.org/")).url.
763
+ must_equal "coffee://example.org/"
764
+ make_request(Rack::MockRequest.env_for("coffee://example.org:443/")).url.
765
+ must_equal "coffee://example.org:443/"
766
+ make_request(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).url.
767
+ must_equal "https://example.com:8080/foo?foo"
768
+ end
769
+
770
+ it "restore the full path" do
771
+ make_request(Rack::MockRequest.env_for("")).fullpath.
772
+ must_equal "/"
773
+ make_request(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).fullpath.
774
+ must_equal "/foo/"
775
+ make_request(Rack::MockRequest.env_for("/foo")).fullpath.
776
+ must_equal "/foo"
777
+ make_request(Rack::MockRequest.env_for("?foo")).fullpath.
778
+ must_equal "/?foo"
779
+ make_request(Rack::MockRequest.env_for("http://example.org:8080/")).fullpath.
780
+ must_equal "/"
781
+ make_request(Rack::MockRequest.env_for("https://example.org/")).fullpath.
782
+ must_equal "/"
783
+
784
+ make_request(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).fullpath.
785
+ must_equal "/foo?foo"
786
+ end
787
+
788
+ it "handle multiple media type parameters" do
789
+ req = make_request \
645
790
  Rack::MockRequest.env_for("/",
646
791
  "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
792
+ req.wont_be :form_data?
793
+ req.media_type_params.must_include 'foo'
794
+ req.media_type_params['foo'].must_equal 'BAR'
795
+ req.media_type_params.must_include 'baz'
796
+ req.media_type_params['baz'].must_equal 'bizzle dizzle'
797
+ req.media_type_params.wont_include 'BLING'
798
+ req.media_type_params.must_include 'bling'
799
+ req.media_type_params['bling'].must_equal 'bam'
800
+ req.media_type_params['blong'].must_equal 'boo'
801
+ req.media_type_params['zump'].must_equal 'zoo\"o'
802
+ req.media_type_params['weird'].must_equal 'lol"'
803
+ end
804
+
805
+ it "parse with junk before boundary" do
661
806
  # Adapted from RFC 1867.
662
807
  input = <<EOF
663
808
  blah blah\r
@@ -674,31 +819,31 @@ Content-Transfer-Encoding: base64\r
674
819
  /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
675
820
  --AaB03x--\r
676
821
  EOF
677
- req = Rack::Request.new Rack::MockRequest.env_for("/",
822
+ req = make_request Rack::MockRequest.env_for("/",
678
823
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
679
824
  "CONTENT_LENGTH" => input.size,
680
825
  :input => input)
681
826
 
682
- req.POST.should.include "fileupload"
683
- req.POST.should.include "reply"
827
+ req.POST.must_include "fileupload"
828
+ req.POST.must_include "reply"
684
829
 
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'
830
+ req.must_be :form_data?
831
+ req.content_length.must_equal input.size
832
+ req.media_type.must_equal 'multipart/form-data'
833
+ req.media_type_params.must_include 'boundary'
834
+ req.media_type_params['boundary'].must_equal 'AaB03x'
690
835
 
691
- req.POST["reply"].should.equal "yes"
836
+ req.POST["reply"].must_equal "yes"
692
837
 
693
838
  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
839
+ f.must_be_kind_of Hash
840
+ f[:type].must_equal "image/jpeg"
841
+ f[:filename].must_equal "dj.jpg"
842
+ f.must_include :tempfile
843
+ f[:tempfile].size.must_equal 76
699
844
  end
700
845
 
701
- should "not infinite loop with a malformed HTTP request" do
846
+ it "not infinite loop with a malformed HTTP request" do
702
847
  # Adapted from RFC 1867.
703
848
  input = <<EOF
704
849
  --AaB03x
@@ -713,16 +858,16 @@ Content-Transfer-Encoding: base64
713
858
  /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
714
859
  --AaB03x--
715
860
  EOF
716
- req = Rack::Request.new Rack::MockRequest.env_for("/",
861
+ req = make_request Rack::MockRequest.env_for("/",
717
862
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
718
863
  "CONTENT_LENGTH" => input.size,
719
864
  :input => input)
720
865
 
721
- lambda{req.POST}.should.raise(EOFError)
866
+ lambda{req.POST}.must_raise EOFError
722
867
  end
723
868
 
724
869
 
725
- should "parse multipart form data" do
870
+ it "parse multipart form data" do
726
871
  # Adapted from RFC 1867.
727
872
  input = <<EOF
728
873
  --AaB03x\r
@@ -737,47 +882,73 @@ Content-Transfer-Encoding: base64\r
737
882
  /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
738
883
  --AaB03x--\r
739
884
  EOF
740
- req = Rack::Request.new Rack::MockRequest.env_for("/",
885
+ req = make_request Rack::MockRequest.env_for("/",
741
886
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
742
887
  "CONTENT_LENGTH" => input.size,
743
888
  :input => input)
744
889
 
745
- req.POST.should.include "fileupload"
746
- req.POST.should.include "reply"
890
+ req.POST.must_include "fileupload"
891
+ req.POST.must_include "reply"
747
892
 
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'
893
+ req.must_be :form_data?
894
+ req.content_length.must_equal input.size
895
+ req.media_type.must_equal 'multipart/form-data'
896
+ req.media_type_params.must_include 'boundary'
897
+ req.media_type_params['boundary'].must_equal 'AaB03x'
753
898
 
754
- req.POST["reply"].should.equal "yes"
899
+ req.POST["reply"].must_equal "yes"
755
900
 
756
901
  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
902
+ f.must_be_kind_of Hash
903
+ f[:type].must_equal "image/jpeg"
904
+ f[:filename].must_equal "dj.jpg"
905
+ f.must_include :tempfile
906
+ f[:tempfile].size.must_equal 76
907
+ end
908
+
909
+ it "MultipartPartLimitError when request has too many multipart parts if limit set" do
910
+ begin
911
+ 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")
912
+ data += "--AaB03x--\r"
913
+
914
+ options = {
915
+ "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
916
+ "CONTENT_LENGTH" => data.length.to_s,
917
+ :input => StringIO.new(data)
918
+ }
919
+
920
+ request = make_request Rack::MockRequest.env_for("/", options)
921
+ lambda { request.POST }.must_raise Rack::Multipart::MultipartPartLimitError
922
+ end
762
923
  end
763
924
 
764
- should "MultipartPartLimitError when request has too many multipart parts if limit set" do
925
+ it 'closes tempfiles it created in the case of too many created' do
765
926
  begin
766
927
  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
928
  data += "--AaB03x--\r"
768
929
 
930
+ files = []
769
931
  options = {
770
932
  "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
771
933
  "CONTENT_LENGTH" => data.length.to_s,
934
+ Rack::RACK_MULTIPART_TEMPFILE_FACTORY => lambda { |filename, content_type|
935
+ file = Tempfile.new(["RackMultipart", ::File.extname(filename)])
936
+ files << file
937
+ file
938
+ },
772
939
  :input => StringIO.new(data)
773
940
  }
774
941
 
775
- request = Rack::Request.new Rack::MockRequest.env_for("/", options)
776
- lambda { request.POST }.should.raise(Rack::Multipart::MultipartPartLimitError)
942
+ request = make_request Rack::MockRequest.env_for("/", options)
943
+ assert_raises(Rack::Multipart::MultipartPartLimitError) do
944
+ request.POST
945
+ end
946
+ refute_predicate files, :empty?
947
+ files.each { |f| assert_predicate f, :closed? }
777
948
  end
778
949
  end
779
950
 
780
- should "parse big multipart form data" do
951
+ it "parse big multipart form data" do
781
952
  input = <<EOF
782
953
  --AaB03x\r
783
954
  content-disposition: form-data; name="huge"; filename="huge"\r
@@ -789,17 +960,17 @@ content-disposition: form-data; name="mean"; filename="mean"\r
789
960
  --AaB03xha\r
790
961
  --AaB03x--\r
791
962
  EOF
792
- req = Rack::Request.new Rack::MockRequest.env_for("/",
963
+ req = make_request Rack::MockRequest.env_for("/",
793
964
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
794
965
  "CONTENT_LENGTH" => input.size,
795
966
  :input => input)
796
967
 
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"
968
+ req.POST["huge"][:tempfile].size.must_equal 32768
969
+ req.POST["mean"][:tempfile].size.must_equal 10
970
+ req.POST["mean"][:tempfile].read.must_equal "--AaB03xha"
800
971
  end
801
972
 
802
- should "record tempfiles from multipart form data in env[rack.tempfiles]" do
973
+ it "record tempfiles from multipart form data in env[rack.tempfiles]" do
803
974
  input = <<EOF
804
975
  --AaB03x\r
805
976
  content-disposition: form-data; name="fileupload"; filename="foo.jpg"\r
@@ -819,22 +990,22 @@ EOF
819
990
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
820
991
  "CONTENT_LENGTH" => input.size,
821
992
  :input => input)
822
- req = Rack::Request.new(env)
993
+ req = make_request(env)
823
994
  req.params
824
- env['rack.tempfiles'].size.should.equal(2)
995
+ env['rack.tempfiles'].size.must_equal 2
825
996
  end
826
997
 
827
- should "detect invalid multipart form data" do
998
+ it "detect invalid multipart form data" do
828
999
  input = <<EOF
829
1000
  --AaB03x\r
830
1001
  content-disposition: form-data; name="huge"; filename="huge"\r
831
1002
  EOF
832
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1003
+ req = make_request Rack::MockRequest.env_for("/",
833
1004
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
834
1005
  "CONTENT_LENGTH" => input.size,
835
1006
  :input => input)
836
1007
 
837
- lambda { req.POST }.should.raise(EOFError)
1008
+ lambda { req.POST }.must_raise EOFError
838
1009
 
839
1010
  input = <<EOF
840
1011
  --AaB03x\r
@@ -842,12 +1013,12 @@ content-disposition: form-data; name="huge"; filename="huge"\r
842
1013
  \r
843
1014
  foo\r
844
1015
  EOF
845
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1016
+ req = make_request Rack::MockRequest.env_for("/",
846
1017
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
847
1018
  "CONTENT_LENGTH" => input.size,
848
1019
  :input => input)
849
1020
 
850
- lambda { req.POST }.should.raise(EOFError)
1021
+ lambda { req.POST }.must_raise EOFError
851
1022
 
852
1023
  input = <<EOF
853
1024
  --AaB03x\r
@@ -855,29 +1026,29 @@ content-disposition: form-data; name="huge"; filename="huge"\r
855
1026
  \r
856
1027
  foo\r
857
1028
  EOF
858
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1029
+ req = make_request Rack::MockRequest.env_for("/",
859
1030
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
860
1031
  "CONTENT_LENGTH" => input.size,
861
1032
  :input => input)
862
1033
 
863
- lambda { req.POST }.should.raise(EOFError)
1034
+ lambda { req.POST }.must_raise EOFError
864
1035
  end
865
1036
 
866
- should "consistently raise EOFError on bad multipart form data" do
1037
+ it "consistently raise EOFError on bad multipart form data" do
867
1038
  input = <<EOF
868
1039
  --AaB03x\r
869
1040
  content-disposition: form-data; name="huge"; filename="huge"\r
870
1041
  EOF
871
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1042
+ req = make_request Rack::MockRequest.env_for("/",
872
1043
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
873
1044
  "CONTENT_LENGTH" => input.size,
874
1045
  :input => input)
875
1046
 
876
- lambda { req.POST }.should.raise(EOFError)
877
- lambda { req.POST }.should.raise(EOFError)
1047
+ lambda { req.POST }.must_raise EOFError
1048
+ lambda { req.POST }.must_raise EOFError
878
1049
  end
879
1050
 
880
- should "correctly parse the part name from Content-Id header" do
1051
+ it "correctly parse the part name from Content-Id header" do
881
1052
  input = <<EOF
882
1053
  --AaB03x\r
883
1054
  Content-Type: text/xml; charset=utf-8\r
@@ -887,20 +1058,15 @@ Content-Transfer-Encoding: 7bit\r
887
1058
  foo\r
888
1059
  --AaB03x--\r
889
1060
  EOF
890
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1061
+ req = make_request Rack::MockRequest.env_for("/",
891
1062
  "CONTENT_TYPE" => "multipart/related, boundary=AaB03x",
892
1063
  "CONTENT_LENGTH" => input.size,
893
1064
  :input => input)
894
1065
 
895
- req.params.keys.should.equal ["<soap-start>"]
1066
+ req.params.keys.must_equal ["<soap-start>"]
896
1067
  end
897
1068
 
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
-
1069
+ it "not try to interpret binary as utf8" do
904
1070
  input = <<EOF
905
1071
  --AaB03x\r
906
1072
  content-disposition: form-data; name="fileupload"; filename="junk.a"\r
@@ -910,77 +1076,33 @@ content-type: application/octet-stream\r
910
1076
  --AaB03x--\r
911
1077
  EOF
912
1078
 
913
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1079
+ req = make_request Rack::MockRequest.env_for("/",
914
1080
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
915
1081
  "CONTENT_LENGTH" => input.size,
916
1082
  :input => input)
917
1083
 
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
1084
+ req.POST["fileupload"][:tempfile].size.must_equal 4
941
1085
  end
942
1086
 
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
1087
+ it "use form_hash when form_input is a Tempfile" do
966
1088
  input = "{foo: 'bar'}"
967
1089
 
968
1090
  rack_input = Tempfile.new("rackspec")
969
1091
  rack_input.write(input)
970
1092
  rack_input.rewind
971
1093
 
972
- req = Rack::Request.new Rack::MockRequest.env_for("/",
1094
+ req = make_request Rack::MockRequest.env_for("/",
973
1095
  "rack.request.form_hash" => {'foo' => 'bar'},
974
1096
  "rack.request.form_input" => rack_input,
975
1097
  :input => rack_input)
976
1098
 
977
- req.POST.should.equal(req.env['rack.request.form_hash'])
1099
+ req.POST.must_equal req.env['rack.request.form_hash']
978
1100
  end
979
1101
 
980
- should "conform to the Rack spec" do
1102
+ it "conform to the Rack spec" do
981
1103
  app = lambda { |env|
982
- content = Rack::Request.new(env).POST["file"].inspect
983
- size = content.respond_to?(:bytesize) ? content.bytesize : content.size
1104
+ content = make_request(env).POST["file"].inspect
1105
+ size = content.bytesize
984
1106
  [200, {"Content-Type" => "text/html", "Content-Length" => size.to_s}, [content]]
985
1107
  }
986
1108
 
@@ -997,149 +1119,151 @@ Content-Transfer-Encoding: base64\r
997
1119
  /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
998
1120
  --AaB03x--\r
999
1121
  EOF
1000
- input.force_encoding("ASCII-8BIT") if input.respond_to? :force_encoding
1122
+ input.force_encoding(Encoding::ASCII_8BIT)
1001
1123
  res = Rack::MockRequest.new(Rack::Lint.new(app)).get "/",
1002
1124
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
1003
1125
  "CONTENT_LENGTH" => input.size.to_s, "rack.input" => StringIO.new(input)
1004
1126
 
1005
- res.should.be.ok
1127
+ res.must_be :ok?
1006
1128
  end
1007
1129
 
1008
- should "parse Accept-Encoding correctly" do
1130
+ it "parse Accept-Encoding correctly" do
1009
1131
  parser = lambda do |x|
1010
- Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => x)).accept_encoding
1132
+ make_request(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => x)).accept_encoding
1011
1133
  end
1012
1134
 
1013
- parser.call(nil).should.equal([])
1135
+ parser.call(nil).must_equal []
1014
1136
 
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] ])
1137
+ parser.call("compress, gzip").must_equal [["compress", 1.0], ["gzip", 1.0]]
1138
+ parser.call("").must_equal []
1139
+ parser.call("*").must_equal [["*", 1.0]]
1140
+ parser.call("compress;q=0.5, gzip;q=1.0").must_equal [["compress", 0.5], ["gzip", 1.0]]
1141
+ parser.call("gzip;q=1.0, identity; q=0.5, *;q=0").must_equal [["gzip", 1.0], ["identity", 0.5], ["*", 0] ]
1020
1142
 
1021
- parser.call("gzip ; q=0.9").should.equal([["gzip", 0.9]])
1022
- parser.call("gzip ; deflate").should.equal([["gzip", 1.0]])
1143
+ parser.call("gzip ; q=0.9").must_equal [["gzip", 0.9]]
1144
+ parser.call("gzip ; deflate").must_equal [["gzip", 1.0]]
1023
1145
  end
1024
1146
 
1025
- should "parse Accept-Language correctly" do
1147
+ it "parse Accept-Language correctly" do
1026
1148
  parser = lambda do |x|
1027
- Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_LANGUAGE" => x)).accept_language
1149
+ make_request(Rack::MockRequest.env_for("", "HTTP_ACCEPT_LANGUAGE" => x)).accept_language
1028
1150
  end
1029
1151
 
1030
- parser.call(nil).should.equal([])
1152
+ parser.call(nil).must_equal []
1031
1153
 
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] ])
1154
+ parser.call("fr, en").must_equal [["fr", 1.0], ["en", 1.0]]
1155
+ parser.call("").must_equal []
1156
+ parser.call("*").must_equal [["*", 1.0]]
1157
+ parser.call("fr;q=0.5, en;q=1.0").must_equal [["fr", 0.5], ["en", 1.0]]
1158
+ parser.call("fr;q=1.0, en; q=0.5, *;q=0").must_equal [["fr", 1.0], ["en", 0.5], ["*", 0] ]
1037
1159
 
1038
- parser.call("fr ; q=0.9").should.equal([["fr", 0.9]])
1039
- parser.call("fr").should.equal([["fr", 1.0]])
1160
+ parser.call("fr ; q=0.9").must_equal [["fr", 0.9]]
1161
+ parser.call("fr").must_equal [["fr", 1.0]]
1040
1162
  end
1041
1163
 
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
- }
1164
+ def ip_app
1165
+ lambda { |env|
1166
+ request = make_request(env)
1167
+ response = Rack::Response.new
1168
+ response.write request.ip
1169
+ response.finish
1170
+ }
1171
+ end
1048
1172
 
1049
- should 'provide ip information' do
1173
+ it 'provide ip information' do
1050
1174
  mock = Rack::MockRequest.new(Rack::Lint.new(ip_app))
1051
1175
 
1052
1176
  res = mock.get '/', 'REMOTE_ADDR' => '1.2.3.4'
1053
- res.body.should.equal '1.2.3.4'
1177
+ res.body.must_equal '1.2.3.4'
1054
1178
 
1055
1179
  res = mock.get '/', 'REMOTE_ADDR' => 'fe80::202:b3ff:fe1e:8329'
1056
- res.body.should.equal 'fe80::202:b3ff:fe1e:8329'
1180
+ res.body.must_equal 'fe80::202:b3ff:fe1e:8329'
1057
1181
 
1058
1182
  res = mock.get '/', 'REMOTE_ADDR' => '1.2.3.4,3.4.5.6'
1059
- res.body.should.equal '1.2.3.4'
1183
+ res.body.must_equal '1.2.3.4'
1060
1184
  end
1061
1185
 
1062
- should 'deals with proxies' do
1186
+ it 'deals with proxies' do
1063
1187
  mock = Rack::MockRequest.new(Rack::Lint.new(ip_app))
1064
1188
 
1065
1189
  res = mock.get '/',
1066
1190
  'REMOTE_ADDR' => '1.2.3.4',
1067
1191
  'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
1068
- res.body.should.equal '1.2.3.4'
1192
+ res.body.must_equal '1.2.3.4'
1069
1193
 
1070
1194
  res = mock.get '/',
1071
1195
  'REMOTE_ADDR' => '1.2.3.4',
1072
1196
  'HTTP_X_FORWARDED_FOR' => 'unknown'
1073
- res.body.should.equal '1.2.3.4'
1197
+ res.body.must_equal '1.2.3.4'
1074
1198
 
1075
1199
  res = mock.get '/',
1076
1200
  'REMOTE_ADDR' => '127.0.0.1',
1077
1201
  'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
1078
- res.body.should.equal '3.4.5.6'
1202
+ res.body.must_equal '3.4.5.6'
1079
1203
 
1080
1204
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => 'unknown,3.4.5.6'
1081
- res.body.should.equal '3.4.5.6'
1205
+ res.body.must_equal '3.4.5.6'
1082
1206
 
1083
1207
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '192.168.0.1,3.4.5.6'
1084
- res.body.should.equal '3.4.5.6'
1208
+ res.body.must_equal '3.4.5.6'
1085
1209
 
1086
1210
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '10.0.0.1,3.4.5.6'
1087
- res.body.should.equal '3.4.5.6'
1211
+ res.body.must_equal '3.4.5.6'
1088
1212
 
1089
1213
  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'
1214
+ res.body.must_equal '3.4.5.6'
1091
1215
 
1092
1216
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '127.0.0.1, 3.4.5.6'
1093
- res.body.should.equal '3.4.5.6'
1217
+ res.body.must_equal '3.4.5.6'
1094
1218
 
1095
1219
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => 'unknown,192.168.0.1'
1096
- res.body.should.equal 'unknown'
1220
+ res.body.must_equal 'unknown'
1097
1221
 
1098
1222
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => 'other,unknown,192.168.0.1'
1099
- res.body.should.equal 'unknown'
1223
+ res.body.must_equal 'unknown'
1100
1224
 
1101
1225
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => 'unknown,localhost,192.168.0.1'
1102
- res.body.should.equal 'unknown'
1226
+ res.body.must_equal 'unknown'
1103
1227
 
1104
1228
  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'
1229
+ res.body.must_equal '3.4.5.6'
1106
1230
 
1107
1231
  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'
1232
+ res.body.must_equal '2620:0:1c00:0:812c:9583:754b:ca11'
1109
1233
 
1110
1234
  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'
1235
+ res.body.must_equal '2620:0:1c00:0:812c:9583:754b:ca11'
1112
1236
 
1113
1237
  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'
1238
+ res.body.must_equal '2620:0:1c00:0:812c:9583:754b:ca11'
1115
1239
 
1116
1240
  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'
1241
+ res.body.must_equal '2620:0:1c00:0:812c:9583:754b:ca11'
1118
1242
 
1119
1243
  res = mock.get '/',
1120
1244
  'HTTP_X_FORWARDED_FOR' => '1.1.1.1, 127.0.0.1',
1121
1245
  'HTTP_CLIENT_IP' => '1.1.1.1'
1122
- res.body.should.equal '1.1.1.1'
1246
+ res.body.must_equal '1.1.1.1'
1123
1247
 
1124
1248
  res = mock.get '/', 'HTTP_X_FORWARDED_FOR' => '8.8.8.8, 9.9.9.9'
1125
- res.body.should.equal '9.9.9.9'
1249
+ res.body.must_equal '9.9.9.9'
1126
1250
 
1127
1251
  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'
1252
+ res.body.must_equal 'fe80::202:b3ff:fe1e:8329'
1129
1253
 
1130
1254
  # Unix Sockets
1131
1255
  res = mock.get '/',
1132
1256
  'REMOTE_ADDR' => 'unix',
1133
1257
  'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
1134
- res.body.should.equal '3.4.5.6'
1258
+ res.body.must_equal '3.4.5.6'
1135
1259
 
1136
1260
  res = mock.get '/',
1137
1261
  'REMOTE_ADDR' => 'unix:/tmp/foo',
1138
1262
  'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
1139
- res.body.should.equal '3.4.5.6'
1263
+ res.body.must_equal '3.4.5.6'
1140
1264
  end
1141
1265
 
1142
- should "not allow IP spoofing via Client-IP and X-Forwarded-For headers" do
1266
+ it "not allow IP spoofing via Client-IP and X-Forwarded-For headers" do
1143
1267
  mock = Rack::MockRequest.new(Rack::Lint.new(ip_app))
1144
1268
 
1145
1269
  # IP Spoofing attempt:
@@ -1154,31 +1278,36 @@ EOF
1154
1278
  res = mock.get '/',
1155
1279
  'HTTP_X_FORWARDED_FOR' => '6.6.6.6, 2.2.2.3, 192.168.0.7',
1156
1280
  '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
1281
+ res.body.must_equal '2.2.2.3'
1282
+ end
1283
+
1284
+ it "regard local addresses as proxies" do
1285
+ req = make_request(Rack::MockRequest.env_for("/"))
1286
+ req.trusted_proxy?('127.0.0.1').must_equal 0
1287
+ req.trusted_proxy?('10.0.0.1').must_equal 0
1288
+ req.trusted_proxy?('172.16.0.1').must_equal 0
1289
+ req.trusted_proxy?('172.20.0.1').must_equal 0
1290
+ req.trusted_proxy?('172.30.0.1').must_equal 0
1291
+ req.trusted_proxy?('172.31.0.1').must_equal 0
1292
+ req.trusted_proxy?('192.168.0.1').must_equal 0
1293
+ req.trusted_proxy?('::1').must_equal 0
1294
+ req.trusted_proxy?('fd00::').must_equal 0
1295
+ req.trusted_proxy?('localhost').must_equal 0
1296
+ req.trusted_proxy?('unix').must_equal 0
1297
+ req.trusted_proxy?('unix:/tmp/sock').must_equal 0
1298
+
1299
+ req.trusted_proxy?("unix.example.org").must_equal nil
1300
+ req.trusted_proxy?("example.org\n127.0.0.1").must_equal nil
1301
+ req.trusted_proxy?("127.0.0.1\nexample.org").must_equal nil
1302
+ req.trusted_proxy?("11.0.0.1").must_equal nil
1303
+ req.trusted_proxy?("172.15.0.1").must_equal nil
1304
+ req.trusted_proxy?("172.32.0.1").must_equal nil
1305
+ req.trusted_proxy?("2001:470:1f0b:18f8::1").must_equal nil
1306
+ end
1307
+
1308
+ it "sets the default session to an empty hash" do
1309
+ req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
1310
+ assert_equal Hash.new, req.session
1182
1311
  end
1183
1312
 
1184
1313
  class MyRequest < Rack::Request
@@ -1187,46 +1316,78 @@ EOF
1187
1316
  end
1188
1317
  end
1189
1318
 
1190
- should "allow subclass request to be instantiated after parent request" do
1319
+ it "allow subclass request to be instantiated after parent request" do
1191
1320
  env = Rack::MockRequest.env_for("/?foo=bar")
1192
1321
 
1193
- req1 = Rack::Request.new(env)
1194
- req1.GET.should.equal "foo" => "bar"
1195
- req1.params.should.equal "foo" => "bar"
1322
+ req1 = make_request(env)
1323
+ req1.GET.must_equal "foo" => "bar"
1324
+ req1.params.must_equal "foo" => "bar"
1196
1325
 
1197
1326
  req2 = MyRequest.new(env)
1198
- req2.GET.should.equal "foo" => "bar"
1199
- req2.params.should.equal :foo => "bar"
1327
+ req2.GET.must_equal "foo" => "bar"
1328
+ req2.params.must_equal :foo => "bar"
1200
1329
  end
1201
1330
 
1202
- should "allow parent request to be instantiated after subclass request" do
1331
+ it "allow parent request to be instantiated after subclass request" do
1203
1332
  env = Rack::MockRequest.env_for("/?foo=bar")
1204
1333
 
1205
1334
  req1 = MyRequest.new(env)
1206
- req1.GET.should.equal "foo" => "bar"
1207
- req1.params.should.equal :foo => "bar"
1335
+ req1.GET.must_equal "foo" => "bar"
1336
+ req1.params.must_equal :foo => "bar"
1208
1337
 
1209
- req2 = Rack::Request.new(env)
1210
- req2.GET.should.equal "foo" => "bar"
1211
- req2.params.should.equal "foo" => "bar"
1338
+ req2 = make_request(env)
1339
+ req2.GET.must_equal "foo" => "bar"
1340
+ req2.params.must_equal "foo" => "bar"
1212
1341
  end
1213
1342
 
1214
- should "raise TypeError every time if request parameters are broken" do
1343
+ it "raise TypeError every time if request parameters are broken" do
1215
1344
  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)
1345
+ req = make_request(broken_query)
1346
+ lambda{req.GET}.must_raise TypeError
1347
+ lambda{req.params}.must_raise TypeError
1219
1348
  end
1220
1349
 
1221
1350
  (0x20...0x7E).collect { |a|
1222
1351
  b = a.chr
1223
1352
  c = CGI.escape(b)
1224
- should "not strip '#{a}' => '#{c}' => '#{b}' escaped character from parameters when accessed as string" do
1353
+ it "not strip '#{a}' => '#{c}' => '#{b}' escaped character from parameters when accessed as string" do
1225
1354
  url = "/?foo=#{c}bar#{c}"
1226
1355
  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}"
1356
+ req2 = make_request(env)
1357
+ req2.GET.must_equal "foo" => "#{b}bar#{b}"
1358
+ req2.params.must_equal "foo" => "#{b}bar#{b}"
1230
1359
  end
1231
1360
  }
1361
+
1362
+ class NonDelegate < Rack::Request
1363
+ def delegate?; false; end
1364
+ end
1365
+
1366
+ def make_request(env)
1367
+ NonDelegate.new env
1368
+ end
1369
+
1370
+ class TestProxyRequest < RackRequestTest
1371
+ class DelegateRequest
1372
+ include Rack::Request::Helpers
1373
+ extend Forwardable
1374
+
1375
+ def_delegators :@req, :has_header?, :get_header, :fetch_header,
1376
+ :each_header, :set_header, :add_header, :delete_header
1377
+
1378
+ def_delegators :@req, :[], :[]=, :values_at
1379
+
1380
+ def initialize(req)
1381
+ @req = req
1382
+ end
1383
+
1384
+ def delegate?; true; end
1385
+
1386
+ def env; @req.env.dup; end
1387
+ end
1388
+
1389
+ def make_request(env)
1390
+ DelegateRequest.new super(env)
1391
+ end
1392
+ end
1232
1393
  end