rack 2.0.9.4 → 2.1.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 (188) hide show
  1. checksums.yaml +4 -4
  2. data/{HISTORY.md → CHANGELOG.md} +214 -164
  3. data/{COPYING → MIT-LICENSE} +4 -2
  4. data/README.rdoc +79 -133
  5. data/Rakefile +25 -18
  6. data/SPEC +9 -9
  7. data/bin/rackup +1 -0
  8. data/example/lobster.ru +2 -0
  9. data/example/protectedlobster.rb +3 -1
  10. data/example/protectedlobster.ru +2 -0
  11. data/lib/rack/auth/abstract/handler.rb +3 -1
  12. data/lib/rack/auth/abstract/request.rb +2 -0
  13. data/lib/rack/auth/basic.rb +4 -1
  14. data/lib/rack/auth/digest/md5.rb +9 -7
  15. data/lib/rack/auth/digest/nonce.rb +6 -3
  16. data/lib/rack/auth/digest/params.rb +4 -2
  17. data/lib/rack/auth/digest/request.rb +2 -0
  18. data/lib/rack/body_proxy.rb +3 -6
  19. data/lib/rack/builder.rb +38 -15
  20. data/lib/rack/cascade.rb +6 -5
  21. data/lib/rack/chunked.rb +29 -6
  22. data/lib/rack/common_logger.rb +9 -11
  23. data/lib/rack/conditional_get.rb +3 -1
  24. data/lib/rack/config.rb +2 -0
  25. data/lib/rack/content_length.rb +3 -1
  26. data/lib/rack/content_type.rb +3 -1
  27. data/lib/rack/core_ext/regexp.rb +14 -0
  28. data/lib/rack/deflater.rb +28 -17
  29. data/lib/rack/directory.rb +17 -14
  30. data/lib/rack/etag.rb +3 -1
  31. data/lib/rack/events.rb +5 -3
  32. data/lib/rack/file.rb +5 -173
  33. data/lib/rack/files.rb +178 -0
  34. data/lib/rack/handler/cgi.rb +3 -1
  35. data/lib/rack/handler/fastcgi.rb +4 -2
  36. data/lib/rack/handler/lsws.rb +3 -1
  37. data/lib/rack/handler/scgi.rb +9 -6
  38. data/lib/rack/handler/thin.rb +3 -1
  39. data/lib/rack/handler/webrick.rb +4 -2
  40. data/lib/rack/handler.rb +7 -2
  41. data/lib/rack/head.rb +2 -0
  42. data/lib/rack/lint.rb +15 -12
  43. data/lib/rack/lobster.rb +7 -5
  44. data/lib/rack/lock.rb +2 -0
  45. data/lib/rack/logger.rb +2 -0
  46. data/lib/rack/media_type.rb +10 -5
  47. data/lib/rack/method_override.rb +4 -2
  48. data/lib/rack/mime.rb +9 -1
  49. data/lib/rack/mock.rb +74 -15
  50. data/lib/rack/multipart/generator.rb +6 -7
  51. data/lib/rack/multipart/parser.rb +55 -62
  52. data/lib/rack/multipart/uploaded_file.rb +2 -0
  53. data/lib/rack/multipart.rb +6 -3
  54. data/lib/rack/null_logger.rb +2 -0
  55. data/lib/rack/query_parser.rb +51 -25
  56. data/lib/rack/recursive.rb +7 -5
  57. data/lib/rack/reloader.rb +10 -4
  58. data/lib/rack/request.rb +79 -26
  59. data/lib/rack/response.rb +71 -31
  60. data/lib/rack/rewindable_input.rb +4 -2
  61. data/lib/rack/runtime.rb +4 -2
  62. data/lib/rack/sendfile.rb +15 -8
  63. data/lib/rack/server.rb +88 -16
  64. data/lib/rack/session/abstract/id.rb +40 -22
  65. data/lib/rack/session/cookie.rb +10 -9
  66. data/lib/rack/session/memcache.rb +4 -93
  67. data/lib/rack/session/pool.rb +4 -2
  68. data/lib/rack/show_exceptions.rb +15 -9
  69. data/lib/rack/show_status.rb +4 -2
  70. data/lib/rack/static.rb +15 -10
  71. data/lib/rack/tempfile_reaper.rb +2 -0
  72. data/lib/rack/urlmap.rb +11 -2
  73. data/lib/rack/utils.rb +64 -93
  74. data/lib/rack.rb +63 -60
  75. data/rack.gemspec +17 -7
  76. metadata +33 -175
  77. data/test/builder/an_underscore_app.rb +0 -5
  78. data/test/builder/anything.rb +0 -5
  79. data/test/builder/comment.ru +0 -4
  80. data/test/builder/end.ru +0 -5
  81. data/test/builder/line.ru +0 -1
  82. data/test/builder/options.ru +0 -2
  83. data/test/cgi/assets/folder/test.js +0 -1
  84. data/test/cgi/assets/fonts/font.eot +0 -1
  85. data/test/cgi/assets/images/image.png +0 -1
  86. data/test/cgi/assets/index.html +0 -1
  87. data/test/cgi/assets/javascripts/app.js +0 -1
  88. data/test/cgi/assets/stylesheets/app.css +0 -1
  89. data/test/cgi/lighttpd.conf +0 -26
  90. data/test/cgi/rackup_stub.rb +0 -6
  91. data/test/cgi/sample_rackup.ru +0 -5
  92. data/test/cgi/test +0 -9
  93. data/test/cgi/test+directory/test+file +0 -1
  94. data/test/cgi/test.fcgi +0 -9
  95. data/test/cgi/test.gz +0 -0
  96. data/test/cgi/test.ru +0 -5
  97. data/test/gemloader.rb +0 -10
  98. data/test/helper.rb +0 -34
  99. data/test/multipart/bad_robots +0 -259
  100. data/test/multipart/binary +0 -0
  101. data/test/multipart/content_type_and_no_filename +0 -6
  102. data/test/multipart/empty +0 -10
  103. data/test/multipart/fail_16384_nofile +0 -814
  104. data/test/multipart/file1.txt +0 -1
  105. data/test/multipart/filename_and_modification_param +0 -7
  106. data/test/multipart/filename_and_no_name +0 -6
  107. data/test/multipart/filename_with_encoded_words +0 -7
  108. data/test/multipart/filename_with_escaped_quotes +0 -6
  109. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  110. data/test/multipart/filename_with_null_byte +0 -7
  111. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  112. data/test/multipart/filename_with_single_quote +0 -7
  113. data/test/multipart/filename_with_unescaped_percentages +0 -6
  114. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  115. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  116. data/test/multipart/filename_with_unescaped_quotes +0 -6
  117. data/test/multipart/ie +0 -6
  118. data/test/multipart/invalid_character +0 -6
  119. data/test/multipart/mixed_files +0 -21
  120. data/test/multipart/nested +0 -10
  121. data/test/multipart/none +0 -9
  122. data/test/multipart/quoted +0 -15
  123. data/test/multipart/rack-logo.png +0 -0
  124. data/test/multipart/semicolon +0 -6
  125. data/test/multipart/text +0 -15
  126. data/test/multipart/three_files_three_fields +0 -31
  127. data/test/multipart/unity3d_wwwform +0 -11
  128. data/test/multipart/webkit +0 -32
  129. data/test/rackup/config.ru +0 -31
  130. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  131. data/test/spec_auth_basic.rb +0 -89
  132. data/test/spec_auth_digest.rb +0 -260
  133. data/test/spec_body_proxy.rb +0 -85
  134. data/test/spec_builder.rb +0 -233
  135. data/test/spec_cascade.rb +0 -63
  136. data/test/spec_cgi.rb +0 -84
  137. data/test/spec_chunked.rb +0 -103
  138. data/test/spec_common_logger.rb +0 -107
  139. data/test/spec_conditional_get.rb +0 -103
  140. data/test/spec_config.rb +0 -23
  141. data/test/spec_content_length.rb +0 -86
  142. data/test/spec_content_type.rb +0 -46
  143. data/test/spec_deflater.rb +0 -375
  144. data/test/spec_directory.rb +0 -148
  145. data/test/spec_etag.rb +0 -108
  146. data/test/spec_events.rb +0 -133
  147. data/test/spec_fastcgi.rb +0 -85
  148. data/test/spec_file.rb +0 -264
  149. data/test/spec_handler.rb +0 -57
  150. data/test/spec_head.rb +0 -46
  151. data/test/spec_lint.rb +0 -520
  152. data/test/spec_lobster.rb +0 -59
  153. data/test/spec_lock.rb +0 -204
  154. data/test/spec_logger.rb +0 -24
  155. data/test/spec_media_type.rb +0 -42
  156. data/test/spec_method_override.rb +0 -110
  157. data/test/spec_mime.rb +0 -51
  158. data/test/spec_mock.rb +0 -359
  159. data/test/spec_multipart.rb +0 -721
  160. data/test/spec_null_logger.rb +0 -21
  161. data/test/spec_recursive.rb +0 -75
  162. data/test/spec_request.rb +0 -1423
  163. data/test/spec_response.rb +0 -528
  164. data/test/spec_rewindable_input.rb +0 -128
  165. data/test/spec_runtime.rb +0 -50
  166. data/test/spec_sendfile.rb +0 -125
  167. data/test/spec_server.rb +0 -193
  168. data/test/spec_session_abstract_id.rb +0 -31
  169. data/test/spec_session_abstract_session_hash.rb +0 -45
  170. data/test/spec_session_cookie.rb +0 -442
  171. data/test/spec_session_memcache.rb +0 -357
  172. data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
  173. data/test/spec_session_pool.rb +0 -247
  174. data/test/spec_show_exceptions.rb +0 -93
  175. data/test/spec_show_status.rb +0 -104
  176. data/test/spec_static.rb +0 -184
  177. data/test/spec_tempfile_reaper.rb +0 -64
  178. data/test/spec_thin.rb +0 -96
  179. data/test/spec_urlmap.rb +0 -237
  180. data/test/spec_utils.rb +0 -742
  181. data/test/spec_version.rb +0 -11
  182. data/test/spec_webrick.rb +0 -206
  183. data/test/static/another/index.html +0 -1
  184. data/test/static/foo.html +0 -1
  185. data/test/static/index.html +0 -1
  186. data/test/testrequest.rb +0 -78
  187. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  188. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,357 +0,0 @@
