rack 1.6.11 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack might be problematic. Click here for more details.

Files changed (190) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +675 -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 +20 -11
  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 +543 -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 +216 -93
  67. data/lib/rack/session/cookie.rb +47 -31
  68. data/lib/rack/session/memcache.rb +4 -87
  69. data/lib/rack/session/pool.rb +26 -17
  70. data/lib/rack/show_exceptions.rb +390 -0
  71. data/lib/rack/{showstatus.rb → show_status.rb} +8 -8
  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 +208 -294
  76. data/lib/rack/version.rb +29 -0
  77. data/lib/rack.rb +76 -33
  78. data/rack.gemspec +43 -30
  79. metadata +62 -183
  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 -321
  176. data/test/spec_session_pool.rb +0 -209
  177. data/test/spec_showexceptions.rb +0 -98
  178. data/test/spec_showstatus.rb +0 -103
  179. data/test/spec_static.rb +0 -145
  180. data/test/spec_tempfile_reaper.rb +0 -63
  181. data/test/spec_thin.rb +0 -91
  182. data/test/spec_urlmap.rb +0 -236
  183. data/test/spec_utils.rb +0 -647
  184. data/test/spec_version.rb +0 -17
  185. data/test/spec_webrick.rb +0 -184
  186. data/test/static/another/index.html +0 -1
  187. data/test/static/index.html +0 -1
  188. data/test/testrequest.rb +0 -78
  189. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  190. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,321 +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 = (cookie = res0["Set-Cookie"])[session_match, 1]
