rack 1.1.6 → 1.2.0

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 (105) hide show
  1. data/README +9 -205
  2. data/SPEC +3 -3
  3. data/lib/rack.rb +1 -24
  4. data/lib/rack/auth/abstract/request.rb +1 -5
  5. data/lib/rack/auth/digest/md5.rb +1 -2
  6. data/lib/rack/auth/digest/params.rb +1 -1
  7. data/lib/rack/content_length.rb +1 -1
  8. data/lib/rack/etag.rb +15 -6
  9. data/lib/rack/file.rb +3 -1
  10. data/lib/rack/handler/cgi.rb +8 -7
  11. data/lib/rack/handler/fastcgi.rb +1 -1
  12. data/lib/rack/handler/lsws.rb +1 -1
  13. data/lib/rack/handler/mongrel.rb +1 -1
  14. data/lib/rack/handler/scgi.rb +1 -4
  15. data/lib/rack/handler/webrick.rb +10 -6
  16. data/lib/rack/lint.rb +29 -37
  17. data/lib/rack/mime.rb +2 -0
  18. data/lib/rack/mock.rb +2 -1
  19. data/lib/rack/recursive.rb +4 -0
  20. data/lib/rack/request.rb +8 -6
  21. data/lib/rack/response.rb +1 -0
  22. data/lib/rack/rewindable_input.rb +13 -10
  23. data/lib/rack/sendfile.rb +8 -6
  24. data/lib/rack/server.rb +68 -9
  25. data/lib/rack/session/cookie.rb +1 -10
  26. data/lib/rack/session/memcache.rb +1 -1
  27. data/lib/rack/urlmap.rb +6 -7
  28. data/lib/rack/utils.rb +40 -71
  29. data/rack.gemspec +7 -11
  30. data/spec/cgi/lighttpd.conf +25 -0
  31. data/spec/cgi/rackup_stub.rb +6 -0
  32. data/spec/cgi/sample_rackup.ru +5 -0
  33. data/spec/cgi/test +9 -0
  34. data/spec/cgi/test.fcgi +8 -0
  35. data/spec/cgi/test.ru +5 -0
  36. data/spec/multipart/bad_robots +259 -0
  37. data/spec/multipart/binary +0 -0
  38. data/spec/multipart/empty +10 -0
  39. data/spec/multipart/fail_16384_nofile +814 -0
  40. data/spec/multipart/file1.txt +1 -0
  41. data/spec/multipart/filename_and_modification_param +7 -0
  42. data/spec/multipart/filename_with_escaped_quotes +6 -0
  43. data/spec/multipart/filename_with_escaped_quotes_and_modification_param +7 -0
  44. data/spec/multipart/filename_with_percent_escaped_quotes +6 -0
  45. data/spec/multipart/filename_with_unescaped_quotes +6 -0
  46. data/spec/multipart/ie +6 -0
  47. data/spec/multipart/nested +10 -0
  48. data/spec/multipart/none +9 -0
  49. data/spec/multipart/semicolon +6 -0
  50. data/spec/multipart/text +10 -0
  51. data/spec/rackup/config.ru +31 -0
  52. data/{test/spec_rack_auth_basic.rb → spec/spec_auth_basic.rb} +11 -14
  53. data/{test/spec_rack_auth_digest.rb → spec/spec_auth_digest.rb} +18 -27
  54. data/{test/spec_rack_builder.rb → spec/spec_builder.rb} +49 -10
  55. data/{test/spec_rack_cascade.rb → spec/spec_cascade.rb} +7 -10
  56. data/{test/spec_rack_cgi.rb → spec/spec_cgi.rb} +34 -32
  57. data/{test/spec_rack_chunked.rb → spec/spec_chunked.rb} +8 -10
  58. data/{test/spec_rack_commonlogger.rb → spec/spec_commonlogger.rb} +10 -15
  59. data/{test/spec_rack_conditionalget.rb → spec/spec_conditionalget.rb} +5 -7
  60. data/{test/spec_rack_config.rb → spec/spec_config.rb} +6 -7
  61. data/{test/spec_rack_content_length.rb → spec/spec_content_length.rb} +7 -8
  62. data/{test/spec_rack_content_type.rb → spec/spec_content_type.rb} +5 -6
  63. data/{test/spec_rack_deflater.rb → spec/spec_deflater.rb} +11 -13
  64. data/{test/spec_rack_directory.rb → spec/spec_directory.rb} +6 -10
  65. data/{test/spec_rack_etag.rb → spec/spec_etag.rb} +3 -5
  66. data/{test/spec_rack_fastcgi.rb → spec/spec_fastcgi.rb} +36 -29
  67. data/{test/spec_rack_file.rb → spec/spec_file.rb} +9 -13
  68. data/{test/spec_rack_handler.rb → spec/spec_handler.rb} +10 -12
  69. data/{test/spec_rack_head.rb → spec/spec_head.rb} +3 -3
  70. data/{test/spec_rack_lint.rb → spec/spec_lint.rb} +19 -32
  71. data/{test/spec_rack_lobster.rb → spec/spec_lobster.rb} +9 -11
  72. data/{test/spec_rack_lock.rb → spec/spec_lock.rb} +15 -17
  73. data/{test/spec_rack_logger.rb → spec/spec_logger.rb} +6 -7
  74. data/{test/spec_rack_methodoverride.rb → spec/spec_methodoverride.rb} +15 -17
  75. data/{test/spec_rack_mock.rb → spec/spec_mock.rb} +30 -32
  76. data/{test/spec_rack_mongrel.rb → spec/spec_mongrel.rb} +40 -46
  77. data/{test/spec_rack_nulllogger.rb → spec/spec_nulllogger.rb} +4 -5
  78. data/{test/spec_rack_recursive.rb → spec/spec_recursive.rb} +28 -36
  79. data/{test/spec_rack_request.rb → spec/spec_request.rb} +84 -98
  80. data/{test/spec_rack_response.rb → spec/spec_response.rb} +46 -27
  81. data/spec/spec_rewindable_input.rb +118 -0
  82. data/{test/spec_rack_runtime.rb → spec/spec_runtime.rb} +15 -11
  83. data/{test/spec_rack_sendfile.rb → spec/spec_sendfile.rb} +11 -14
  84. data/{test/spec_rack_session_cookie.rb → spec/spec_session_cookie.rb} +14 -36
  85. data/{test/spec_rack_session_memcache.rb → spec/spec_session_memcache.rb} +32 -26
  86. data/{test/spec_rack_session_pool.rb → spec/spec_session_pool.rb} +36 -31
  87. data/spec/spec_showexceptions.rb +23 -0
  88. data/spec/spec_showstatus.rb +79 -0
  89. data/{test/spec_rack_static.rb → spec/spec_static.rb} +5 -9
  90. data/{test/spec_rack_thin.rb → spec/spec_thin.rb} +30 -35
  91. data/{test/spec_rack_urlmap.rb → spec/spec_urlmap.rb} +6 -8
  92. data/{test/spec_rack_utils.rb → spec/spec_utils.rb} +134 -74
  93. data/{test/spec_rack_webrick.rb → spec/spec_webrick.rb} +28 -36
  94. data/spec/testrequest.rb +77 -0
  95. data/spec/unregistered_handler/rack/handler/unregistered.rb +7 -0
  96. data/spec/unregistered_handler/rack/handler/unregistered_long_one.rb +7 -0
  97. metadata +176 -191
  98. data/RDOX +0 -0
  99. data/lib/rack/adapter/camping.rb +0 -22
  100. data/test/spec_auth.rb +0 -57
  101. data/test/spec_rack_camping.rb +0 -55
  102. data/test/spec_rack_rewindable_input.rb +0 -118
  103. data/test/spec_rack_showexceptions.rb +0 -21
  104. data/test/spec_rack_showstatus.rb +0 -72
  105. data/test/spec_rackup.rb +0 -164
