rack 1.4.0 → 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. data/COPYING +1 -1
  2. data/KNOWN-ISSUES +9 -0
  3. data/README.rdoc +118 -4
  4. data/Rakefile +18 -11
  5. data/SPEC +3 -1
  6. data/contrib/rack.png +0 -0
  7. data/contrib/rack.svg +150 -0
  8. data/contrib/rdoc.css +412 -0
  9. data/lib/rack/auth/abstract/request.rb +5 -1
  10. data/lib/rack/auth/basic.rb +1 -1
  11. data/lib/rack/auth/digest/nonce.rb +1 -1
  12. data/lib/rack/backports/uri/common_18.rb +14 -28
  13. data/lib/rack/backports/uri/common_192.rb +14 -17
  14. data/lib/rack/backports/uri/common_193.rb +29 -0
  15. data/lib/rack/body_proxy.rb +15 -2
  16. data/lib/rack/builder.rb +1 -1
  17. data/lib/rack/cascade.rb +12 -1
  18. data/lib/rack/commonlogger.rb +18 -5
  19. data/lib/rack/deflater.rb +5 -1
  20. data/lib/rack/directory.rb +1 -1
  21. data/lib/rack/etag.rb +6 -3
  22. data/lib/rack/file.rb +20 -16
  23. data/lib/rack/head.rb +1 -0
  24. data/lib/rack/lint.rb +3 -1
  25. data/lib/rack/lock.rb +3 -4
  26. data/lib/rack/mime.rb +1 -1
  27. data/lib/rack/mock.rb +3 -2
  28. data/lib/rack/multipart/parser.rb +22 -20
  29. data/lib/rack/multipart.rb +2 -2
  30. data/lib/rack/reloader.rb +1 -1
  31. data/lib/rack/request.rb +4 -6
  32. data/lib/rack/response.rb +19 -17
  33. data/lib/rack/server.rb +28 -2
  34. data/lib/rack/session/abstract/id.rb +8 -3
  35. data/lib/rack/session/cookie.rb +20 -7
  36. data/lib/rack/showstatus.rb +2 -2
  37. data/lib/rack/static.rb +91 -9
  38. data/lib/rack/utils.rb +74 -36
  39. data/lib/rack.rb +13 -1
  40. data/rack.gemspec +3 -3
  41. data/test/builder/line.ru +1 -0
  42. data/test/cgi/assets/folder/test.js +1 -0
  43. data/test/cgi/assets/fonts/font.eot +1 -0
  44. data/test/cgi/assets/images/image.png +1 -0
  45. data/test/cgi/assets/index.html +1 -0
  46. data/test/cgi/assets/javascripts/app.js +1 -0
  47. data/test/cgi/assets/stylesheets/app.css +1 -0
  48. data/test/multipart/filename_with_unescaped_percentages +6 -0
  49. data/test/multipart/filename_with_unescaped_percentages2 +6 -0
  50. data/test/multipart/filename_with_unescaped_percentages3 +6 -0
  51. data/test/spec_auth.rb +57 -0
  52. data/test/spec_auth_basic.rb +8 -0
  53. data/test/spec_auth_digest.rb +14 -0
  54. data/test/spec_body_proxy.rb +21 -0
  55. data/test/spec_builder.rb +7 -1
  56. data/test/spec_cascade.rb +14 -3
  57. data/test/spec_chunked.rb +6 -6
  58. data/test/spec_config.rb +0 -1
  59. data/test/spec_content_length.rb +26 -13
  60. data/test/spec_content_type.rb +15 -5
  61. data/test/spec_deflater.rb +35 -17
  62. data/test/spec_directory.rb +20 -1
  63. data/test/spec_etag.rb +29 -13
  64. data/test/spec_file.rb +58 -30
  65. data/test/spec_head.rb +25 -7
  66. data/test/spec_lobster.rb +20 -5
  67. data/test/spec_lock.rb +46 -21
  68. data/test/spec_logger.rb +2 -7
  69. data/test/spec_methodoverride.rb +21 -22
  70. data/test/spec_mock.rb +12 -7
  71. data/test/spec_multipart.rb +129 -2
  72. data/test/spec_nulllogger.rb +13 -2
  73. data/test/spec_recursive.rb +12 -9
  74. data/test/spec_request.rb +15 -2
  75. data/test/spec_response.rb +41 -3
  76. data/test/spec_runtime.rb +15 -5
  77. data/test/spec_sendfile.rb +13 -9
  78. data/test/spec_server.rb +47 -0
  79. data/test/spec_session_cookie.rb +93 -3
  80. data/test/spec_session_memcache.rb +10 -8
  81. data/test/spec_session_pool.rb +13 -10
  82. data/test/spec_showexceptions.rb +9 -4
  83. data/test/spec_showstatus.rb +10 -5
  84. data/test/spec_static.rb +89 -8
  85. data/test/spec_urlmap.rb +10 -10
  86. data/test/spec_utils.rb +34 -7
  87. data/test/static/another/index.html +1 -0
  88. metadata +26 -8