229
- ses0 = pool.pool.get(session_id, true)
230
-
231
- req.get("/", "HTTP_COOKIE" => cookie)
232
- ses1 = pool.pool.get(session_id, true)
233
-
234
- ses1.should.not.equal ses0
235
- end
236
-
237
- # anyone know how to do this better?
238
- it "cleanly merges sessions when multithreaded" do
239
- unless $DEBUG
240
- 1.should.equal 1 # fake assertion to appease the mighty bacon
241
- next
242
- end
243
- warn 'Running multithread test for Session::Memcache'
244
- pool = Rack::Session::Memcache.new(incrementor)
245
- req = Rack::MockRequest.new(pool)
246
-
247
- res = req.get('/')
248
- res.body.should.equal '{"counter"=>1}'
249
- cookie = res["Set-Cookie"]
250
- session_id = cookie[session_match, 1]
251
-
252
- delta_incrementor = lambda do |env|
253
- # emulate disconjoinment of threading
254
- env['rack.session'] = env['rack.session'].dup
255
- Thread.stop
256
- env['rack.session'][(Time.now.usec*rand).to_i] = true
257
- incrementor.call(env)
258
- end
259
- tses = Rack::Utils::Context.new pool, delta_incrementor
260
- treq = Rack::MockRequest.new(tses)
261
- tnum = rand(7).to_i+5
262
- r = Array.new(tnum) do
263
- Thread.new(treq) do |run|
264
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
265
- end
266
- end.reverse.map{|t| t.run.join.value }
267
- r.each do |request|
268
- request['Set-Cookie'].should.equal cookie
269
- request.body.should.include '"counter"=>2'
270
- end
271
-
272
- session = pool.pool.get(session_id)
273
- session.size.should.equal tnum+1 # counter
274
- session['counter'].should.equal 2 # meeeh
275
-
276
- tnum = rand(7).to_i+5
277
- r = Array.new(tnum) do
278
- app = Rack::Utils::Context.new pool, time_delta
279
- req = Rack::MockRequest.new app
280
- Thread.new(req) do |run|
281
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
282
- end
283
- end.reverse.map{|t| t.run.join.value }
284
- r.each do |request|
285
- request['Set-Cookie'].should.equal cookie
286
- request.body.should.include '"counter"=>3'
287
- end
288
-
289
- session = pool.pool.get(session_id)
290
- session.size.should.be tnum+1
291
- session['counter'].should.be 3
292
-
293
- drop_counter = proc do |env|
294
- env['rack.session'].delete 'counter'
295
- env['rack.session']['foo'] = 'bar'
296
- [200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
297
- end
298
- tses = Rack::Utils::Context.new pool, drop_counter
299
- treq = Rack::MockRequest.new(tses)
300
- tnum = rand(7).to_i+5
301
- r = Array.new(tnum) do
302
- Thread.new(treq) do |run|
303
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
304
- end
305
- end.reverse.map{|t| t.run.join.value }
306
- r.each do |request|
307
- request['Set-Cookie'].should.equal cookie
308
- request.body.should.include '"foo"=>"bar"'
309
- end
310
-
311
- session = pool.pool.get(session_id)
312
- session.size.should.be r.size+1
313
- session['counter'].should.be.nil?
314
- session['foo'].should.equal 'bar'
315
- end
316
- end
317
- rescue RuntimeError
318
- $stderr.puts "Skipping Rack::Session::Memcache tests. Start memcached and try again."
319
- rescue LoadError
320
- $stderr.puts "Skipping Rack::Session::Memcache tests (Memcache is required). `gem install memcache-client` and try again."
321
- end
@@ -1,209 +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
- 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
- # anyone know how to do this better?
146
- it "should merge sessions when multithreaded" do
147
- unless $DEBUG
148
- 1.should.equal 1
149
- next
150
- end
151
-
152
- warn 'Running multithread tests for Session::Pool'
153
- pool = Rack::Session::Pool.new(incrementor)
154
- req = Rack::MockRequest.new(pool)
155
-
156
- res = req.get('/')
157
- res.body.should.equal '{"counter"=>1}'
158
- cookie = res["Set-Cookie"]
159
- sess_id = cookie[/#{pool.key}=([^,;]+)/,1]
160
-
161
- delta_incrementor = lambda do |env|
162
- # emulate disconjoinment of threading
163
- env['rack.session'] = env['rack.session'].dup
164
- Thread.stop
165
- env['rack.session'][(Time.now.usec*rand).to_i] = true
166
- incrementor.call(env)
167
- end
168
- tses = Rack::Utils::Context.new pool, delta_incrementor
169
- treq = Rack::MockRequest.new(tses)
170
- tnum = rand(7).to_i+5
171
- r = Array.new(tnum) do
172
- Thread.new(treq) do |run|
173
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
174
- end
175
- end.reverse.map{|t| t.run.join.value }
176
- r.each do |resp|
177
- resp['Set-Cookie'].should.equal cookie
178
- resp.body.should.include '"counter"=>2'
179
- end
180
-
181
- session = pool.pool[sess_id]
182
- session.size.should.equal tnum+1 # counter
183
- session['counter'].should.equal 2 # meeeh
184
- end
185
-
186
- it "does not return a cookie if cookie was not read/written" do
187
- app = Rack::Session::Pool.new(nothing)
188
- res = Rack::MockRequest.new(app).get("/")
189
- res["Set-Cookie"].should.be.nil
190
- end
191
-
192
- it "does not return a cookie if cookie was not written (only read)" do
193
- app = Rack::Session::Pool.new(session_id)
194
- res = Rack::MockRequest.new(app).get("/")
195
- res["Set-Cookie"].should.be.nil
196
- end
197
-
198
- it "returns even if not read/written if :expire_after is set" do
199
- app = Rack::Session::Pool.new(nothing, :expire_after => 3600)
200
- res = Rack::MockRequest.new(app).get("/", 'rack.session' => {'not' => 'empty'})
201
- res["Set-Cookie"].should.not.be.nil
202
- end
203
-
204
- it "returns no cookie if no data was written and no session was created previously, even if :expire_after is set" do
205
- app = Rack::Session::Pool.new(nothing, :expire_after => 3600)
206
- res = Rack::MockRequest.new(app).get("/")
207
- res["Set-Cookie"].should.be.nil
208
- end
209
- end
@@ -1,98 +0,0 @@
1
- require 'rack/showexceptions'
2
- require 'rack/lint'
3
- require 'rack/mock'
4
-
5
- describe Rack::ShowExceptions do
6
- def show_exceptions(app)
7
- Rack::Lint.new Rack::ShowExceptions.new(app)
8
- end
9
-
10
- it "catches exceptions" do
11
- res = nil
12
-
13
- req = Rack::MockRequest.new(
14
- show_exceptions(
15
- lambda{|env| raise RuntimeError }
16
- ))
17
-
18
- lambda{
19
- res = req.get("/", "HTTP_ACCEPT" => "text/html")
20
- }.should.not.raise
21
-
22
- res.should.be.a.server_error
23
- res.status.should.equal 500
24
-
25
- res.should =~ /RuntimeError/
26
- res.should =~ /ShowExceptions/
27
- end
28
-
29
- it "responds with HTML only to requests accepting HTML" do
30
- res = nil
31
-
32
- req = Rack::MockRequest.new(
33
- show_exceptions(
34
- lambda{|env| raise RuntimeError, "It was never supposed to work" }
35
- ))
36
-
37
- [
38
- # Serve text/html when the client accepts text/html
39
- ["text/html", ["/", {"HTTP_ACCEPT" => "text/html"}]],
40
- ["text/html", ["/", {"HTTP_ACCEPT" => "*/*"}]],
41
- # Serve text/plain when the client does not accept text/html
42
- ["text/plain", ["/"]],
43
- ["text/plain", ["/", {"HTTP_ACCEPT" => "application/json"}]]
44
- ].each do |exmime, rargs|
45
- lambda{
46
- res = req.get(*rargs)
47
- }.should.not.raise
48
-
49
- res.should.be.a.server_error
50
- res.status.should.equal 500
51
-
52
- res.content_type.should.equal exmime
53
-
54
- res.body.should.include "RuntimeError"
55
- res.body.should.include "It was never supposed to work"
56
-
57
- if exmime == "text/html"
58
- res.body.should.include '</html>'
59
- else
60
- res.body.should.not.include '</html>'
61
- end
62
- end
63
- end
64
-
65
- it "handles exceptions without a backtrace" do
66
- res = nil
67
-
68
- req = Rack::MockRequest.new(
69
- show_exceptions(
70
- lambda{|env| raise RuntimeError, "", [] }
71
- )
72
- )
73
-
74
- lambda{
75
- res = req.get("/", "HTTP_ACCEPT" => "text/html")
76
- }.should.not.raise
77
-
78
- res.should.be.a.server_error
79
- res.status.should.equal 500
80
-
81
- res.should =~ /RuntimeError/
82
- res.should =~ /ShowExceptions/
83
- res.should =~ /unknown location/
84
- end
85
-
86
- it "knows to prefer plaintext for non-html" do
87
- # We don't need an app for this
88
- exc = Rack::ShowExceptions.new(nil)
89
-
90
- [
91
- [{ "HTTP_ACCEPT" => "text/plain" }, true],
92
- [{ "HTTP_ACCEPT" => "text/foo" }, true],
93
- [{ "HTTP_ACCEPT" => "text/html" }, false]
94
- ].each do |env, expected|
95
- assert_equal(expected, exc.prefers_plaintext?(env))
96
- end
97
- end
98
- end