rack 1.6.13 → 2.0.0.alpha
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.
- checksums.yaml +5 -5
- data/HISTORY.md +139 -18
- data/README.rdoc +17 -25
- data/Rakefile +6 -14
- data/SPEC +8 -9
- data/contrib/rack_logo.svg +164 -111
- data/lib/rack.rb +70 -21
- data/lib/rack/auth/digest/request.rb +1 -1
- data/lib/rack/body_proxy.rb +14 -9
- data/lib/rack/builder.rb +3 -3
- data/lib/rack/chunked.rb +5 -5
- data/lib/rack/{commonlogger.rb → common_logger.rb} +2 -2
- data/lib/rack/{conditionalget.rb → conditional_get.rb} +0 -0
- data/lib/rack/content_length.rb +2 -2
- data/lib/rack/deflater.rb +4 -4
- data/lib/rack/directory.rb +49 -55
- data/lib/rack/etag.rb +2 -1
- data/lib/rack/events.rb +154 -0
- data/lib/rack/file.rb +55 -40
- data/lib/rack/handler.rb +2 -24
- data/lib/rack/handler/cgi.rb +15 -16
- data/lib/rack/handler/fastcgi.rb +13 -14
- data/lib/rack/handler/lsws.rb +11 -11
- data/lib/rack/handler/scgi.rb +15 -15
- data/lib/rack/handler/thin.rb +3 -0
- data/lib/rack/handler/webrick.rb +22 -24
- data/lib/rack/head.rb +15 -17
- data/lib/rack/lint.rb +38 -38
- data/lib/rack/lobster.rb +1 -1
- data/lib/rack/lock.rb +6 -10
- data/lib/rack/logger.rb +2 -2
- data/lib/rack/media_type.rb +38 -0
- data/lib/rack/{methodoverride.rb → method_override.rb} +4 -11
- data/lib/rack/mime.rb +18 -5
- data/lib/rack/mock.rb +35 -52
- data/lib/rack/multipart.rb +35 -6
- data/lib/rack/multipart/generator.rb +4 -4
- data/lib/rack/multipart/parser.rb +273 -158
- data/lib/rack/multipart/uploaded_file.rb +1 -2
- data/lib/rack/{nulllogger.rb → null_logger.rb} +1 -1
- data/lib/rack/query_parser.rb +174 -0
- data/lib/rack/recursive.rb +8 -8
- data/lib/rack/reloader.rb +1 -2
- data/lib/rack/request.rb +370 -304
- data/lib/rack/response.rb +129 -56
- data/lib/rack/rewindable_input.rb +1 -12
- data/lib/rack/runtime.rb +10 -18
- data/lib/rack/sendfile.rb +5 -7
- data/lib/rack/server.rb +31 -25
- data/lib/rack/session/abstract/id.rb +93 -135
- data/lib/rack/session/cookie.rb +26 -28
- data/lib/rack/session/memcache.rb +8 -14
- data/lib/rack/session/pool.rb +14 -21
- data/lib/rack/show_exceptions.rb +386 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +3 -3
- data/lib/rack/static.rb +30 -5
- data/lib/rack/tempfile_reaper.rb +2 -2
- data/lib/rack/urlmap.rb +13 -14
- data/lib/rack/utils.rb +128 -221
- data/rack.gemspec +9 -5
- data/test/builder/an_underscore_app.rb +5 -0
- data/test/builder/options.ru +1 -1
- data/test/cgi/test.fcgi +1 -0
- data/test/cgi/test.gz +0 -0
- data/test/helper.rb +31 -0
- data/test/multipart/filename_with_encoded_words +7 -0
- data/test/multipart/{filename_with_null_byte → filename_with_single_quote} +1 -1
- data/test/multipart/quoted +15 -0
- data/test/multipart/rack-logo.png +0 -0
- data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
- data/test/spec_auth_basic.rb +20 -19
- data/test/spec_auth_digest.rb +47 -46
- data/test/spec_body_proxy.rb +27 -27
- data/test/spec_builder.rb +51 -41
- data/test/spec_cascade.rb +24 -22
- data/test/spec_cgi.rb +49 -67
- data/test/spec_chunked.rb +36 -34
- data/test/{spec_commonlogger.rb → spec_common_logger.rb} +23 -21
- data/test/{spec_conditionalget.rb → spec_conditional_get.rb} +29 -28
- data/test/spec_config.rb +3 -2
- data/test/spec_content_length.rb +18 -17
- data/test/spec_content_type.rb +13 -12
- data/test/spec_deflater.rb +66 -40
- data/test/spec_directory.rb +72 -27
- data/test/spec_etag.rb +32 -31
- data/test/spec_events.rb +133 -0
- data/test/spec_fastcgi.rb +50 -72
- data/test/spec_file.rb +96 -77
- data/test/spec_handler.rb +19 -34
- data/test/spec_head.rb +15 -14
- data/test/spec_lint.rb +162 -197
- data/test/spec_lobster.rb +24 -23
- data/test/spec_lock.rb +69 -39
- data/test/spec_logger.rb +4 -3
- data/test/spec_media_type.rb +42 -0
- data/test/spec_method_override.rb +83 -0
- data/test/spec_mime.rb +19 -19
- data/test/spec_mock.rb +196 -151
- data/test/spec_multipart.rb +310 -202
- data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
- data/test/spec_recursive.rb +17 -14
- data/test/spec_request.rb +763 -607
- data/test/spec_response.rb +209 -156
- data/test/spec_rewindable_input.rb +50 -40
- data/test/spec_runtime.rb +11 -10
- data/test/spec_sendfile.rb +30 -35
- data/test/spec_server.rb +78 -52
- data/test/spec_session_abstract_id.rb +11 -33
- data/test/spec_session_cookie.rb +97 -65
- data/test/spec_session_memcache.rb +63 -101
- data/test/spec_session_pool.rb +48 -84
- data/test/spec_show_exceptions.rb +80 -0
- data/test/{spec_showstatus.rb → spec_show_status.rb} +36 -35
- data/test/spec_static.rb +71 -32
- data/test/spec_tempfile_reaper.rb +11 -10
- data/test/spec_thin.rb +55 -50
- data/test/spec_urlmap.rb +79 -78
- data/test/spec_utils.rb +417 -345
- data/test/spec_version.rb +2 -8
- data/test/spec_webrick.rb +77 -67
- data/test/static/foo.html +1 -0
- data/test/testrequest.rb +1 -1
- data/test/unregistered_handler/rack/handler/unregistered.rb +1 -1
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +1 -1
- metadata +116 -71
- data/KNOWN-ISSUES +0 -44
- data/lib/rack/backports/uri/common_18.rb +0 -56
- data/lib/rack/backports/uri/common_192.rb +0 -52
- data/lib/rack/backports/uri/common_193.rb +0 -29
- data/lib/rack/handler/evented_mongrel.rb +0 -8
- data/lib/rack/handler/mongrel.rb +0 -106
- data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/lib/rack/showexceptions.rb +0 -387
- data/lib/rack/utils/okjson.rb +0 -600
- data/test/spec_methodoverride.rb +0 -111
- data/test/spec_mongrel.rb +0 -182
- data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
- data/test/spec_showexceptions.rb +0 -98
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
begin
|
2
3
|
require 'rack/session/memcache'
|
3
4
|
require 'rack/lint'
|
@@ -34,26 +35,26 @@ begin
|
|
34
35
|
Rack::Session::Memcache.new(incrementor)
|
35
36
|
|
36
37
|
it "faults on no connection" do
|
37
|
-
lambda{
|
38
|
+
lambda {
|
38
39
|
Rack::Session::Memcache.new(incrementor, :memcache_server => 'nosuchserver')
|
39
|
-
}.
|
40
|
+
}.must_raise(RuntimeError).message.must_equal 'No memcache servers'
|
40
41
|
end
|
41
42
|
|
42
43
|
it "connects to existing server" do
|
43
44
|
test_pool = MemCache.new(incrementor, :namespace => 'test:rack:session')
|
44
|
-
test_pool.namespace.
|
45
|
+
test_pool.namespace.must_equal 'test:rack:session'
|
45
46
|
end
|
46
47
|
|
47
48
|
it "passes options to MemCache" do
|
48
49
|
pool = Rack::Session::Memcache.new(incrementor, :namespace => 'test:rack:session')
|
49
|
-
pool.pool.namespace.
|
50
|
+
pool.pool.namespace.must_equal 'test:rack:session'
|
50
51
|
end
|
51
52
|
|
52
53
|
it "creates a new cookie" do
|
53
54
|
pool = Rack::Session::Memcache.new(incrementor)
|
54
55
|
res = Rack::MockRequest.new(pool).get("/")
|
55
|
-
res["Set-Cookie"].
|
56
|
-
res.body.
|
56
|
+
res["Set-Cookie"].must_include "#{session_key}="
|
57
|
+
res.body.must_equal '{"counter"=>1}'
|
57
58
|
end
|
58
59
|
|
59
60
|
it "determines session from a cookie" do
|
@@ -62,9 +63,9 @@ begin
|
|
62
63
|
res = req.get("/")
|
63
64
|
cookie = res["Set-Cookie"]
|
64
65
|
req.get("/", "HTTP_COOKIE" => cookie).
|
65
|
-
body.
|
66
|
+
body.must_equal '{"counter"=>2}'
|
66
67
|
req.get("/", "HTTP_COOKIE" => cookie).
|
67
|
-
body.
|
68
|
+
body.must_equal '{"counter"=>3}'
|
68
69
|
end
|
69
70
|
|
70
71
|
it "determines session only from a cookie by default" do
|
@@ -73,9 +74,9 @@ begin
|
|
73
74
|
res = req.get("/")
|
74
75
|
sid = res["Set-Cookie"][session_match, 1]
|
75
76
|
req.get("/?rack.session=#{sid}").
|
76
|
-
body.
|
77
|
+
body.must_equal '{"counter"=>1}'
|
77
78
|
req.get("/?rack.session=#{sid}").
|
78
|
-
body.
|
79
|
+
body.must_equal '{"counter"=>1}'
|
79
80
|
end
|
80
81
|
|
81
82
|
it "determines session from params" do
|
@@ -84,9 +85,9 @@ begin
|
|
84
85
|
res = req.get("/")
|
85
86
|
sid = res["Set-Cookie"][session_match, 1]
|
86
87
|
req.get("/?rack.session=#{sid}").
|
87
|
-
body.
|
88
|
+
body.must_equal '{"counter"=>2}'
|
88
89
|
req.get("/?rack.session=#{sid}").
|
89
|
-
body.
|
90
|
+
body.must_equal '{"counter"=>3}'
|
90
91
|
end
|
91
92
|
|
92
93
|
it "survives nonexistant cookies" do
|
@@ -94,24 +95,24 @@ begin
|
|
94
95
|
pool = Rack::Session::Memcache.new(incrementor)
|
95
96
|
res = Rack::MockRequest.new(pool).
|
96
97
|
get("/", "HTTP_COOKIE" => bad_cookie)
|
97
|
-
res.body.
|
98
|
+
res.body.must_equal '{"counter"=>1}'
|
98
99
|
cookie = res["Set-Cookie"][session_match]
|
99
|
-
cookie.
|
100
|
+
cookie.wont_match(/#{bad_cookie}/)
|
100
101
|
end
|
101
102
|
|
102
103
|
it "maintains freshness" do
|
103
104
|
pool = Rack::Session::Memcache.new(incrementor, :expire_after => 3)
|
104
105
|
res = Rack::MockRequest.new(pool).get('/')
|
105
|
-
res.body.
|
106
|
+
res.body.must_include '"counter"=>1'
|
106
107
|
cookie = res["Set-Cookie"]
|
107
108
|
res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
|
108
|
-
res["Set-Cookie"].
|
109
|
-
res.body.
|
109
|
+
res["Set-Cookie"].must_equal cookie
|
110
|
+
res.body.must_include '"counter"=>2'
|
110
111
|
puts 'Sleeping to expire session' if $DEBUG
|
111
112
|
sleep 4
|
112
113
|
res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
|
113
|
-
res["Set-Cookie"].
|
114
|
-
res.body.
|
114
|
+
res["Set-Cookie"].wont_equal cookie
|
115
|
+
res.body.must_include '"counter"=>1'
|
115
116
|
end
|
116
117
|
|
117
118
|
it "does not send the same session id if it did not change" do
|
@@ -120,15 +121,15 @@ begin
|
|
120
121
|
|
121
122
|
res0 = req.get("/")
|
122
123
|
cookie = res0["Set-Cookie"][session_match]
|
123
|
-
res0.body.
|
124
|
+
res0.body.must_equal '{"counter"=>1}'
|
124
125
|
|
125
126
|
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
126
|
-
res1["Set-Cookie"].
|
127
|
-
res1.body.
|
127
|
+
res1["Set-Cookie"].must_be_nil
|
128
|
+
res1.body.must_equal '{"counter"=>2}'
|
128
129
|
|
129
130
|
res2 = req.get("/", "HTTP_COOKIE" => cookie)
|
130
|
-
res2["Set-Cookie"].
|
131
|
-
res2.body.
|
131
|
+
res2["Set-Cookie"].must_be_nil
|
132
|
+
res2.body.must_equal '{"counter"=>3}'
|
132
133
|
end
|
133
134
|
|
134
135
|
it "deletes cookies with :drop option" do
|
@@ -139,15 +140,15 @@ begin
|
|
139
140
|
|
140
141
|
res1 = req.get("/")
|
141
142
|
session = (cookie = res1["Set-Cookie"])[session_match]
|
142
|
-
res1.body.
|
143
|
+
res1.body.must_equal '{"counter"=>1}'
|
143
144
|
|
144
145
|
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
145
|
-
res2["Set-Cookie"].
|
146
|
-
res2.body.
|
146
|
+
res2["Set-Cookie"].must_equal nil
|
147
|
+
res2.body.must_equal '{"counter"=>2}'
|
147
148
|
|
148
149
|
res3 = req.get("/", "HTTP_COOKIE" => cookie)
|
149
|
-
res3["Set-Cookie"][session_match].
|
150
|
-
res3.body.
|
150
|
+
res3["Set-Cookie"][session_match].wont_equal session
|
151
|
+
res3.body.must_equal '{"counter"=>1}'
|
151
152
|
end
|
152
153
|
|
153
154
|
it "provides new session id with :renew option" do
|
@@ -158,20 +159,20 @@ begin
|
|
158
159
|
|
159
160
|
res1 = req.get("/")
|
160
161
|
session = (cookie = res1["Set-Cookie"])[session_match]
|
161
|
-
res1.body.
|
162
|
+
res1.body.must_equal '{"counter"=>1}'
|
162
163
|
|
163
164
|
res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
|
164
165
|
new_cookie = res2["Set-Cookie"]
|
165
166
|
new_session = new_cookie[session_match]
|
166
|
-
new_session.
|
167
|
-
res2.body.
|
167
|
+
new_session.wont_equal session
|
168
|
+
res2.body.must_equal '{"counter"=>2}'
|
168
169
|
|
169
170
|
res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
|
170
|
-
res3.body.
|
171
|
+
res3.body.must_equal '{"counter"=>3}'
|
171
172
|
|
172
173
|
# Old cookie was deleted
|
173
174
|
res4 = req.get("/", "HTTP_COOKIE" => cookie)
|
174
|
-
res4.body.
|
175
|
+
res4.body.must_equal '{"counter"=>1}'
|
175
176
|
end
|
176
177
|
|
177
178
|
it "omits cookie with :defer option but still updates the state" do
|
@@ -182,14 +183,14 @@ begin
|
|
182
183
|
creq = Rack::MockRequest.new(count)
|
183
184
|
|
184
185
|
res0 = dreq.get("/")
|
185
|
-
res0["Set-Cookie"].
|
186
|
-
res0.body.
|
186
|
+
res0["Set-Cookie"].must_equal nil
|
187
|
+
res0.body.must_equal '{"counter"=>1}'
|
187
188
|
|
188
189
|
res0 = creq.get("/")
|
189
190
|
res1 = dreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
|
190
|
-
res1.body.
|
191
|
+
res1.body.must_equal '{"counter"=>2}'
|
191
192
|
res2 = dreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
|
192
|
-
res2.body.
|
193
|
+
res2.body.must_equal '{"counter"=>3}'
|
193
194
|
end
|
194
195
|
|
195
196
|
it "omits cookie and state update with :skip option" do
|
@@ -200,14 +201,14 @@ begin
|
|
200
201
|
creq = Rack::MockRequest.new(count)
|
201
202
|
|
202
203
|
res0 = sreq.get("/")
|
203
|
-
res0["Set-Cookie"].
|
204
|
-
res0.body.
|
204
|
+
res0["Set-Cookie"].must_equal nil
|
205
|
+
res0.body.must_equal '{"counter"=>1}'
|
205
206
|
|
206
207
|
res0 = creq.get("/")
|
207
208
|
res1 = sreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
|
208
|
-
res1.body.
|
209
|
+
res1.body.must_equal '{"counter"=>2}'
|
209
210
|
res2 = sreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
|
210
|
-
res2.body.
|
211
|
+
res2.body.must_equal '{"counter"=>2}'
|
211
212
|
end
|
212
213
|
|
213
214
|
it "updates deep hashes correctly" do
|
@@ -225,64 +226,25 @@ begin
|
|
225
226
|
req = Rack::MockRequest.new(pool)
|
226
227
|
|
227
228
|
res0 = req.get("/")
|
228
|
-
session_id =
|
229
|
-
ses0 = pool.pool.get(session_id
|
229
|
+
session_id = (cookie = res0["Set-Cookie"])[session_match, 1]
|
230
|
+
ses0 = pool.pool.get(session_id, true)
|
230
231
|
|
231
232
|
req.get("/", "HTTP_COOKIE" => cookie)
|
232
|
-
ses1 = pool.pool.get(session_id
|
233
|
+
ses1 = pool.pool.get(session_id, true)
|
233
234
|
|
234
|
-
ses1.
|
235
|
-
end
|
236
|
-
|
237
|
-
it "can read the session with the legacy id" do
|
238
|
-
pool = Rack::Session::Memcache.new(incrementor)
|
239
|
-
req = Rack::MockRequest.new(pool)
|
240
|
-
|
241
|
-
res0 = req.get("/")
|
242
|
-
cookie = res0["Set-Cookie"]
|
243
|
-
session_id = Rack::Session::SessionId.new cookie[session_match, 1]
|
244
|
-
ses0 = pool.pool.get(session_id.private_id, true)
|
245
|
-
pool.pool.set(session_id.public_id, ses0, 0, true)
|
246
|
-
pool.pool.delete(session_id.private_id)
|
247
|
-
|
248
|
-
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
249
|
-
res1["Set-Cookie"].should.be.nil
|
250
|
-
res1.body.should.equal '{"counter"=>2}'
|
251
|
-
pool.pool.get(session_id.private_id, true).should.not.be.nil
|
252
|
-
end
|
253
|
-
|
254
|
-
it "drops the session in the legacy id as well" do
|
255
|
-
pool = Rack::Session::Memcache.new(incrementor)
|
256
|
-
req = Rack::MockRequest.new(pool)
|
257
|
-
drop = Rack::Utils::Context.new(pool, drop_session)
|
258
|
-
dreq = Rack::MockRequest.new(drop)
|
259
|
-
|
260
|
-
res0 = req.get("/")
|
261
|
-
cookie = res0["Set-Cookie"]
|
262
|
-
session_id = Rack::Session::SessionId.new cookie[session_match, 1]
|
263
|
-
ses0 = pool.pool.get(session_id.private_id, true)
|
264
|
-
pool.pool.set(session_id.public_id, ses0, 0, true)
|
265
|
-
pool.pool.delete(session_id.private_id)
|
266
|
-
|
267
|
-
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
268
|
-
res2["Set-Cookie"].should.be.nil
|
269
|
-
res2.body.should.equal '{"counter"=>2}'
|
270
|
-
pool.pool.get(session_id.private_id, true).should.be.nil
|
271
|
-
pool.pool.get(session_id.public_id, true).should.be.nil
|
235
|
+
ses1.wont_equal ses0
|
272
236
|
end
|
273
237
|
|
274
238
|
# anyone know how to do this better?
|
275
239
|
it "cleanly merges sessions when multithreaded" do
|
276
|
-
unless $DEBUG
|
277
|
-
|
278
|
-
next
|
279
|
-
end
|
240
|
+
skip unless $DEBUG
|
241
|
+
|
280
242
|
warn 'Running multithread test for Session::Memcache'
|
281
243
|
pool = Rack::Session::Memcache.new(incrementor)
|
282
244
|
req = Rack::MockRequest.new(pool)
|
283
245
|
|
284
246
|
res = req.get('/')
|
285
|
-
res.body.
|
247
|
+
res.body.must_equal '{"counter"=>1}'
|
286
248
|
cookie = res["Set-Cookie"]
|
287
249
|
session_id = cookie[session_match, 1]
|
288
250
|
|
@@ -302,13 +264,13 @@ begin
|
|
302
264
|
end
|
303
265
|
end.reverse.map{|t| t.run.join.value }
|
304
266
|
r.each do |request|
|
305
|
-
request['Set-Cookie'].
|
306
|
-
request.body.
|
267
|
+
request['Set-Cookie'].must_equal cookie
|
268
|
+
request.body.must_include '"counter"=>2'
|
307
269
|
end
|
308
270
|
|
309
271
|
session = pool.pool.get(session_id)
|
310
|
-
session.size.
|
311
|
-
session['counter'].
|
272
|
+
session.size.must_equal tnum+1 # counter
|
273
|
+
session['counter'].must_equal 2 # meeeh
|
312
274
|
|
313
275
|
tnum = rand(7).to_i+5
|
314
276
|
r = Array.new(tnum) do
|
@@ -319,13 +281,13 @@ begin
|
|
319
281
|
end
|
320
282
|
end.reverse.map{|t| t.run.join.value }
|
321
283
|
r.each do |request|
|
322
|
-
request['Set-Cookie'].
|
323
|
-
request.body.
|
284
|
+
request['Set-Cookie'].must_equal cookie
|
285
|
+
request.body.must_include '"counter"=>3'
|
324
286
|
end
|
325
287
|
|
326
288
|
session = pool.pool.get(session_id)
|
327
|
-
session.size.
|
328
|
-
session['counter'].
|
289
|
+
session.size.must_equal tnum+1
|
290
|
+
session['counter'].must_equal 3
|
329
291
|
|
330
292
|
drop_counter = proc do |env|
|
331
293
|
env['rack.session'].delete 'counter'
|
@@ -341,14 +303,14 @@ begin
|
|
341
303
|
end
|
342
304
|
end.reverse.map{|t| t.run.join.value }
|
343
305
|
r.each do |request|
|
344
|
-
request['Set-Cookie'].
|
345
|
-
request.body.
|
306
|
+
request['Set-Cookie'].must_equal cookie
|
307
|
+
request.body.must_include '"foo"=>"bar"'
|
346
308
|
end
|
347
309
|
|
348
310
|
session = pool.pool.get(session_id)
|
349
|
-
session.size.
|
350
|
-
session['counter'].
|
351
|
-
session['foo'].
|
311
|
+
session.size.must_equal r.size+1
|
312
|
+
session['counter'].must_be_nil?
|
313
|
+
session['foo'].must_equal 'bar'
|
352
314
|
end
|
353
315
|
end
|
354
316
|
rescue RuntimeError
|
data/test/spec_session_pool.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
require 'thread'
|
2
3
|
require 'rack/lint'
|
3
4
|
require 'rack/mock'
|
@@ -5,7 +6,7 @@ require 'rack/session/pool'
|
|
5
6
|
|
6
7
|
describe Rack::Session::Pool do
|
7
8
|
session_key = Rack::Session::Pool::DEFAULT_OPTIONS[:key]
|
8
|
-
session_match = /#{session_key}=
|
9
|
+
session_match = /#{session_key}=[0-9a-fA-F]+;/
|
9
10
|
|
10
11
|
incrementor = lambda do |env|
|
11
12
|
env["rack.session"]["counter"] ||= 0
|
@@ -13,7 +14,7 @@ describe Rack::Session::Pool do
|
|
13
14
|
Rack::Response.new(env["rack.session"].inspect).to_a
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
+
session_id = Rack::Lint.new(lambda do |env|
|
17
18
|
Rack::Response.new(env["rack.session"].inspect).to_a
|
18
19
|
end)
|
19
20
|
|
@@ -35,14 +36,14 @@ describe Rack::Session::Pool do
|
|
35
36
|
env['rack.session.options'][:defer] = true
|
36
37
|
incrementor.call(env)
|
37
38
|
end)
|
38
|
-
|
39
|
+
|
39
40
|
incrementor = Rack::Lint.new(incrementor)
|
40
41
|
|
41
42
|
it "creates a new cookie" do
|
42
43
|
pool = Rack::Session::Pool.new(incrementor)
|
43
44
|
res = Rack::MockRequest.new(pool).get("/")
|
44
|
-
res["Set-Cookie"].
|
45
|
-
res.body.
|
45
|
+
res["Set-Cookie"].must_match(session_match)
|
46
|
+
res.body.must_equal '{"counter"=>1}'
|
46
47
|
end
|
47
48
|
|
48
49
|
it "determines session from a cookie" do
|
@@ -50,16 +51,16 @@ describe Rack::Session::Pool do
|
|
50
51
|
req = Rack::MockRequest.new(pool)
|
51
52
|
cookie = req.get("/")["Set-Cookie"]
|
52
53
|
req.get("/", "HTTP_COOKIE" => cookie).
|
53
|
-
body.
|
54
|
+
body.must_equal '{"counter"=>2}'
|
54
55
|
req.get("/", "HTTP_COOKIE" => cookie).
|
55
|
-
body.
|
56
|
+
body.must_equal '{"counter"=>3}'
|
56
57
|
end
|
57
58
|
|
58
59
|
it "survives nonexistant cookies" do
|
59
60
|
pool = Rack::Session::Pool.new(incrementor)
|
60
61
|
res = Rack::MockRequest.new(pool).
|
61
62
|
get("/", "HTTP_COOKIE" => "#{session_key}=blarghfasel")
|
62
|
-
res.body.
|
63
|
+
res.body.must_equal '{"counter"=>1}'
|
63
64
|
end
|
64
65
|
|
65
66
|
it "does not send the same session id if it did not change" do
|
@@ -68,18 +69,18 @@ describe Rack::Session::Pool do
|
|
68
69
|
|
69
70
|
res0 = req.get("/")
|
70
71
|
cookie = res0["Set-Cookie"][session_match]
|
71
|
-
res0.body.
|
72
|
-
pool.pool.size.
|
72
|
+
res0.body.must_equal '{"counter"=>1}'
|
73
|
+
pool.pool.size.must_equal 1
|
73
74
|
|
74
75
|
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
75
|
-
res1["Set-Cookie"].
|
76
|
-
res1.body.
|
77
|
-
pool.pool.size.
|
76
|
+
res1["Set-Cookie"].must_be_nil
|
77
|
+
res1.body.must_equal '{"counter"=>2}'
|
78
|
+
pool.pool.size.must_equal 1
|
78
79
|
|
79
80
|
res2 = req.get("/", "HTTP_COOKIE" => cookie)
|
80
|
-
res2["Set-Cookie"].
|
81
|
-
res2.body.
|
82
|
-
pool.pool.size.
|
81
|
+
res2["Set-Cookie"].must_be_nil
|
82
|
+
res2.body.must_equal '{"counter"=>3}'
|
83
|
+
pool.pool.size.must_equal 1
|
83
84
|
end
|
84
85
|
|
85
86
|
it "deletes cookies with :drop option" do
|
@@ -90,18 +91,18 @@ describe Rack::Session::Pool do
|
|
90
91
|
|
91
92
|
res1 = req.get("/")
|
92
93
|
session = (cookie = res1["Set-Cookie"])[session_match]
|
93
|
-
res1.body.
|
94
|
-
pool.pool.size.
|
94
|
+
res1.body.must_equal '{"counter"=>1}'
|
95
|
+
pool.pool.size.must_equal 1
|
95
96
|
|
96
97
|
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
97
|
-
res2["Set-Cookie"].
|
98
|
-
res2.body.
|
99
|
-
pool.pool.size.
|
98
|
+
res2["Set-Cookie"].must_be_nil
|
99
|
+
res2.body.must_equal '{"counter"=>2}'
|
100
|
+
pool.pool.size.must_equal 0
|
100
101
|
|
101
102
|
res3 = req.get("/", "HTTP_COOKIE" => cookie)
|
102
|
-
res3["Set-Cookie"][session_match].
|
103
|
-
res3.body.
|
104
|
-
pool.pool.size.
|
103
|
+
res3["Set-Cookie"][session_match].wont_equal session
|
104
|
+
res3.body.must_equal '{"counter"=>1}'
|
105
|
+
pool.pool.size.must_equal 1
|
105
106
|
end
|
106
107
|
|
107
108
|
it "provides new session id with :renew option" do
|
@@ -112,23 +113,23 @@ describe Rack::Session::Pool do
|
|
112
113
|
|
113
114
|
res1 = req.get("/")
|
114
115
|
session = (cookie = res1["Set-Cookie"])[session_match]
|
115
|
-
res1.body.
|
116
|
-
pool.pool.size.
|
116
|
+
res1.body.must_equal '{"counter"=>1}'
|
117
|
+
pool.pool.size.must_equal 1
|
117
118
|
|
118
119
|
res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
|
119
120
|
new_cookie = res2["Set-Cookie"]
|
120
121
|
new_session = new_cookie[session_match]
|
121
|
-
new_session.
|
122
|
-
res2.body.
|
123
|
-
pool.pool.size.
|
122
|
+
new_session.wont_equal session
|
123
|
+
res2.body.must_equal '{"counter"=>2}'
|
124
|
+
pool.pool.size.must_equal 1
|
124
125
|
|
125
126
|
res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
|
126
|
-
res3.body.
|
127
|
-
pool.pool.size.
|
127
|
+
res3.body.must_equal '{"counter"=>3}'
|
128
|
+
pool.pool.size.must_equal 1
|
128
129
|
|
129
130
|
res4 = req.get("/", "HTTP_COOKIE" => cookie)
|
130
|
-
res4.body.
|
131
|
-
pool.pool.size.
|
131
|
+
res4.body.must_equal '{"counter"=>1}'
|
132
|
+
pool.pool.size.must_equal 2
|
132
133
|
end
|
133
134
|
|
134
135
|
it "omits cookie with :defer option" do
|
@@ -137,52 +138,15 @@ describe Rack::Session::Pool do
|
|
137
138
|
dreq = Rack::MockRequest.new(defer)
|
138
139
|
|
139
140
|
res1 = dreq.get("/")
|
140
|
-
res1["Set-Cookie"].
|
141
|
-
res1.body.
|
142
|
-
pool.pool.size.
|
143
|
-
end
|
144
|
-
|
145
|
-
it "can read the session with the legacy id" do
|
146
|
-
pool = Rack::Session::Pool.new(incrementor)
|
147
|
-
req = Rack::MockRequest.new(pool)
|
148
|
-
|
149
|
-
res0 = req.get("/")
|
150
|
-
cookie = res0["Set-Cookie"]
|
151
|
-
session_id = Rack::Session::SessionId.new cookie[session_match, 1]
|
152
|
-
ses0 = pool.pool[session_id.private_id]
|
153
|
-
pool.pool[session_id.public_id] = ses0
|
154
|
-
pool.pool.delete(session_id.private_id)
|
155
|
-
|
156
|
-
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
157
|
-
res1["Set-Cookie"].should.be.nil
|
158
|
-
res1.body.should.equal '{"counter"=>2}'
|
159
|
-
pool.pool[session_id.private_id].should.not.be.nil
|
160
|
-
end
|
161
|
-
|
162
|
-
it "drops the session in the legacy id as well" do
|
163
|
-
pool = Rack::Session::Pool.new(incrementor)
|
164
|
-
req = Rack::MockRequest.new(pool)
|
165
|
-
drop = Rack::Utils::Context.new(pool, drop_session)
|
166
|
-
dreq = Rack::MockRequest.new(drop)
|
167
|
-
|
168
|
-
res0 = req.get("/")
|
169
|
-
cookie = res0["Set-Cookie"]
|
170
|
-
session_id = Rack::Session::SessionId.new cookie[session_match, 1]
|
171
|
-
ses0 = pool.pool[session_id.private_id]
|
172
|
-
pool.pool[session_id.public_id] = ses0
|
173
|
-
pool.pool.delete(session_id.private_id)
|
174
|
-
|
175
|
-
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
176
|
-
res2["Set-Cookie"].should.be.nil
|
177
|
-
res2.body.should.equal '{"counter"=>2}'
|
178
|
-
pool.pool[session_id.private_id].should.be.nil
|
179
|
-
pool.pool[session_id.public_id].should.be.nil
|
141
|
+
res1["Set-Cookie"].must_equal nil
|
142
|
+
res1.body.must_equal '{"counter"=>1}'
|
143
|
+
pool.pool.size.must_equal 1
|
180
144
|
end
|
181
145
|
|
182
146
|
# anyone know how to do this better?
|
183
147
|
it "should merge sessions when multithreaded" do
|
184
148
|
unless $DEBUG
|
185
|
-
1.
|
149
|
+
1.must_equal 1
|
186
150
|
next
|
187
151
|
end
|
188
152
|
|
@@ -191,7 +155,7 @@ describe Rack::Session::Pool do
|
|
191
155
|
req = Rack::MockRequest.new(pool)
|
192
156
|
|
193
157
|
res = req.get('/')
|
194
|
-
res.body.
|
158
|
+
res.body.must_equal '{"counter"=>1}'
|
195
159
|
cookie = res["Set-Cookie"]
|
196
160
|
sess_id = cookie[/#{pool.key}=([^,;]+)/,1]
|
197
161
|
|
@@ -211,36 +175,36 @@ describe Rack::Session::Pool do
|
|
211
175
|
end
|
212
176
|
end.reverse.map{|t| t.run.join.value }
|
213
177
|
r.each do |resp|
|
214
|
-
resp['Set-Cookie'].
|
215
|
-
resp.body.
|
178
|
+
resp['Set-Cookie'].must_equal cookie
|
179
|
+
resp.body.must_include '"counter"=>2'
|
216
180
|
end
|
217
181
|
|
218
182
|
session = pool.pool[sess_id]
|
219
|
-
session.size.
|
220
|
-
session['counter'].
|
183
|
+
session.size.must_equal tnum+1 # counter
|
184
|
+
session['counter'].must_equal 2 # meeeh
|
221
185
|
end
|
222
186
|
|
223
187
|
it "does not return a cookie if cookie was not read/written" do
|
224
188
|
app = Rack::Session::Pool.new(nothing)
|
225
189
|
res = Rack::MockRequest.new(app).get("/")
|
226
|
-
res["Set-Cookie"].
|
190
|
+
res["Set-Cookie"].must_be_nil
|
227
191
|
end
|
228
192
|
|
229
193
|
it "does not return a cookie if cookie was not written (only read)" do
|
230
|
-
app = Rack::Session::Pool.new(
|
194
|
+
app = Rack::Session::Pool.new(session_id)
|
231
195
|
res = Rack::MockRequest.new(app).get("/")
|
232
|
-
res["Set-Cookie"].
|
196
|
+
res["Set-Cookie"].must_be_nil
|
233
197
|
end
|
234
198
|
|
235
199
|
it "returns even if not read/written if :expire_after is set" do
|
236
200
|
app = Rack::Session::Pool.new(nothing, :expire_after => 3600)
|
237
201
|
res = Rack::MockRequest.new(app).get("/", 'rack.session' => {'not' => 'empty'})
|
238
|
-
res["Set-Cookie"].
|
202
|
+
res["Set-Cookie"].wont_be :nil?
|
239
203
|
end
|
240
204
|
|
241
205
|
it "returns no cookie if no data was written and no session was created previously, even if :expire_after is set" do
|
242
206
|
app = Rack::Session::Pool.new(nothing, :expire_after => 3600)
|
243
207
|
res = Rack::MockRequest.new(app).get("/")
|
244
|
-
res["Set-Cookie"].
|
208
|
+
res["Set-Cookie"].must_be_nil
|
245
209
|
end
|
246
210
|
end
|