data/test/spec_request.rb CHANGED
@@ -137,6 +137,19 @@ describe Rack::Request do
137
137
  end
138
138
  end
139
139
 
140
+ should "limit the key size per nested params hash" do
141
+ nested_query = Rack::MockRequest.env_for("/?foo[bar][baz][qux]=1")
142
+ plain_query = Rack::MockRequest.env_for("/?foo_bar__baz__qux_=1")
143
+
144
+ old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 3
145
+ begin
146
+ lambda { Rack::Request.new(nested_query).GET }.should.not.raise(RangeError)
147
+ lambda { Rack::Request.new(plain_query).GET }.should.raise(RangeError)
148
+ ensure
149
+ Rack::Utils.key_space_limit = old
150
+ end
151
+ end
152
+
140
153
  should "not unify GET and POST when calling params" do
141
154
  mr = Rack::MockRequest.env_for("/?foo=quux",
142
155
  "REQUEST_METHOD" => 'POST',
@@ -398,9 +411,9 @@ describe Rack::Request do
398
411
  req.cookies.should.equal 'foo' => 'bar'
399
412
  end
400
413
 
401
- should "raise any errors on every request" do
414
+ should "pass through non-uri escaped cookies as-is" do
402
415
  req = Rack::Request.new Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=%")
403
- 2.times { proc { req.cookies }.should.raise(ArgumentError) }
416
+ req.cookies["foo"].should == "%"
404
417
  end
405
418
 
406
419
  should "parse cookies according to RFC 2109" do
@@ -1,4 +1,3 @@
1
- require 'set'
2
1
  require 'rack/response'
3
2
  require 'stringio'
4
3
 
@@ -125,7 +124,6 @@ describe Rack::Response do
125
124
  response = Rack::Response.new
126
125
  response.redirect "/foo"
127
126
  status, header, body = response.finish
128
-
129
127
  status.should.equal 302
130
128
  header["Location"].should.equal "/foo"
131
129
 
@@ -147,7 +145,12 @@ describe Rack::Response do
147
145
  str = ""; body.each { |part| str << part }
148
146
  str.should.equal "foobar"
149
147
 
150
- r = Rack::Response.new(["foo", "bar"].to_set)
148
+ object_with_each = Object.new
149
+ def object_with_each.each
150
+ yield "foo"
151
+ yield "bar"
152
+ end
153
+ r = Rack::Response.new(object_with_each)
151
154
  r.write "foo"
152
155
  status, header, body = r.finish
153
156
  str = ""; body.each { |part| str << part }
@@ -218,6 +221,11 @@ describe Rack::Response do
218
221
  res.should.be.client_error
219
222
  res.should.be.not_found
220
223
 
224
+ res.status = 405
225
+ res.should.not.be.successful
226
+ res.should.be.client_error
227
+ res.should.be.method_not_allowed
228
+
221
229
  res.status = 422
222
230
  res.should.not.be.successful
223
231
  res.should.be.client_error
@@ -272,4 +280,34 @@ describe Rack::Response do
272
280
  res.close
273
281
  res.body.should.be.closed
274
282
  end
283
+
284
+ it "calls close on #body when 204, 205, or 304" do
285
+ res = Rack::Response.new
286
+ res.body = StringIO.new
287
+ res.finish
288
+ res.body.should.not.be.closed
289
+
290
+ res.status = 204
291
+ _, _, b = res.finish
292
+ res.body.should.be.closed
293
+ b.should.not == res.body
294
+
295
+ res.body = StringIO.new
296
+ res.status = 205
297
+ _, _, b = res.finish
298
+ res.body.should.be.closed
299
+ b.should.not == res.body
300
+
301
+ res.body = StringIO.new
302
+ res.status = 304
303
+ _, _, b = res.finish
304
+ res.body.should.be.closed
305
+ b.should.not == res.body
306
+ end
307
+
308
+ it "wraps the body from #to_ary to prevent infinite loops" do
309
+ res = Rack::Response.new
310
+ res.finish.last.should.not.respond_to?(:to_ary)
311
+ lambda { res.finish.last.to_ary }.should.raise(NoMethodError)
312
+ end
275
313
  end
data/test/spec_runtime.rb CHANGED
@@ -1,27 +1,37 @@
1
+ require 'rack/lint'
2
+ require 'rack/mock'
1
3
  require 'rack/runtime'
2
4
 
3
5
  describe Rack::Runtime do
6
+ def runtime_app(app, *args)
7
+ Rack::Lint.new Rack::Runtime.new(app, *args)
8
+ end
9
+
10
+ def request
11
+ Rack::MockRequest.env_for
12
+ end
13
+
4
14
  it "sets X-Runtime is none is set" do
5
15
  app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
6
- response = Rack::Runtime.new(app).call({})
16
+ response = runtime_app(app).call(request)
7
17
  response[1]['X-Runtime'].should =~ /[\d\.]+/
8
18
  end
9
19
 
10
20
  it "doesn't set the X-Runtime if it is already set" do
11
21
  app = lambda { |env| [200, {'Content-Type' => 'text/plain', "X-Runtime" => "foobar"}, "Hello, World!"] }
12
- response = Rack::Runtime.new(app).call({})
22
+ response = runtime_app(app).call(request)
13
23
  response[1]['X-Runtime'].should == "foobar"
14
24
  end
15
25
 
16
26
  should "allow a suffix to be set" do
17
27
  app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
18
- response = Rack::Runtime.new(app, "Test").call({})
28
+ response = runtime_app(app, "Test").call(request)
19
29
  response[1]['X-Runtime-Test'].should =~ /[\d\.]+/
20
30
  end
21
31
 
22
32
  should "allow multiple timers to be set" do
23
33
  app = lambda { |env| sleep 0.1; [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
24
- runtime = Rack::Runtime.new(app, "App")
34
+ runtime = runtime_app(app, "App")
25
35
 
26
36
  # wrap many times to guarantee a measurable difference
27
37
  100.times do |i|
@@ -29,7 +39,7 @@ describe Rack::Runtime do
29
39
  end
30
40
  runtime = Rack::Runtime.new(runtime, "All")
31
41
 
32
- response = runtime.call({})
42
+ response = runtime.call(request)
33
43
 
34
44
  response[1]['X-Runtime-App'].should =~ /[\d\.]+/
35
45
  response[1]['X-Runtime-All'].should =~ /[\d\.]+/
@@ -1,5 +1,8 @@
1
+ require 'fileutils'
2
+ require 'rack/lint'
1
3
  require 'rack/sendfile'
2
4
  require 'rack/mock'
5
+ require 'tmpdir'
3
6
 
4
7
  describe Rack::File do
5
8
  should "respond to #to_path" do
@@ -9,8 +12,9 @@ end
9
12
 
10
13
  describe Rack::Sendfile do
11
14
  def sendfile_body
15
+ FileUtils.touch File.join(Dir.tmpdir, "rack_sendfile")
12
16
  res = ['Hello World']
13
- def res.to_path ; "/tmp/hello.txt" ; end
17
+ def res.to_path ; File.join(Dir.tmpdir, "rack_sendfile") ; end
14
18
  res
15
19
  end
16
20
 
@@ -19,7 +23,7 @@ describe Rack::Sendfile do
19
23
  end
20
24
 
21
25
  def sendfile_app(body=sendfile_body)
22
- Rack::Sendfile.new(simple_app(body))
26
+ Rack::Lint.new Rack::Sendfile.new(simple_app(body))
23
27
  end
24
28
 
25
29
  @request = Rack::MockRequest.new(sendfile_app)
@@ -40,8 +44,8 @@ describe Rack::Sendfile do
40
44
  request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response|
41
45
  response.should.be.ok
42
46
  response.body.should.be.empty
43
- response.headers['Content-Length'].should == '0'
44
- response.headers['X-Sendfile'].should.equal '/tmp/hello.txt'
47
+ response.headers['Content-Length'].should.equal '0'
48
+ response.headers['X-Sendfile'].should.equal File.join(Dir.tmpdir, "rack_sendfile")
45
49
  end
46
50
  end
47
51
 
@@ -49,21 +53,21 @@ describe Rack::Sendfile do
49
53
  request 'HTTP_X_SENDFILE_TYPE' => 'X-Lighttpd-Send-File' do |response|
50
54
  response.should.be.ok
51
55
  response.body.should.be.empty
52
- response.headers['Content-Length'].should == '0'
53
- response.headers['X-Lighttpd-Send-File'].should.equal '/tmp/hello.txt'
56
+ response.headers['Content-Length'].should.equal '0'
57
+ response.headers['X-Lighttpd-Send-File'].should.equal File.join(Dir.tmpdir, "rack_sendfile")
54
58
  end
55
59
  end
56
60
 
57
61
  it "sets X-Accel-Redirect response header and discards body" do
58
62
  headers = {
59
63
  'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect',
60
- 'HTTP_X_ACCEL_MAPPING' => '/tmp/=/foo/bar/'
64
+ 'HTTP_X_ACCEL_MAPPING' => "#{Dir.tmpdir}/=/foo/bar/"
61
65
  }
62
66
  request headers do |response|
63
67
  response.should.be.ok
64
68
  response.body.should.be.empty
65
- response.headers['Content-Length'].should == '0'
66
- response.headers['X-Accel-Redirect'].should.equal '/foo/bar/hello.txt'
69
+ response.headers['Content-Length'].should.equal '0'
70
+ response.headers['X-Accel-Redirect'].should.equal '/foo/bar/rack_sendfile'
67
71
  end
68
72
  end
69
73
 
data/test/spec_server.rb CHANGED
@@ -10,6 +10,13 @@ describe Rack::Server do
10
10
  lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['success']] }
11
11
  end
12
12
 
13
+ def with_stderr
14
+ old, $stderr = $stderr, StringIO.new
15
+ yield $stderr
16
+ ensure
17
+ $stderr = old
18
+ end
19
+
13
20
  it "overrides :config if :app is passed in" do
14
21
  server = Rack::Server.new(:app => "FOO")
15
22
  server.app.should == "FOO"
@@ -71,4 +78,44 @@ describe Rack::Server do
71
78
  open(pidfile) { |f| f.read.should.eql $$.to_s }
72
79
  end
73
80
 
81
+ should "check pid file presence and running process" do
82
+ pidfile = Tempfile.open('pidfile') { |f| f.write($$); break f }.path
83
+ server = Rack::Server.new(:pid => pidfile)
84
+ server.send(:pidfile_process_status).should.eql :running
85
+ end
86
+
87
+ should "check pid file presence and dead process" do
88
+ dead_pid = `echo $$`.to_i
89
+ pidfile = Tempfile.open('pidfile') { |f| f.write(dead_pid); break f }.path
90
+ server = Rack::Server.new(:pid => pidfile)
91
+ server.send(:pidfile_process_status).should.eql :dead
92
+ end
93
+
94
+ should "check pid file presence and exited process" do
95
+ pidfile = Tempfile.open('pidfile') { |f| break f }.path
96
+ ::File.delete(pidfile)
97
+ server = Rack::Server.new(:pid => pidfile)
98
+ server.send(:pidfile_process_status).should.eql :exited
99
+ end
100
+
101
+ should "check pid file presence and not owned process" do
102
+ pidfile = Tempfile.open('pidfile') { |f| f.write(1); break f }.path
103
+ server = Rack::Server.new(:pid => pidfile)
104
+ server.send(:pidfile_process_status).should.eql :not_owned
105
+ end
106
+
107
+ should "inform the user about existing pidfiles with running processes" do
108
+ pidfile = Tempfile.open('pidfile') { |f| f.write(1); break f }.path
109
+ server = Rack::Server.new(:pid => pidfile)
110
+ with_stderr do |err|
111
+ should.raise(SystemExit) do
112
+ server.start
113
+ end
114
+ err.rewind
115
+ output = err.read
116
+ output.should.match(/already running/)
117
+ output.should.include? pidfile
118
+ end
119
+ end
120
+
74
121
  end
@@ -1,4 +1,5 @@
1
1
  require 'rack/session/cookie'
2
+ require 'rack/lint'
2
3
  require 'rack/mock'
3
4
 
4
5
  describe Rack::Session::Cookie do
@@ -9,7 +10,7 @@ describe Rack::Session::Cookie do
9
10
  hash.delete("session_id")
10
11
  Rack::Response.new(hash.inspect).to_a
11
12
  end
12
-
13
+
13
14
  session_id = lambda do |env|
14
15
  Rack::Response.new(env["rack.session"].to_hash.inspect).to_a
15
16
  end
@@ -24,6 +25,50 @@ describe Rack::Session::Cookie do
24
25
  Rack::Response.new("Nothing").to_a
25
26
  end
26
27
 
28
+ renewer = lambda do |env|
29
+ env["rack.session.options"][:renew] = true
30
+ Rack::Response.new("Nothing").to_a
31
+ end
32
+
33
+ only_session_id = lambda do |env|
34
+ Rack::Response.new(env["rack.session"]["session_id"].to_s).to_a
35
+ end
36
+
37
+ bigcookie = lambda do |env|
38
+ env["rack.session"]["cookie"] = "big" * 3000
39
+ Rack::Response.new(env["rack.session"].inspect).to_a
40
+ end
41
+
42
+ destroy_session = lambda do |env|
43
+ env["rack.session"].destroy
44
+ Rack::Response.new("Nothing").to_a
45
+ end
46
+
47
+ def response_for(options={})
48
+ request_options = options.fetch(:request, {})
49
+ cookie = if options[:cookie].is_a?(Rack::Response)
50
+ options[:cookie]["Set-Cookie"]
51
+ else
52
+ options[:cookie]
53
+ end
54
+ request_options["HTTP_COOKIE"] = cookie || ""
55
+
56
+ app_with_cookie = Rack::Session::Cookie.new(*options[:app])
57
+ app_with_cookie = Rack::Lint.new(app_with_cookie)
58
+ Rack::MockRequest.new(app_with_cookie).get("/", request_options)
59
+ end
60
+
61
+ before do
62
+ @warnings = warnings = []
63
+ Rack::Session::Cookie.class_eval do
64
+ define_method(:warn) { |m| warnings << m }
65
+ end
66
+ end
67
+
68
+ after do
69
+ Rack::Session::Cookie.class_eval { remove_method :warn }
70
+ end
71
+
27
72
  describe 'Base64' do
28
73
  it 'uses base64 to encode' do
29
74
  coder = Rack::Session::Cookie::Base64.new
@@ -57,6 +102,14 @@ describe Rack::Session::Cookie do
57
102
  end
58
103
  end
59
104
 
105
+ it "warns if no secret is given" do
106
+ cookie = Rack::Session::Cookie.new(incrementor)
107
+ @warnings.first.should =~ /no secret/i
108
+ @warnings.clear
109
+ cookie = Rack::Session::Cookie.new(incrementor, :secret => 'abc')
110
+ @warnings.should.be.empty?
111
+ end
112
+
60
113
  it 'uses a coder' do
61
114
  identity = Class.new {
62
115
  attr_reader :calls
@@ -123,6 +176,10 @@ describe Rack::Session::Cookie do
123
176
  res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)).