@@ -1,13 +1,12 @@
1
1
  require 'rack/nulllogger'
2
- require 'rack/lint'
3
- require 'rack/mock'
4
2
 
5
- context "Rack::NullLogger" do
6
- specify "acks as a nop logger" do
3
+ describe Rack::NullLogger do
4
+ should "act as a noop logger" do
7
5
  app = lambda { |env|
8
6
  env['rack.logger'].warn "b00m"
9
7
  [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]]
10
8
  }
11
- Rack::NullLogger.new(app).call({})
9
+ logger = Rack::NullLogger.new(app)
10
+ lambda{ logger.call({}) }.should.not.raise
12
11
  end
13
12
  end
@@ -1,53 +1,45 @@
1
- require 'test/spec'
2
-
3
1
  require 'rack/recursive'
4
- require 'rack/urlmap'
5
- require 'rack/response'
6
2
  require 'rack/mock'
7
3
 
8
- context "Rack::Recursive" do
9
- setup do
10
-
11
- @app1 = lambda { |env|
12
- res = Rack::Response.new
13
- res["X-Path-Info"] = env["PATH_INFO"]
14
- res["X-Query-String"] = env["QUERY_STRING"]
15
- res.finish do |res|
16
- res.write "App1"
17
- end
18
- }
4
+ describe Rack::Recursive do
5
+ @app1 = lambda { |env|
6
+ res = Rack::Response.new
7
+ res["X-Path-Info"] = env["PATH_INFO"]
8
+ res["X-Query-String"] = env["QUERY_STRING"]
9
+ res.finish do |inner_res|
10
+ inner_res.write "App1"
11
+ end
12
+ }
19
13
 