1
- require 'minitest/autorun'
2
- begin
3
- require 'rack/session/memcache'
4
- require 'rack/lint'
5
- require 'rack/mock'
6
- require 'thread'
7
-
8
- describe Rack::Session::Memcache do
9
- session_key = Rack::Session::Memcache::DEFAULT_OPTIONS[:key]
10
- session_match = /#{session_key}=([0-9a-fA-F]+);/
11
- incrementor = lambda do |env|
12
- env["rack.session"]["counter"] ||= 0
13
- env["rack.session"]["counter"] += 1
14
- Rack::Response.new(env["rack.session"].inspect).to_a
15
- end
16
- drop_session = Rack::Lint.new(proc do |env|
17
- env['rack.session.options'][:drop] = true
18
- incrementor.call(env)
19
- end)
20
- renew_session = Rack::Lint.new(proc do |env|
21
- env['rack.session.options'][:renew] = true
22
- incrementor.call(env)
23
- end)
24
- defer_session = Rack::Lint.new(proc do |env|
25
- env['rack.session.options'][:defer] = true
26
- incrementor.call(env)
27
- end)
28
- skip_session = Rack::Lint.new(proc do |env|
29
- env['rack.session.options'][:skip] = true
30
- incrementor.call(env)
31
- end)
32
- incrementor = Rack::Lint.new(incrementor)
33
-
34
- # test memcache connection
35
- Rack::Session::Memcache.new(incrementor)
36
-
37
- it "faults on no connection" do
38
- lambda {
39
- Rack::Session::Memcache.new(incrementor, :memcache_server => 'nosuchserver')
40
- }.must_raise(RuntimeError).message.must_equal 'No memcache servers'
41
- end
42
-
43
- it "connects to existing server" do
44
- test_pool = MemCache.new(incrementor, :namespace => 'test:rack:session')
45
- test_pool.namespace.must_equal 'test:rack:session'
46
- end
47
-
48
- it "passes options to MemCache" do
49
- pool = Rack::Session::Memcache.new(incrementor, :namespace => 'test:rack:session')
50
- pool.pool.namespace.must_equal 'test:rack:session'
51
- end
52
-
53
- it "creates a new cookie" do
54
- pool = Rack::Session::Memcache.new(incrementor)
55
- res = Rack::MockRequest.new(pool).get("/")
56
- res["Set-Cookie"].must_include "#{session_key}="
57
- res.body.must_equal '{"counter"=>1}'
58
- end
59
-
60
- it "determines session from a cookie" do
61
- pool = Rack::Session::Memcache.new(incrementor)
62
- req = Rack::MockRequest.new(pool)
63
- res = req.get("/")
64
- cookie = res["Set-Cookie"]
65
- req.get("/", "HTTP_COOKIE" => cookie).
66
- body.must_equal '{"counter"=>2}'
67
- req.get("/", "HTTP_COOKIE" => cookie).
68
- body.must_equal '{"counter"=>3}'
69
- end
70
-
71
- it "determines session only from a cookie by default" do
72
- pool = Rack::Session::Memcache.new(incrementor)
73
- req = Rack::MockRequest.new(pool)
74
- res = req.get("/")
75
- sid = res["Set-Cookie"][session_match, 1]
76
- req.get("/?rack.session=#{sid}").
77
- body.must_equal '{"counter"=>1}'
78
- req.get("/?rack.session=#{sid}").
79
- body.must_equal '{"counter"=>1}'
80
- end
81
-
82
- it "determines session from params" do
83
- pool = Rack::Session::Memcache.new(incrementor, :cookie_only => false)
84
- req = Rack::MockRequest.new(pool)
85
- res = req.get("/")
86
- sid = res["Set-Cookie"][session_match, 1]
87
- req.get("/?rack.session=#{sid}").
88
- body.must_equal '{"counter"=>2}'
89
- req.get("/?rack.session=#{sid}").
90
- body.must_equal '{"counter"=>3}'
91
- end
92
-
93
- it "survives nonexistant cookies" do
94
- bad_cookie = "rack.session=blarghfasel"
95
- pool = Rack::Session::Memcache.new(incrementor)
96
- res = Rack::MockRequest.new(pool).
97
- get("/", "HTTP_COOKIE" => bad_cookie)
98
- res.body.must_equal '{"counter"=>1}'
99
- cookie = res["Set-Cookie"][session_match]
100
- cookie.wont_match(/#{bad_cookie}/)
101
- end
102
-
103
- it "maintains freshness" do
104
- pool = Rack::Session::Memcache.new(incrementor, :expire_after => 3)
105
- res = Rack::MockRequest.new(pool).get('/')
106
- res.body.must_include '"counter"=>1'
107
- cookie = res["Set-Cookie"]
108
- res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
109
- res["Set-Cookie"].must_equal cookie
110
- res.body.must_include '"counter"=>2'
111
- puts 'Sleeping to expire session' if $DEBUG
112
- sleep 4
113
- res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
114
- res["Set-Cookie"].wont_equal cookie
115
- res.body.must_include '"counter"=>1'
116
- end
117
-
118
- it "does not send the same session id if it did not change" do
119
- pool = Rack::Session::Memcache.new(incrementor)
120
- req = Rack::MockRequest.new(pool)
121
-
122
- res0 = req.get("/")
123
- cookie = res0["Set-Cookie"][session_match]
124
- res0.body.must_equal '{"counter"=>1}'
125
-
126
- res1 = req.get("/", "HTTP_COOKIE" => cookie)
127
- res1["Set-Cookie"].must_be_nil
128
- res1.body.must_equal '{"counter"=>2}'
129
-
130
- res2 = req.get("/", "HTTP_COOKIE" => cookie)
131
- res2["Set-Cookie"].must_be_nil
132
- res2.body.must_equal '{"counter"=>3}'
133
- end
134
-
135
- it "deletes cookies with :drop option" do
136
- pool = Rack::Session::Memcache.new(incrementor)
137
- req = Rack::MockRequest.new(pool)
138
- drop = Rack::Utils::Context.new(pool, drop_session)
139
- dreq = Rack::MockRequest.new(drop)
140
-
141
- res1 = req.get("/")
142
- session = (cookie = res1["Set-Cookie"])[session_match]
143
- res1.body.must_equal '{"counter"=>1}'
144
-
145
- res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
146
- res2["Set-Cookie"].must_be_nil
147
- res2.body.must_equal '{"counter"=>2}'
148
-
149
- res3 = req.get("/", "HTTP_COOKIE" => cookie)
150
- res3["Set-Cookie"][session_match].wont_equal session
151
- res3.body.must_equal '{"counter"=>1}'
152
- end
153
-
154
- it "provides new session id with :renew option" do
155
- pool = Rack::Session::Memcache.new(incrementor)
156
- req = Rack::MockRequest.new(pool)
157
- renew = Rack::Utils::Context.new(pool, renew_session)
158
- rreq = Rack::MockRequest.new(renew)
159
-
160
- res1 = req.get("/")
161
- session = (cookie = res1["Set-Cookie"])[session_match]
162
- res1.body.must_equal '{"counter"=>1}'
163
-
164
- res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
165
- new_cookie = res2["Set-Cookie"]
166
- new_session = new_cookie[session_match]
167
- new_session.wont_equal session
168
- res2.body.must_equal '{"counter"=>2}'
169
-
170
- res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
171
- res3.body.must_equal '{"counter"=>3}'
172
-
173
- # Old cookie was deleted
174
- res4 = req.get("/", "HTTP_COOKIE" => cookie)
175
- res4.body.must_equal '{"counter"=>1}'
176
- end
177
-
178
- it "omits cookie with :defer option but still updates the state" do
179
- pool = Rack::Session::Memcache.new(incrementor)
180
- count = Rack::Utils::Context.new(pool, incrementor)
181
- defer = Rack::Utils::Context.new(pool, defer_session)
182
- dreq = Rack::MockRequest.new(defer)
183
- creq = Rack::MockRequest.new(count)
184
-
185
- res0 = dreq.get("/")
186
- res0["Set-Cookie"].must_be_nil
187
- res0.body.must_equal '{"counter"=>1}'
188
-
189
- res0 = creq.get("/")
190
- res1 = dreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
191
- res1.body.must_equal '{"counter"=>2}'
192
- res2 = dreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
193
- res2.body.must_equal '{"counter"=>3}'
194
- end
195
-
196
- it "omits cookie and state update with :skip option" do
197
- pool = Rack::Session::Memcache.new(incrementor)
198
- count = Rack::Utils::Context.new(pool, incrementor)
199
- skip = Rack::Utils::Context.new(pool, skip_session)
200
- sreq = Rack::MockRequest.new(skip)
201
- creq = Rack::MockRequest.new(count)
202
-
203
- res0 = sreq.get("/")
204
- res0["Set-Cookie"].must_be_nil
205
- res0.body.must_equal '{"counter"=>1}'
206
-
207
- res0 = creq.get("/")
208
- res1 = sreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
209
- res1.body.must_equal '{"counter"=>2}'
210
- res2 = sreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
211
- res2.body.must_equal '{"counter"=>2}'
212
- end
213
-
214
- it "updates deep hashes correctly" do
215
- hash_check = proc do |env|
216
- session = env['rack.session']
217
- unless session.include? 'test'
218
- session.update :a => :b, :c => { :d => :e },
219
- :f => { :g => { :h => :i} }, 'test' => true
220
- else
221
- session[:f][:g][:h] = :j
222
- end
223
- [200, {}, [session.inspect]]
224
- end
225
- pool = Rack::Session::Memcache.new(hash_check)
226
- req = Rack::MockRequest.new(pool)
227
-
228
- res0 = req.get("/")
229
- session_id = Rack::Session::SessionId.new (cookie = res0["Set-Cookie"])[session_match, 1]
230
- ses0 = pool.pool.get(session_id.private_id, true)
231
-
232
- req.get("/", "HTTP_COOKIE" => cookie)
233
- ses1 = pool.pool.get(session_id.private_id, true)
234
-
235
- ses1.wont_equal ses0
236
- end
237
-
238
- it "can read the session with the legacy id" do
239
- pool = Rack::Session::Memcache.new(incrementor)
240
- req = Rack::MockRequest.new(pool)
241
-
242
- res0 = req.get("/")
243
- cookie = res0["Set-Cookie"]
244
- session_id = Rack::Session::SessionId.new cookie[session_match, 1]
245
- ses0 = pool.pool.get(session_id.private_id, true)
246
- pool.pool.set(session_id.public_id, ses0, 0, true)
247
- pool.pool.delete(session_id.private_id)
248
-
249
- res1 = req.get("/", "HTTP_COOKIE" => cookie)
250
- res1["Set-Cookie"].must_be_nil
251
- res1.body.must_equal '{"counter"=>2}'
252
- pool.pool.get(session_id.private_id, true).wont_be_nil
253
- end
254
-
255
- it "drops the session in the legacy id as well" do
256
- pool = Rack::Session::Memcache.new(incrementor)
257
- req = Rack::MockRequest.new(pool)
258
- drop = Rack::Utils::Context.new(pool, drop_session)
259
- dreq = Rack::MockRequest.new(drop)
260
-
261
- res0 = req.get("/")
262
- cookie = res0["Set-Cookie"]
263
- session_id = Rack::Session::SessionId.new cookie[session_match, 1]
264
- ses0 = pool.pool.get(session_id.private_id, true)
265
- pool.pool.set(session_id.public_id, ses0, 0, true)
266
- pool.pool.delete(session_id.private_id)
267
-
268
- res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
269
- res2["Set-Cookie"].must_be_nil
270
- res2.body.must_equal '{"counter"=>2}'
271
- pool.pool.get(session_id.private_id, true).must_be_nil
272
- pool.pool.get(session_id.public_id, true).must_be_nil
273
- end
274
-
275
- # anyone know how to do this better?
276
- it "cleanly merges sessions when multithreaded" do
277
- skip unless $DEBUG
278
-
279
- warn 'Running multithread test for Session::Memcache'
280
- pool = Rack::Session::Memcache.new(incrementor)
281
- req = Rack::MockRequest.new(pool)
282
-
283
- res = req.get('/')
284
- res.body.must_equal '{"counter"=>1}'
285
- cookie = res["Set-Cookie"]
286
- session_id = cookie[session_match, 1]
287
-
288
- delta_incrementor = lambda do |env|
289
- # emulate disconjoinment of threading
290
- env['rack.session'] = env['rack.session'].dup
291
- Thread.stop
292
- env['rack.session'][(Time.now.usec*rand).to_i] = true
293
- incrementor.call(env)
294
- end
295
- tses = Rack::Utils::Context.new pool, delta_incrementor
296
- treq = Rack::MockRequest.new(tses)
297
- tnum = rand(7).to_i+5
298
- r = Array.new(tnum) do
299
- Thread.new(treq) do |run|
300
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
301
- end
302
- end.reverse.map{|t| t.run.join.value }
303
- r.each do |request|
304
- request['Set-Cookie'].must_equal cookie
305
- request.body.must_include '"counter"=>2'
306
- end
307
-
308
- session = pool.pool.get(session_id)
309
- session.size.must_equal tnum+1 # counter
310
- session['counter'].must_equal 2 # meeeh
311
-
312
- tnum = rand(7).to_i+5
313
- r = Array.new(tnum) do
314
- app = Rack::Utils::Context.new pool, time_delta
315
- req = Rack::MockRequest.new app
316
- Thread.new(req) do |run|
317
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
318
- end
319
- end.reverse.map{|t| t.run.join.value }
320
- r.each do |request|
321
- request['Set-Cookie'].must_equal cookie
322
- request.body.must_include '"counter"=>3'
323
- end
324
-
325
- session = pool.pool.get(session_id)
326
- session.size.must_equal tnum+1
327
- session['counter'].must_equal 3
328
-
329
- drop_counter = proc do |env|
330
- env['rack.session'].delete 'counter'
331
- env['rack.session']['foo'] = 'bar'
332
- [200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
333
- end
334
- tses = Rack::Utils::Context.new pool, drop_counter
335
- treq = Rack::MockRequest.new(tses)
336
- tnum = rand(7).to_i+5
337
- r = Array.new(tnum) do
338
- Thread.new(treq) do |run|
339
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
340
- end
341
- end.reverse.map{|t| t.run.join.value }
342
- r.each do |request|
343
- request['Set-Cookie'].must_equal cookie
344
- request.body.must_include '"foo"=>"bar"'
345
- end
346
-
347
- session = pool.pool.get(session_id)
348
- session.size.must_equal r.size+1
349
- session['counter'].must_be_nil?
350
- session['foo'].must_equal 'bar'
351
- end
352
- end
353
- rescue RuntimeError
354
- $stderr.puts "Skipping Rack::Session::Memcache tests. Start memcached and try again."
355
- rescue LoadError
356
- $stderr.puts "Skipping Rack::Session::Memcache tests (Memcache is required). `gem install memcache-client` and try again."
357
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'minitest/global_expectations/autorun'
4
- require 'rack/session/abstract/id'
5
-
6
- describe Rack::Session::Abstract::PersistedSecure::SecureSessionHash do
7
- attr_reader :hash
8
-
9
- def setup
10
- super
11
- @store = Class.new do
12
- def load_session(req)
13
- [Rack::Session::SessionId.new("id"), { foo: :bar, baz: :qux }]
14
- end
15
- def session_exists?(req)
16
- true
17
- end
18
- end
19
- @hash = Rack::Session::Abstract::PersistedSecure::SecureSessionHash.new(@store.new, nil)
20
- end
21
-
22
- it "returns keys" do
23
- assert_equal ["foo", "baz"], hash.keys
24
- end
25
-
26
- it "returns values" do
27
- assert_equal [:bar, :qux], hash.values
28
- end
29
-
30
- describe "#[]" do
31
- it "returns value for a matching key" do
32
- assert_equal :bar, hash[:foo]
33
- end
34
-
35
- it "returns value for a 'session_id' key" do
36
- assert_equal "id", hash['session_id']
37
- end
38
-
39
- it "returns nil value for missing 'session_id' key" do
40
- store = @store.new
41
- def store.load_session(req)
42
- [nil, {}]
43
- end
44
- @hash = Rack::Session::Abstract::PersistedSecure::SecureSessionHash.new(store, nil)
45
- assert_nil hash['session_id']
46
- end
47
- end
48
-
49
- describe "#fetch" do
50
- it "returns value for a matching key" do
51
- assert_equal :bar, hash.fetch(:foo)
52
- end
53
-
54
- it "works with a default value" do
55
- assert_equal :default, hash.fetch(:unknown, :default)
56
- end
57
-
58
- it "works with a block" do
59
- assert_equal :default, hash.fetch(:unkown) { :default }
60
- end
61
-
62
- it "it raises when fetching unknown keys without defaults" do
63
- lambda { hash.fetch(:unknown) }.must_raise KeyError
64
- end
65
- end
66
-
67
- describe "#stringify_keys" do
68
- it "returns hash or session hash with keys stringified" do
69
- assert_equal({ "foo" => :bar, "baz" => :qux }, hash.send(:stringify_keys, hash).to_h)
70
- end
71
- end
72
- end
73
-
@@ -1,247 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'thread'
3
- require 'rack/lint'
4
- require 'rack/mock'
5
- require 'rack/session/pool'
6
-
7
- describe Rack::Session::Pool do
8
- session_key = Rack::Session::Pool::DEFAULT_OPTIONS[:key]
9
- session_match = /#{session_key}=([0-9a-fA-F]+);/
10
-
11
- incrementor = lambda do |env|
12
- env["rack.session"]["counter"] ||= 0
13
- env["rack.session"]["counter"] += 1
14
- Rack::Response.new(env["rack.session"].inspect).to_a
15
- end
16
-
17
- get_session_id = Rack::Lint.new(lambda do |env|
18
- Rack::Response.new(env["rack.session"].inspect).to_a
19
- end)
20
-
21
- nothing = Rack::Lint.new(lambda do |env|
22
- Rack::Response.new("Nothing").to_a
23
- end)
24
-
25
- drop_session = Rack::Lint.new(lambda do |env|
26
- env['rack.session.options'][:drop] = true
27
- incrementor.call(env)
28
- end)
29
-
30
- renew_session = Rack::Lint.new(lambda do |env|
31
- env['rack.session.options'][:renew] = true
32
- incrementor.call(env)
33
- end)
34
-
35
- defer_session = Rack::Lint.new(lambda do |env|
36
- env['rack.session.options'][:defer] = true
37
- incrementor.call(env)
38
- end)
39
-
40
- incrementor = Rack::Lint.new(incrementor)
41
-
42
- it "creates a new cookie" do
43
- pool = Rack::Session::Pool.new(incrementor)
44
- res = Rack::MockRequest.new(pool).get("/")
45
- res["Set-Cookie"].must_match(session_match)
46
- res.body.must_equal '{"counter"=>1}'
47
- end
48
-
49
- it "determines session from a cookie" do
50
- pool = Rack::Session::Pool.new(incrementor)
51
- req = Rack::MockRequest.new(pool)
52
- cookie = req.get("/")["Set-Cookie"]
53
- req.get("/", "HTTP_COOKIE" => cookie).
54
- body.must_equal '{"counter"=>2}'
55
- req.get("/", "HTTP_COOKIE" => cookie).
56
- body.must_equal '{"counter"=>3}'
57
- end
58
-
59
- it "survives nonexistant cookies" do
60
- pool = Rack::Session::Pool.new(incrementor)
61
- res = Rack::MockRequest.new(pool).
62
- get("/", "HTTP_COOKIE" => "#{session_key}=blarghfasel")
63
- res.body.must_equal '{"counter"=>1}'
64
- end
65
-
66
- it "does not send the same session id if it did not change" do
67
- pool = Rack::Session::Pool.new(incrementor)
68
- req = Rack::MockRequest.new(pool)
69
-
70
- res0 = req.get("/")
71
- cookie = res0["Set-Cookie"][session_match]
72
- res0.body.must_equal '{"counter"=>1}'
73
- pool.pool.size.must_equal 1
74
-
75
- res1 = req.get("/", "HTTP_COOKIE" => cookie)
76
- res1["Set-Cookie"].must_be_nil
77
- res1.body.must_equal '{"counter"=>2}'
78
- pool.pool.size.must_equal 1
79
-
80
- res2 = req.get("/", "HTTP_COOKIE" => cookie)
81
- res2["Set-Cookie"].must_be_nil
82
- res2.body.must_equal '{"counter"=>3}'
83
- pool.pool.size.must_equal 1
84
- end
85
-
86
- it "deletes cookies with :drop option" do
87
- pool = Rack::Session::Pool.new(incrementor)
88
- req = Rack::MockRequest.new(pool)
89
- drop = Rack::Utils::Context.new(pool, drop_session)
90
- dreq = Rack::MockRequest.new(drop)
91
-
92
- res1 = req.get("/")
93
- session = (cookie = res1["Set-Cookie"])[session_match]
94
- res1.body.must_equal '{"counter"=>1}'
95
- pool.pool.size.must_equal 1
96
-
97
- res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
98
- res2["Set-Cookie"].must_be_nil
99
- res2.body.must_equal '{"counter"=>2}'
100
- pool.pool.size.must_equal 0
101
-
102
- res3 = req.get("/", "HTTP_COOKIE" => cookie)
103
- res3["Set-Cookie"][session_match].wont_equal session
104
- res3.body.must_equal '{"counter"=>1}'
105
- pool.pool.size.must_equal 1
106
- end
107
-
108
- it "provides new session id with :renew option" do
109
- pool = Rack::Session::Pool.new(incrementor)
110
- req = Rack::MockRequest.new(pool)
111
- renew = Rack::Utils::Context.new(pool, renew_session)
112
- rreq = Rack::MockRequest.new(renew)
113
-
114
- res1 = req.get("/")
115
- session = (cookie = res1["Set-Cookie"])[session_match]
116
- res1.body.must_equal '{"counter"=>1}'
117
- pool.pool.size.must_equal 1
118
-
119
- res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
120
- new_cookie = res2["Set-Cookie"]
121
- new_session = new_cookie[session_match]
122
- new_session.wont_equal session
123
- res2.body.must_equal '{"counter"=>2}'
124
- pool.pool.size.must_equal 1
125
-
126
- res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
127
- res3.body.must_equal '{"counter"=>3}'
128
- pool.pool.size.must_equal 1
129
-
130
- res4 = req.get("/", "HTTP_COOKIE" => cookie)
131
- res4.body.must_equal '{"counter"=>1}'
132
- pool.pool.size.must_equal 2
133
- end
134
-
135
- it "omits cookie with :defer option" do
136
- pool = Rack::Session::Pool.new(incrementor)
137
- defer = Rack::Utils::Context.new(pool, defer_session)
138
- dreq = Rack::MockRequest.new(defer)
139
-
140
- res1 = dreq.get("/")
141
- res1["Set-Cookie"].must_be_nil
142
- res1.body.must_equal '{"counter"=>1}'
143
- pool.pool.size.must_equal 1
144
- end
145
-
146
- it "can read the session with the legacy id" do
147
- pool = Rack::Session::Pool.new(incrementor)
148
- req = Rack::MockRequest.new(pool)
149
-
150
- res0 = req.get("/")
151
- cookie = res0["Set-Cookie"]
152
- session_id = Rack::Session::SessionId.new cookie[session_match, 1]
153
- ses0 = pool.pool[session_id.private_id]
154
- pool.pool[session_id.public_id] = ses0
155
- pool.pool.delete(session_id.private_id)
156
-
157
- res1 = req.get("/", "HTTP_COOKIE" => cookie)
158
- res1["Set-Cookie"].must_be_nil
159
- res1.body.must_equal '{"counter"=>2}'
160
- pool.pool[session_id.private_id].wont_be_nil
161
- end
162
-
163
- it "drops the session in the legacy id as well" do
164
- pool = Rack::Session::Pool.new(incrementor)
165
- req = Rack::MockRequest.new(pool)
166
- drop = Rack::Utils::Context.new(pool, drop_session)
167
- dreq = Rack::MockRequest.new(drop)
168
-
169
- res0 = req.get("/")
170
- cookie = res0["Set-Cookie"]
171
- session_id = Rack::Session::SessionId.new cookie[session_match, 1]
172
- ses0 = pool.pool[session_id.private_id]
173
- pool.pool[session_id.public_id] = ses0
174
- pool.pool.delete(session_id.private_id)
175
-
176
- res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
177
- res2["Set-Cookie"].must_be_nil
178
- res2.body.must_equal '{"counter"=>2}'
179
- pool.pool[session_id.private_id].must_be_nil
180
- pool.pool[session_id.public_id].must_be_nil
181
- end
182
-
183
- # anyone know how to do this better?
184
- it "should merge sessions when multithreaded" do
185
- unless $DEBUG
186
- 1.must_equal 1
187
- next
188
- end
189
-
190
- warn 'Running multithread tests for Session::Pool'
191
- pool = Rack::Session::Pool.new(incrementor)
192
- req = Rack::MockRequest.new(pool)
193
-
194
- res = req.get('/')
195
- res.body.must_equal '{"counter"=>1}'
196
- cookie = res["Set-Cookie"]
197
- sess_id = cookie[/#{pool.key}=([^,;]+)/,1]
198
-
199
- delta_incrementor = lambda do |env|
200
- # emulate disconjoinment of threading
201
- env['rack.session'] = env['rack.session'].dup
202
- Thread.stop
203
- env['rack.session'][(Time.now.usec*rand).to_i] = true
204
- incrementor.call(env)
205
- end
206
- tses = Rack::Utils::Context.new pool, delta_incrementor
207
- treq = Rack::MockRequest.new(tses)
208
- tnum = rand(7).to_i+5
209
- r = Array.new(tnum) do
210
- Thread.new(treq) do |run|
211
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
212
- end
213
- end.reverse.map{|t| t.run.join.value }
214
- r.each do |resp|
215
- resp['Set-Cookie'].must_equal cookie
216
- resp.body.must_include '"counter"=>2'
217
- end
218
-
219
- session = pool.pool[sess_id]
220
- session.size.must_equal tnum+1 # counter
221
- session['counter'].must_equal 2 # meeeh
222
- end
223
-
224
- it "does not return a cookie if cookie was not read/written" do
225
- app = Rack::Session::Pool.new(nothing)
226
- res = Rack::MockRequest.new(app).get("/")
227
- res["Set-Cookie"].must_be_nil
228
- end
229
-
230
- it "does not return a cookie if cookie was not written (only read)" do
231
- app = Rack::Session::Pool.new(get_session_id)
232
- res = Rack::MockRequest.new(app).get("/")
233
- res["Set-Cookie"].must_be_nil
234
- end
235
-
236
- it "returns even if not read/written if :expire_after is set" do
237
- app = Rack::Session::Pool.new(nothing, :expire_after => 3600)
238
- res = Rack::MockRequest.new(app).get("/", 'rack.session' => {'not' => 'empty'})
239
- res["Set-Cookie"].wont_be :nil?
240
- end
241
-
242
- it "returns no cookie if no data was written and no session was created previously, even if :expire_after is set" do
243
- app = Rack::Session::Pool.new(nothing, :expire_after => 3600)
244
- res = Rack::MockRequest.new(app).get("/")
245
- res["Set-Cookie"].must_be_nil
246
- end
247
- end