124
177
  get("/", "HTTP_COOKIE" => "rack.session=blarghfasel")
125
178
  res.body.should.equal '{"counter"=>1}'
179
+
180
+ app = Rack::Session::Cookie.new(incrementor, :secret => 'test')
181
+ res = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" => "rack.session=")
182
+ res.body.should.equal '{"counter"=>1}'
126
183
  end
127
184
 
128
185
  bigcookie = lambda do |env|
@@ -137,7 +194,7 @@ describe Rack::Session::Cookie do
137
194
  }.should.raise(Rack::MockRequest::FatalWarning)
138
195
  end
139
196
 
140
- it "loads from a cookie wih integrity hash" do
197
+ it "loads from a cookie with integrity hash" do
141
198
  res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).get("/")
142
199
  cookie = res["Set-Cookie"]
143
200
  res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).
@@ -147,6 +204,9 @@ describe Rack::Session::Cookie do
147
204
  res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).
148
205
  get("/", "HTTP_COOKIE" => cookie)
149
206
  res.body.should.equal '{"counter"=>3}'
207
+ res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'other')).
208
+ get("/", "HTTP_COOKIE" => cookie)
209
+ res.body.should.equal '{"counter"=>1}'
150
210
  end
151
211
 
152
212
  it "loads from a cookie wih accept-only integrity hash for graceful key rotation" do