20
- @app2 = lambda { |env|
21
- Rack::Response.new.finish do |res|
22
- res.write "App2"
23
- _, _, body = env['rack.recursive.include'].call(env, "/app1")
24
- body.each { |b|
25
- res.write b
26
- }
27
- end
28
- }
14
+ @app2 = lambda { |env|
15
+ Rack::Response.new.finish do |res|
16
+ res.write "App2"
17
+ _, _, body = env['rack.recursive.include'].call(env, "/app1")
18
+ body.each { |b|
19
+ res.write b
20
+ }
21
+ end
22
+ }
29
23
 
30
- @app3 = lambda { |env|
31
- raise Rack::ForwardRequest.new("/app1")
32
- }
24
+ @app3 = lambda { |env|
25
+ raise Rack::ForwardRequest.new("/app1")
26
+ }
33
27
 
34
- @app4 = lambda { |env|
35
- raise Rack::ForwardRequest.new("http://example.org/app1/quux?meh")
36
- }
37
-
38
- end
28
+ @app4 = lambda { |env|
29
+ raise Rack::ForwardRequest.new("http://example.org/app1/quux?meh")
30
+ }
39
31
 
40
- specify "should allow for subrequests" do
32
+ should "allow for subrequests" do
41
33
  res = Rack::MockRequest.new(Rack::Recursive.new(
42
34
  Rack::URLMap.new("/app1" => @app1,
43
35
  "/app2" => @app2))).
44
36
  get("/app2")
45
37
 
46
38
  res.should.be.ok
47
- res.body.should.equal "App2App1"
39
+ res.body.should.equal "App2App1"
48
40
  end
49
41
 
