rack 1.6.13 → 2.2.3

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