@@ -165,16 +225,31 @@ describe Rack::Session::Cookie do
165
225
  app = Rack::Session::Cookie.new(incrementor, :secret => 'test')
166
226
  response1 = Rack::MockRequest.new(app).get("/")
167
227
  response1.body.should.equal '{"counter"=>1}'
228
+ response1 = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" => response1["Set-Cookie"])
229
+ response1.body.should.equal '{"counter"=>2}'
168
230
 
169
231
  _, digest = response1["Set-Cookie"].split("--")
170
232
  tampered_with_cookie = "hackerman-was-here" + "--" + digest
171
233
  response2 = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" =>
172
234
  tampered_with_cookie)
173
235
 
174
- # Tampared cookie was ignored. Counter is back to 1.
236
+ # Tampered cookie was ignored. Counter is back to 1.
175
237
  response2.body.should.equal '{"counter"=>1}'
176
238
  end
177
239
 
240
+ it "supports either of secret or old_secret" do
241
+ app = Rack::Session::Cookie.new(incrementor, :secret => 'test')
242
+ res = Rack::MockRequest.new(app).get("/")
243
+ res.body.should.equal '{"counter"=>1}'
244
+ res = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" => res["Set-Cookie"])
245
+ res.body.should.equal '{"counter"=>2}'
246
+ app = Rack::Session::Cookie.new(incrementor, :old_secret => 'test')
247
+ res = Rack::MockRequest.new(app).get("/")
248
+ res.body.should.equal '{"counter"=>1}'
249
+ res = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" => res["Set-Cookie"])
250
+ res.body.should.equal '{"counter"=>2}'
251
+ end
252
+
178
253
  describe "1.9 bugs relating to inspecting yet-to-be-loaded from cookie data: Rack::Session::Abstract::SessionHash" do