50
- specify "should raise error on requests not below the app" do
42
+ should "raise error on requests not below the app" do
51
43
  app = Rack::URLMap.new("/app1" => @app1,
52
44
  "/app" => Rack::Recursive.new(
53
45
  Rack::URLMap.new("/1" => @app1,
@@ -59,7 +51,7 @@ context "Rack::Recursive" do
59
51
  message.should =~ /can only include below/
60
52
  end
61
53
 
62
- specify "should support forwarding" do
54
+ should "support forwarding" do
63
55
  app = Rack::Recursive.new(Rack::URLMap.new("/app1" => @app1,
64
56
  "/app3" => @app3,
65
57
  "/app4" => @app4))
@@ -1,11 +1,10 @@
1
- require 'test/spec'
2
1
  require 'stringio'
3
-
2
+ require 'cgi'
4
3
  require 'rack/request'
5
4
  require 'rack/mock'
6
5
 
7
- context "Rack::Request" do
8
- specify "wraps the rack variables" do
6
+ describe Rack::Request do
7
+ should "wrap the rack variables" do
9
8
  req = Rack::Request.new(Rack::MockRequest.env_for("http://example.com:8080/"))
10
9
 
11
10
  req.body.should.respond_to? :gets
@@ -29,7 +28,7 @@ context "Rack::Request" do
29
28
  req.content_type.should.be.nil
30
29
  end
31
30
 
32
- specify "can figure out the correct host" do
31
+ should "figure out the correct host" do
33
32
  req = Rack::Request.new \
34
33
  Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org")
35
34
  req.host.should.equal "www2.example.org"
@@ -53,7 +52,7 @@ context "Rack::Request" do
53
52
  req.host.should.equal ""
54
53
  end
55
54
 
56
- specify "can parse the query string" do
55
+ should "parse the query string" do
57
56
  req = Rack::Request.new(Rack::MockRequest.env_for("/?foo=bar&quux=bla"))
58
57
  req.query_string.should.equal "foo=bar&quux=bla"
59
58
  req.GET.should.equal "foo" => "bar", "quux" => "bla"
@@ -61,12 +60,12 @@ context "Rack::Request" do
61
60
  req.params.should.equal "foo" => "bar", "quux" => "bla"
62
61
  end
63
62
 
64
- specify "raises if rack.input is missing" do
63
+ should "raise if rack.input is missing" do
65
64
  req = Rack::Request.new({})
66
65
  lambda { req.POST }.should.raise(RuntimeError)
67
66
  end
68
67
 
69
- specify "can parse POST data when method is POST and no Content-Type given" do
68
+ should "parse POST data when method is POST and no Content-Type given" do
70
69
  req = Rack::Request.new \
71
70
  Rack::MockRequest.env_for("/?foo=quux",
72
71
  "REQUEST_METHOD" => 'POST',
@@ -79,33 +78,7 @@ context "Rack::Request" do
79
78
  req.params.should.equal "foo" => "bar", "quux" => "bla"
80
79
  end
81
80
 
82
- specify "limit the keys from the GET query string" do
83
- env = Rack::MockRequest.env_for("/?foo=bar")
84
-
85
- old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
86
- begin
87
- req = Rack::Request.new(env)
88
- lambda { req.GET }.should.raise(RangeError)
89
- ensure
90
- Rack::Utils.key_space_limit = old
91
- end
92
- end
93
-
94
- specify "limit the keys from the POST form data" do
95
- env = Rack::MockRequest.env_for("",
96
- "REQUEST_METHOD" => 'POST',
97
- :input => "foo=bar&quux=bla")
98
-
99
- old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
100
- begin
101
- req = Rack::Request.new(env)
102
- lambda { req.POST }.should.raise(RangeError)
103
- ensure
104
- Rack::Utils.key_space_limit = old
105
- end
106
- end
107
-
108
- specify "can parse POST data with explicit content type regardless of method" do
81
+ should "parse POST data with explicit content type regardless of method" do
109
82
  req = Rack::Request.new \
110
83
  Rack::MockRequest.env_for("/",
111
84
  "CONTENT_TYPE" => 'application/x-www-form-urlencoded;foo=bar',
@@ -117,7 +90,7 @@ context "Rack::Request" do
117
90
  req.params.should.equal "foo" => "bar", "quux" => "bla"
118
91
  end
119
92
 
120
- specify "does not parse POST data when media type is not form-data" do
93
+ should "not parse POST data when media type is not form-data" do
121
94
  req = Rack::Request.new \
122
95
  Rack::MockRequest.env_for("/?foo=quux",
123
96
  "REQUEST_METHOD" => 'POST',
@@ -131,7 +104,7 @@ context "Rack::Request" do
131
104
  req.body.read.should.equal "foo=bar&quux=bla"
132
105
  end
133
106
 
134
- specify "can parse POST data on PUT when media type is form-data" do
107
+ should "parse POST data on PUT when media type is form-data" do
135
108
  req = Rack::Request.new \
136
109
  Rack::MockRequest.env_for("/?foo=quux",
137
110
  "REQUEST_METHOD" => 'PUT',
@@ -141,7 +114,7 @@ context "Rack::Request" do
141
114
  req.body.read.should.equal "foo=bar&quux=bla"
142
115
  end
143
116
 
144
- specify "rewinds input after parsing POST data" do
117
+ should "rewind input after parsing POST data" do
145
118
  input = StringIO.new("foo=bar&quux=bla")
146
119
  req = Rack::Request.new \
147
120
  Rack::MockRequest.env_for("/",
@@ -151,21 +124,21 @@ context "Rack::Request" do
151
124
  input.read.should.equal "foo=bar&quux=bla"
152
125
  end
153
126
 
154
- specify "cleans up Safari's ajax POST body" do
127
+ should "clean up Safari's ajax POST body" do
155
128
  req = Rack::Request.new \
156
129
  Rack::MockRequest.env_for("/",
157
130
  'REQUEST_METHOD' => 'POST', :input => "foo=bar&quux=bla\0")
158
131
  req.POST.should.equal "foo" => "bar", "quux" => "bla"
159
132
  end
160
133
 
161
- specify "can get value by key from params with #[]" do
134
+ should "get value by key from params with #[]" do
162
135
  req = Rack::Request.new \
163
136
  Rack::MockRequest.env_for("?foo=quux")
164
137
  req['foo'].should.equal 'quux'
165
138
  req[:foo].should.equal 'quux'
166
139
  end
167
140
 
168
- specify "can set value to key on params with #[]=" do
141
+ should "set value to key on params with #[]=" do
169
142
  req = Rack::Request.new \
170
143
  Rack::MockRequest.env_for("?foo=duh")
171
144
  req['foo'].should.equal 'duh'
@@ -183,7 +156,7 @@ context "Rack::Request" do
183
156
  req[:foo].should.equal 'jaz'
184
157
  end
185
158
 
186
- specify "values_at answers values by keys in order given" do
159
+ should "return values for the keys in the order given from values_at" do
187
160
  req = Rack::Request.new \
188
161
  Rack::MockRequest.env_for("?foo=baz&wun=der&bar=ful")
189
162
  req.values_at('foo').should.equal ['baz']
@@ -191,7 +164,7 @@ context "Rack::Request" do
191
164
  req.values_at('bar', 'foo', 'wun').should.equal ['ful', 'baz', 'der']
192
165
  end
193
166
 
194
- specify "referrer should be extracted correct" do
167
+ should "extract referrer correctly" do
195
168
  req = Rack::Request.new \
196
169
  Rack::MockRequest.env_for("/", "HTTP_REFERER" => "/some/path")
197
170
  req.referer.should.equal "/some/path"
@@ -201,7 +174,7 @@ context "Rack::Request" do
201
174
  req.referer.should.equal "/"
202
175
  end
203
176
 
204
- specify "user agent should be extracted correct" do
177
+ should "extract user agent correctly" do
205
178
  req = Rack::Request.new \
206
179
  Rack::MockRequest.env_for("/", "HTTP_USER_AGENT" => "Mozilla/4.0 (compatible)")
207
180
  req.user_agent.should.equal "Mozilla/4.0 (compatible)"
@@ -211,7 +184,7 @@ context "Rack::Request" do
211
184
  req.user_agent.should.equal nil
212
185
  end
213
186
 
214
- specify "can cache, but invalidates the cache" do
187
+ should "cache, but invalidates the cache" do
215
188
  req = Rack::Request.new \
216
189
  Rack::MockRequest.env_for("/?foo=quux",
217
190
  "CONTENT_TYPE" => "application/x-www-form-urlencoded",
@@ -229,7 +202,7 @@ context "Rack::Request" do
229
202
  req.POST.should.equal "foo" => "bla", "quux" => "bar"
230
203
  end
231
204
 
232
- specify "can figure out if called via XHR" do
205
+ should "figure out if called via XHR" do
233
206
  req = Rack::Request.new(Rack::MockRequest.env_for(""))
234
207
  req.should.not.be.xhr
235
208
 
@@ -238,7 +211,7 @@ context "Rack::Request" do
238
211
  req.should.be.xhr
239
212
  end
240
213
 
241
- specify "can parse cookies" do
214
+ should "parse cookies" do
242
215
  req = Rack::Request.new \
243
216
  Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m")
244
217
  req.cookies.should.equal "foo" => "bar", "quux" => "h&m"
@@ -247,13 +220,13 @@ context "Rack::Request" do
247
220
  req.cookies.should.equal({})
248
221
  end
249
222
 
250
- specify "parses cookies according to RFC 2109" do
223
+ should "parse cookies according to RFC 2109" do
251
224
  req = Rack::Request.new \
252
225
  Rack::MockRequest.env_for('', 'HTTP_COOKIE' => 'foo=bar;foo=car')
253
226
  req.cookies.should.equal 'foo' => 'bar'
254
227
  end
255
228
 
256
- specify "provides setters" do
229
+ should "provide setters" do
257
230
  req = Rack::Request.new(e=Rack::MockRequest.env_for(""))
258
231
  req.script_name.should.equal ""
259
232
  req.script_name = "/foo"
@@ -266,12 +239,12 @@ context "Rack::Request" do
266
239
  e["PATH_INFO"].should.equal "/foo"
267
240
  end
268
241
 
269
- specify "provides the original env" do
270
- req = Rack::Request.new(e=Rack::MockRequest.env_for(""))
271
- req.env.should.be e
242
+ should "provide the original env" do
243
+ req = Rack::Request.new(e = Rack::MockRequest.env_for(""))
244
+ req.env.should == e
272
245
  end
273
246
 
274
- specify "can restore the URL" do
247
+ should "restore the URL" do
275
248
  Rack::Request.new(Rack::MockRequest.env_for("")).url.
276
249
  should.equal "http://example.org/"
277
250
  Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).url.
@@ -289,7 +262,7 @@ context "Rack::Request" do
289
262
  should.equal "https://example.com:8080/foo?foo"
290
263
  end
291
264
 
292
- specify "can restore the full path" do
265
+ should "restore the full path" do
293
266
  Rack::Request.new(Rack::MockRequest.env_for("")).fullpath.
294
267
  should.equal "/"
295
268
  Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).fullpath.
@@ -307,7 +280,7 @@ context "Rack::Request" do
307
280
  should.equal "/foo?foo"
308
281
  end
309
282
 
310
- specify "can handle multiple media type parameters" do
283
+ should "handle multiple media type parameters" do
311
284
  req = Rack::Request.new \
312
285
  Rack::MockRequest.env_for("/",
313
286
  "CONTENT_TYPE" => 'text/plain; foo=BAR,baz=bizzle dizzle;BLING=bam')
@@ -321,30 +294,7 @@ context "Rack::Request" do
321
294
  req.media_type_params['bling'].should.equal 'bam'
322
295
  end
323
296
 
324
- specify "raise RangeError if the key space is exhausted" do
325
- input = <<EOF
326
- --AaB03x\r
327
- Content-Disposition: form-data; name="text"\r
328
- Content-Type: text/plain; charset=US-ASCII\r
329
- \r
330
- contents\r
331
- --AaB03x--\r
332
- EOF
333
-
334
- env = Rack::MockRequest.env_for("/",
335
- "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
336
- "CONTENT_LENGTH" => input.size,
337
- :input => input)
338
-
339
- old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
340
- begin
341
- lambda { Rack::Utils::Multipart.parse_multipart(env) }.should.raise(RangeError)
342
- ensure
343
- Rack::Utils.key_space_limit = old
344
- end
345
- end
346
-
347
- specify "can parse multipart form data" do
297
+ should "parse multipart form data" do
348
298
  # Adapted from RFC 1867.
349
299
  input = <<EOF
350
300
  --AaB03x\r
@@ -383,7 +333,7 @@ EOF
383
333
  f[:tempfile].size.should.equal 76
384
334
  end
385
335
 
386
- specify "can parse big multipart form data" do
336
+ should "parse big multipart form data" do
387
337
  input = <<EOF
388
338
  --AaB03x\r
389
339
  content-disposition: form-data; name="huge"; filename="huge"\r
@@ -405,7 +355,7 @@ EOF
405
355
  req.POST["mean"][:tempfile].read.should.equal "--AaB03xha"
406
356
  end
407
357
 
408
- specify "can detect invalid multipart form data" do
358
+ should "detect invalid multipart form data" do
409
359
  input = <<EOF
410
360
  --AaB03x\r
411
361
  content-disposition: form-data; name="huge"; filename="huge"\r
@@ -444,12 +394,33 @@ EOF
444
394
  lambda { req.POST }.should.raise(EOFError)
445
395
  end
446
396
 
447
- specify "shouldn't try to interpret binary as utf8" do
448
- begin
449
- original_kcode = $KCODE
450
- $KCODE='UTF8'
397
+ should "not try to interpret binary as utf8" do
398
+ if /regexp/.respond_to?(:kcode) # < 1.9
399
+ begin
400
+ original_kcode = $KCODE
401
+ $KCODE='UTF8'
402
+
403
+ input = <<EOF
404
+ --AaB03x\r
405
+ content-disposition: form-data; name="fileupload"; filename="junk.a"\r
406
+ content-type: application/octet-stream\r
407
+ \r
408
+ #{[0x36,0xCF,0x0A,0xF8].pack('c*')}\r
409
+ --AaB03x--\r
410
+ EOF
451
411
 
452
- input = <<EOF
412
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
413
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
414
+ "CONTENT_LENGTH" => input.size,
415
+ :input => input)
416
+
417
+ lambda{req.POST}.should.not.raise(EOFError)
418
+ req.POST["fileupload"][:tempfile].size.should.equal 4
419
+ ensure
420
+ $KCODE = original_kcode
421
+ end
422
+ else # >= 1.9
423
+ input = <<EOF
453
424
  --AaB03x\r
454
425
  content-disposition: form-data; name="fileupload"; filename="junk.a"\r
455
426
  content-type: application/octet-stream\r
@@ -465,13 +436,10 @@ EOF
465
436
 
466
437
  lambda{req.POST}.should.not.raise(EOFError)
467
438
  req.POST["fileupload"][:tempfile].size.should.equal 4
468
- ensure
469
- $KCODE = original_kcode
470
439
  end
471
440
  end
472
441
 
473
-
474
- specify "should work around buggy 1.8.* Tempfile equality" do
442
+ should "work around buggy 1.8.* Tempfile equality" do
475
443
  input = <<EOF
476
444
  --AaB03x\r
477
445
  content-disposition: form-data; name="huge"; filename="huge"\r
@@ -489,11 +457,11 @@ EOF
489
457
  "CONTENT_LENGTH" => input.size,
490
458
  :input => rack_input)
491
459
 
492
- lambda {req.POST}.should.not.raise
493
- lambda {req.POST}.should.blaming("input re-processed!").not.raise
460
+ lambda{ req.POST }.should.not.raise
461
+ lambda{ req.POST }.should.not.raise("input re-processed!")
494
462
  end
495
463
 
496
- specify "does conform to the Rack spec" do
464
+ should "conform to the Rack spec" do
497
465
  app = lambda { |env|
498
466
  content = Rack::Request.new(env).POST["file"].inspect
499
467
  size = content.respond_to?(:bytesize) ? content.bytesize : content.size
@@ -521,7 +489,7 @@ EOF
521
489
  res.should.be.ok
522
490
  end
523
491
 
524
- specify "should parse Accept-Encoding correctly" do
492
+ should "parse Accept-Encoding correctly" do
525
493
  parser = lambda do |x|
526
494
  Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => x)).accept_encoding
527
495
  end
@@ -537,7 +505,7 @@ EOF
537
505
  lambda { parser.call("gzip ; q=1.0") }.should.raise(RuntimeError)
538
506
  end
539
507
 
540
- specify 'should provide ip information' do
508
+ should 'provide ip information' do
541
509
  app = lambda { |env|
542
510
  request = Rack::Request.new(env)
543
511
  response = Rack::Response.new
@@ -559,7 +527,13 @@ EOF
559
527
  'REMOTE_ADDR' => '123.123.123.123',
560
528
  'HTTP_X_FORWARDED_FOR' => '234.234.234.234,212.212.212.212'
561
529
 
562
- res.body.should.equal '212.212.212.212'
530
+ res.body.should.equal '234.234.234.234'
531
+
532
+ res = mock.get '/',
533
+ 'REMOTE_ADDR' => '123.123.123.123',
534
+ 'HTTP_X_FORWARDED_FOR' => 'unknown,234.234.234.234,212.212.212.212'
535
+
536
+ res.body.should.equal '234.234.234.234'
563
537
  end
564
538
 
565
539
  class MyRequest < Rack::Request
@@ -568,7 +542,7 @@ EOF
568
542
  end
569
543
  end
570
544
 
571
- specify "should allow subclass request to be instantiated after parent request" do
545
+ should "allow subclass request to be instantiated after parent request" do
572
546
  env = Rack::MockRequest.env_for("/?foo=bar")
573
547
 
574
548
  req1 = Rack::Request.new(env)
@@ -580,7 +554,7 @@ EOF
580
554
  req2.params.should.equal :foo => "bar"
581
555
  end
582
556
 
583
- specify "should allow parent request to be instantiated after subclass request" do
557
+ should "allow parent request to be instantiated after subclass request" do
584
558
  env = Rack::MockRequest.env_for("/?foo=bar")
585
559
 
586
560
  req1 = MyRequest.new(env)
@@ -591,4 +565,16 @@ EOF
591
565
  req2.GET.should.equal "foo" => "bar"
592
566
  req2.params.should.equal "foo" => "bar"
593
567
  end
568
+
569
+ (0x20...0x7E).collect { |a|
570
+ b = a.chr
571
+ c = CGI.escape(b)
572
+ should "not strip '#{a}' => '#{c}' => '#{b}' escaped character from parameters when accessed as string" do
573
+ url = "/?foo=#{c}bar#{c}"
574
+ env = Rack::MockRequest.env_for(url)
575
+ req2 = Rack::Request.new(env)
576
+ req2.GET.should.equal "foo" => "#{b}bar#{b}"
577
+ req2.params.should.equal "foo" => "#{b}bar#{b}"
578
+ end
579
+ }
594
580
  end