179
254
 
180
255
  it "can handle Rack::Lint middleware" do
@@ -225,6 +300,7 @@ describe Rack::Session::Cookie do
225
300
 
226
301
  res = Rack::MockRequest.new(app).get("/", "HTTPS" => "on")
227
302
  res["Set-Cookie"].should.not.be.nil
303
+ res["Set-Cookie"].should.match(/secure/)
228
304
  end
229
305
 
230
306
  it "does not return a cookie if cookie was not read/written" do
@@ -268,4 +344,18 @@ describe Rack::Session::Cookie do
268
344
  res = Rack::MockRequest.new(app).get("/", 'rack.session' => {:foo => 'bar'})
269
345
  res.body.should.match(/foo/)
270
346
  end
347
+
348
+ it "allows modifying session data with session data from middleware in front" do
349
+ request = { 'rack.session' => { :foo => 'bar' }}
350
+ response = response_for(:app => incrementor, :request => request)
351
+ response.body.should.match(/counter/)
352
+ response.body.should.match(/foo/)
353
+ end
354
+
355
+ it "allows modifying session data with session data from middleware in front" do
356
+ request = { 'rack.session' => { :foo => 'bar' }}
357
+ response = response_for(:app => incrementor, :request => request)
358
+ response.body.should.match(/counter/)
359
+ response.body.should.match(/foo/)
360
+ end
271
361
  end
@@ -1,5 +1,6 @@
1
1
  begin
2
2
  require 'rack/session/memcache'
3
+ require 'rack/lint'
3
4
  require 'rack/mock'
4
5
  require 'thread'
5
6
 
@@ -11,22 +12,23 @@ begin
11
12
  env["rack.session"]["counter"] += 1
12
13
  Rack::Response.new(env["rack.session"].inspect).to_a
13
14
  end
14
- drop_session = proc do |env|
15
+ drop_session = Rack::Lint.new(proc do |env|
15
16
  env['rack.session.options'][:drop] = true
16
17
  incrementor.call(env)
17
- end
18
- renew_session = proc do |env|
18
+ end)
19
+ renew_session = Rack::Lint.new(proc do |env|
19
20
  env['rack.session.options'][:renew] = true
20
21
  incrementor.call(env)
21
- end
22
- defer_session = proc do |env|
22
+ end)
23
+ defer_session = Rack::Lint.new(proc do |env|
23
24
  env['rack.session.options'][:defer] = true
24
25
  incrementor.call(env)
25
- end
26
- skip_session = proc do |env|
26
+ end)
27
+ skip_session = Rack::Lint.new(proc do |env|
27
28
  env['rack.session.options'][:skip] = true
28
29
  incrementor.call(env)
29
- end
30
+ end)
31
+ incrementor = Rack::Lint.new(incrementor)
30
32
 
31
33
  # test memcache connection
32
34
  Rack::Session::Memcache.new(incrementor)
@@ -1,4 +1,5 @@
1
1
  require 'thread'
2
+ require 'rack/lint'
2
3
  require 'rack/mock'
3
4
  require 'rack/session/pool'
4
5
 
@@ -12,28 +13,30 @@ describe Rack::Session::Pool do
12
13
  Rack::Response.new(env["rack.session"].inspect).to_a
13
14
  end
14
15
 
15
- session_id = lambda do |env|
16
+ session_id = Rack::Lint.new(lambda do |env|
16
17
  Rack::Response.new(env["rack.session"].inspect).to_a
17
- end
18
+ end)
18
19
 
19
- nothing = lambda do |env|
20
+ nothing = Rack::Lint.new(lambda do |env|
20
21
  Rack::Response.new("Nothing").to_a
21
- end
22
+ end)
22
23
 
23
- drop_session = lambda do |env|
24
+ drop_session = Rack::Lint.new(lambda do |env|
24
25
  env['rack.session.options'][:drop] = true
25
26
  incrementor.call(env)
26
- end
27
+ end)
27
28
 
28
- renew_session = lambda do |env|
29
+ renew_session = Rack::Lint.new(lambda do |env|
29
30
  env['rack.session.options'][:renew] = true
30
31
  incrementor.call(env)
31
- end
32
+ end)
32
33
 
33
- defer_session = lambda do |env|
34
+ defer_session = Rack::Lint.new(lambda do |env|
34
35
  env['rack.session.options'][:defer] = true
35
36
  incrementor.call(env)
36
- end
37
+ end)
38
+
39
+ incrementor = Rack::Lint.new(incrementor)
37
40
 
38
41
  it "creates a new cookie" do
39
42
  pool = Rack::Session::Pool.new(incrementor)
@@ -1,12 +1,17 @@
1
1
  require 'rack/showexceptions'
2
+ require 'rack/lint'
2
3
  require 'rack/mock'
3
4
 
4
5
  describe Rack::ShowExceptions do
6
+ def show_exceptions(app)
7
+ Rack::Lint.new Rack::ShowExceptions.new(app)
8
+ end
9
+
5
10
  it "catches exceptions" do
6
11
  res = nil
7
12
 
8
13
  req = Rack::MockRequest.new(
9
- Rack::ShowExceptions.new(
14
+ show_exceptions(
10
15
  lambda{|env| raise RuntimeError }
11
16
  ))
12
17
 
@@ -25,7 +30,7 @@ describe Rack::ShowExceptions do
25
30
  res = nil
26
31
 
27
32
  req = Rack::MockRequest.new(
28
- Rack::ShowExceptions.new(
33
+ show_exceptions(
29
34
  lambda{|env| raise RuntimeError, "It was never supposed to work" }
30
35
  ))
31
36
 
@@ -46,7 +51,7 @@ describe Rack::ShowExceptions do
46
51
  res = nil
47
52
 
48
53
  req = Rack::MockRequest.new(
49
- Rack::ShowExceptions.new(
54
+ show_exceptions(
50
55
  lambda{|env| raise RuntimeError, "It was never supposed to work" }
51
56
  ))
52
57
 
@@ -68,7 +73,7 @@ describe Rack::ShowExceptions do
68
73
  res = nil
69
74
 
70
75
  req = Rack::MockRequest.new(
71
- Rack::ShowExceptions.new(
76
+ show_exceptions(
72
77
  lambda{|env| raise RuntimeError, "", [] }
73
78
  )
74
79
  )
@@ -1,10 +1,15 @@
1
1
  require 'rack/showstatus'
2
+ require 'rack/lint'
2
3
  require 'rack/mock'
3
4
 
4
5
  describe Rack::ShowStatus do
6
+ def show_status(app)
7
+ Rack::Lint.new Rack::ShowStatus.new(app)
8
+ end
9
+
5
10
  should "provide a default status message" do
6
11
  req = Rack::MockRequest.new(
7
- Rack::ShowStatus.new(lambda{|env|
12
+ show_status(lambda{|env|
8
13
  [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
9
14
  }))
10
15
 
@@ -19,7 +24,7 @@ describe Rack::ShowStatus do
19
24
 
20
25
  should "let the app provide additional information" do
21
26
  req = Rack::MockRequest.new(
22
- Rack::ShowStatus.new(
27
+ show_status(
23
28
  lambda{|env|
24
29
  env["rack.showstatus.detail"] = "gone too meta."
25
30
  [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
@@ -37,7 +42,7 @@ describe Rack::ShowStatus do
37
42
 
38
43
  should "not replace existing messages" do
39
44
  req = Rack::MockRequest.new(
40
- Rack::ShowStatus.new(
45
+ show_status(
41
46
  lambda{|env|
42
47
  [404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]]
43
48
  }))
@@ -52,7 +57,7 @@ describe Rack::ShowStatus do
52
57
  headers = {"WWW-Authenticate" => "Basic blah"}
53
58
 
54
59
  req = Rack::MockRequest.new(
55
- Rack::ShowStatus.new(lambda{|env| [401, headers, []] }))
60
+ show_status(lambda{|env| [401, headers, []] }))
56
61
  res = req.get("/", :lint => true)
57
62
 
58
63
  res["WWW-Authenticate"].should.equal("Basic blah")
@@ -60,7 +65,7 @@ describe Rack::ShowStatus do
60
65
 
61
66
  should "replace existing messages if there is detail" do
62
67
  req = Rack::MockRequest.new(
63
- Rack::ShowStatus.new(
68
+ show_status(
64
69
  lambda{|env|
65
70
  env["rack.showstatus.detail"] = "gone too meta."
66
71
  [404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]]