rack 2.0.9.3 → 3.0.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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +808 -0
  3. data/CONTRIBUTING.md +142 -0
  4. data/{COPYING → MIT-LICENSE} +4 -2
  5. data/README.md +293 -0
  6. data/SPEC.rdoc +340 -0
  7. data/lib/rack/auth/abstract/handler.rb +6 -2
  8. data/lib/rack/auth/abstract/request.rb +4 -2
  9. data/lib/rack/auth/basic.rb +7 -4
  10. data/lib/rack/auth/digest/md5.rb +1 -129
  11. data/lib/rack/auth/digest/nonce.rb +1 -51
  12. data/lib/rack/auth/digest/params.rb +1 -52
  13. data/lib/rack/auth/digest/request.rb +1 -41
  14. data/lib/rack/auth/digest.rb +256 -0
  15. data/lib/rack/body_proxy.rb +18 -15
  16. data/lib/rack/builder.rb +151 -40
  17. data/lib/rack/cascade.rb +30 -12
  18. data/lib/rack/chunked.rb +74 -23
  19. data/lib/rack/common_logger.rb +49 -36
  20. data/lib/rack/conditional_get.rb +33 -26
  21. data/lib/rack/config.rb +2 -0
  22. data/lib/rack/constants.rb +63 -0
  23. data/lib/rack/content_length.rb +13 -16
  24. data/lib/rack/content_type.rb +12 -8
  25. data/lib/rack/deflater.rb +84 -45
  26. data/lib/rack/directory.rb +90 -64
  27. data/lib/rack/etag.rb +17 -23
  28. data/lib/rack/events.rb +23 -20
  29. data/lib/rack/file.rb +5 -172
  30. data/lib/rack/files.rb +216 -0
  31. data/lib/rack/head.rb +10 -9
  32. data/lib/rack/headers.rb +154 -0
  33. data/lib/rack/lint.rb +786 -645
  34. data/lib/rack/lock.rb +4 -6
  35. data/lib/rack/logger.rb +4 -0
  36. data/lib/rack/media_type.rb +10 -5
  37. data/lib/rack/method_override.rb +8 -2
  38. data/lib/rack/mime.rb +17 -1
  39. data/lib/rack/mock.rb +2 -195
  40. data/lib/rack/mock_request.rb +166 -0
  41. data/lib/rack/mock_response.rb +126 -0
  42. data/lib/rack/multipart/generator.rb +21 -15
  43. data/lib/rack/multipart/parser.rb +161 -118
  44. data/lib/rack/multipart/uploaded_file.rb +19 -7
  45. data/lib/rack/multipart.rb +23 -41
  46. data/lib/rack/null_logger.rb +11 -0
  47. data/lib/rack/query_parser.rb +126 -65
  48. data/lib/rack/recursive.rb +9 -5
  49. data/lib/rack/reloader.rb +6 -4
  50. data/lib/rack/request.rb +331 -74
  51. data/lib/rack/response.rb +223 -70
  52. data/lib/rack/rewindable_input.rb +28 -8
  53. data/lib/rack/runtime.rb +11 -8
  54. data/lib/rack/sendfile.rb +42 -33
  55. data/lib/rack/show_exceptions.rb +35 -18
  56. data/lib/rack/show_status.rb +25 -15
  57. data/lib/rack/static.rb +30 -18
  58. data/lib/rack/tempfile_reaper.rb +16 -5
  59. data/lib/rack/urlmap.rb +14 -6
  60. data/lib/rack/utils.rb +268 -260
  61. data/lib/rack/version.rb +34 -0
  62. data/lib/rack.rb +15 -92
  63. metadata +44 -207
  64. data/HISTORY.md +0 -520
  65. data/README.rdoc +0 -316
  66. data/Rakefile +0 -116
  67. data/SPEC +0 -263
  68. data/bin/rackup +0 -4
  69. data/contrib/rack.png +0 -0
  70. data/contrib/rack.svg +0 -150
  71. data/contrib/rack_logo.svg +0 -164
  72. data/contrib/rdoc.css +0 -412
  73. data/example/lobster.ru +0 -4
  74. data/example/protectedlobster.rb +0 -14
  75. data/example/protectedlobster.ru +0 -8
  76. data/lib/rack/handler/cgi.rb +0 -60
  77. data/lib/rack/handler/fastcgi.rb +0 -100
  78. data/lib/rack/handler/lsws.rb +0 -61
  79. data/lib/rack/handler/scgi.rb +0 -70
  80. data/lib/rack/handler/thin.rb +0 -36
  81. data/lib/rack/handler/webrick.rb +0 -120
  82. data/lib/rack/handler.rb +0 -99
  83. data/lib/rack/lobster.rb +0 -70
  84. data/lib/rack/server.rb +0 -395
  85. data/lib/rack/session/abstract/id.rb +0 -510
  86. data/lib/rack/session/cookie.rb +0 -204
  87. data/lib/rack/session/memcache.rb +0 -99
  88. data/lib/rack/session/pool.rb +0 -83
  89. data/rack.gemspec +0 -34
  90. data/test/builder/an_underscore_app.rb +0 -5
  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 -9
  108. data/test/cgi/test.gz +0 -0
  109. data/test/cgi/test.ru +0 -5
  110. data/test/gemloader.rb +0 -10
  111. data/test/helper.rb +0 -34
  112. data/test/multipart/bad_robots +0 -259
  113. data/test/multipart/binary +0 -0
  114. data/test/multipart/content_type_and_no_filename +0 -6
  115. data/test/multipart/empty +0 -10
  116. data/test/multipart/fail_16384_nofile +0 -814
  117. data/test/multipart/file1.txt +0 -1
  118. data/test/multipart/filename_and_modification_param +0 -7
  119. data/test/multipart/filename_and_no_name +0 -6
  120. data/test/multipart/filename_with_encoded_words +0 -7
  121. data/test/multipart/filename_with_escaped_quotes +0 -6
  122. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  123. data/test/multipart/filename_with_null_byte +0 -7
  124. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  125. data/test/multipart/filename_with_single_quote +0 -7
  126. data/test/multipart/filename_with_unescaped_percentages +0 -6
  127. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  128. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  129. data/test/multipart/filename_with_unescaped_quotes +0 -6
  130. data/test/multipart/ie +0 -6
  131. data/test/multipart/invalid_character +0 -6
  132. data/test/multipart/mixed_files +0 -21
  133. data/test/multipart/nested +0 -10
  134. data/test/multipart/none +0 -9
  135. data/test/multipart/quoted +0 -15
  136. data/test/multipart/rack-logo.png +0 -0
  137. data/test/multipart/semicolon +0 -6
  138. data/test/multipart/text +0 -15
  139. data/test/multipart/three_files_three_fields +0 -31
  140. data/test/multipart/unity3d_wwwform +0 -11
  141. data/test/multipart/webkit +0 -32
  142. data/test/rackup/config.ru +0 -31
  143. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  144. data/test/spec_auth_basic.rb +0 -89
  145. data/test/spec_auth_digest.rb +0 -260
  146. data/test/spec_body_proxy.rb +0 -85
  147. data/test/spec_builder.rb +0 -233
  148. data/test/spec_cascade.rb +0 -63
  149. data/test/spec_cgi.rb +0 -84
  150. data/test/spec_chunked.rb +0 -103
  151. data/test/spec_common_logger.rb +0 -107
  152. data/test/spec_conditional_get.rb +0 -103
  153. data/test/spec_config.rb +0 -23
  154. data/test/spec_content_length.rb +0 -86
  155. data/test/spec_content_type.rb +0 -46
  156. data/test/spec_deflater.rb +0 -375
  157. data/test/spec_directory.rb +0 -148
  158. data/test/spec_etag.rb +0 -108
  159. data/test/spec_events.rb +0 -133
  160. data/test/spec_fastcgi.rb +0 -85
  161. data/test/spec_file.rb +0 -264
  162. data/test/spec_handler.rb +0 -57
  163. data/test/spec_head.rb +0 -46
  164. data/test/spec_lint.rb +0 -520
  165. data/test/spec_lobster.rb +0 -59
  166. data/test/spec_lock.rb +0 -204
  167. data/test/spec_logger.rb +0 -24
  168. data/test/spec_media_type.rb +0 -42
  169. data/test/spec_method_override.rb +0 -110
  170. data/test/spec_mime.rb +0 -51
  171. data/test/spec_mock.rb +0 -359
  172. data/test/spec_multipart.rb +0 -721
  173. data/test/spec_null_logger.rb +0 -21
  174. data/test/spec_recursive.rb +0 -75
  175. data/test/spec_request.rb +0 -1423
  176. data/test/spec_response.rb +0 -528
  177. data/test/spec_rewindable_input.rb +0 -128
  178. data/test/spec_runtime.rb +0 -50
  179. data/test/spec_sendfile.rb +0 -125
  180. data/test/spec_server.rb +0 -193
  181. data/test/spec_session_abstract_id.rb +0 -31
  182. data/test/spec_session_abstract_session_hash.rb +0 -45
  183. data/test/spec_session_cookie.rb +0 -442
  184. data/test/spec_session_memcache.rb +0 -357
  185. data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
  186. data/test/spec_session_pool.rb +0 -247
  187. data/test/spec_show_exceptions.rb +0 -93
  188. data/test/spec_show_status.rb +0 -104
  189. data/test/spec_static.rb +0 -184
  190. data/test/spec_tempfile_reaper.rb +0 -64
  191. data/test/spec_thin.rb +0 -96
  192. data/test/spec_urlmap.rb +0 -237
  193. data/test/spec_utils.rb +0 -742
  194. data/test/spec_version.rb +0 -11
  195. data/test/spec_webrick.rb +0 -206
  196. data/test/static/another/index.html +0 -1
  197. data/test/static/foo.html +0 -1
  198. data/test/static/index.html +0 -1
  199. data/test/testrequest.rb +0 -78
  200. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  201. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,442 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'rack/session/cookie'
3
- require 'rack/lint'
4
- require 'rack/mock'
5
-
6
- describe Rack::Session::Cookie do
7
- incrementor = lambda do |env|
8
- env["rack.session"]["counter"] ||= 0
9
- env["rack.session"]["counter"] += 1
10
- hash = env["rack.session"].dup
11
- hash.delete("session_id")
12
- Rack::Response.new(hash.inspect).to_a
13
- end
14
-
15
- session_id = lambda do |env|
16
- Rack::Response.new(env["rack.session"].to_hash.inspect).to_a
17
- end
18
-
19
- session_option = lambda do |opt|
20
- lambda do |env|
21
- Rack::Response.new(env["rack.session.options"][opt].inspect).to_a
22
- end
23
- end
24
-
25
- nothing = lambda do |env|
26
- Rack::Response.new("Nothing").to_a
27
- end
28
-
29
- renewer = lambda do |env|
30
- env["rack.session.options"][:renew] = true
31
- Rack::Response.new("Nothing").to_a
32
- end
33
-
34
- only_session_id = lambda do |env|
35
- Rack::Response.new(env["rack.session"]["session_id"].to_s).to_a
36
- end
37
-
38
- bigcookie = lambda do |env|
39
- env["rack.session"]["cookie"] = "big" * 3000
40
- Rack::Response.new(env["rack.session"].inspect).to_a
41
- end
42
-
43
- destroy_session = lambda do |env|
44
- env["rack.session"].destroy
45
- Rack::Response.new("Nothing").to_a
46
- end
47
-
48
- def response_for(options={})
49
- request_options = options.fetch(:request, {})
50
- cookie = if options[:cookie].is_a?(Rack::Response)
51
- options[:cookie]["Set-Cookie"]
52
- else
53
- options[:cookie]
54
- end
55
- request_options["HTTP_COOKIE"] = cookie || ""
56
-
57
- app_with_cookie = Rack::Session::Cookie.new(*options[:app])
58
- app_with_cookie = Rack::Lint.new(app_with_cookie)
59
- Rack::MockRequest.new(app_with_cookie).get("/", request_options)
60
- end
61
-
62
- before do
63
- @warnings = warnings = []
64
- Rack::Session::Cookie.class_eval do
65
- define_method(:warn) { |m| warnings << m }
66
- end
67
- end
68
-
69
- after do
70
- Rack::Session::Cookie.class_eval { remove_method :warn }
71
- end
72
-
73
- describe 'Base64' do
74
- it 'uses base64 to encode' do
75
- coder = Rack::Session::Cookie::Base64.new
76
- str = 'fuuuuu'
77
- coder.encode(str).must_equal [str].pack('m')
78
- end
79
-
80
- it 'uses base64 to decode' do
81
- coder = Rack::Session::Cookie::Base64.new
82
- str = ['fuuuuu'].pack('m')
83
- coder.decode(str).must_equal str.unpack('m').first
84
- end
85
-
86
- describe 'Marshal' do
87
- it 'marshals and base64 encodes' do
88
- coder = Rack::Session::Cookie::Base64::Marshal.new
89
- str = 'fuuuuu'
90
- coder.encode(str).must_equal [::Marshal.dump(str)].pack('m')
91
- end
92
-
93
- it 'marshals and base64 decodes' do
94
- coder = Rack::Session::Cookie::Base64::Marshal.new
95
- str = [::Marshal.dump('fuuuuu')].pack('m')
96
- coder.decode(str).must_equal ::Marshal.load(str.unpack('m').first)
97
- end
98
-
99
- it 'rescues failures on decode' do
100
- coder = Rack::Session::Cookie::Base64::Marshal.new
101
- coder.decode('lulz').must_be_nil
102
- end
103
- end
104
-
105
- describe 'JSON' do
106
- it 'JSON and base64 encodes' do
107
- coder = Rack::Session::Cookie::Base64::JSON.new
108
- obj = %w[fuuuuu]
109
- coder.encode(obj).must_equal [::JSON.dump(obj)].pack('m')
110
- end
111
-
112
- it 'JSON and base64 decodes' do
113
- coder = Rack::Session::Cookie::Base64::JSON.new
114
- str = [::JSON.dump(%w[fuuuuu])].pack('m')
115
- coder.decode(str).must_equal ::JSON.parse(str.unpack('m').first)
116
- end
117
-
118
- it 'rescues failures on decode' do
119
- coder = Rack::Session::Cookie::Base64::JSON.new
120
- coder.decode('lulz').must_be_nil
121
- end
122
- end
123
-
124
- describe 'ZipJSON' do
125
- it 'jsons, deflates, and base64 encodes' do
126
- coder = Rack::Session::Cookie::Base64::ZipJSON.new
127
- obj = %w[fuuuuu]
128
- json = JSON.dump(obj)
129
- coder.encode(obj).must_equal [Zlib::Deflate.deflate(json)].pack('m')
130
- end
131
-
132
- it 'base64 decodes, inflates, and decodes json' do
133
- coder = Rack::Session::Cookie::Base64::ZipJSON.new
134
- obj = %w[fuuuuu]
135
- json = JSON.dump(obj)
136
- b64 = [Zlib::Deflate.deflate(json)].pack('m')
137
- coder.decode(b64).must_equal obj
138
- end
139
-
140
- it 'rescues failures on decode' do
141
- coder = Rack::Session::Cookie::Base64::ZipJSON.new
142
- coder.decode('lulz').must_be_nil
143
- end
144
- end
145
- end
146
-
147
- it "warns if no secret is given" do
148
- Rack::Session::Cookie.new(incrementor)
149
- @warnings.first.must_match(/no secret/i)
150
- @warnings.clear
151
- Rack::Session::Cookie.new(incrementor, :secret => 'abc')
152
- @warnings.must_be :empty?
153
- end
154
-
155
- it "doesn't warn if coder is configured to handle encoding" do
156
- Rack::Session::Cookie.new(
157
- incrementor,
158
- :coder => Object.new,
159
- :let_coder_handle_secure_encoding => true)
160
- @warnings.must_be :empty?
161
- end
162
-
163
- it "still warns if coder is not set" do
164
- Rack::Session::Cookie.new(
165
- incrementor,
166
- :let_coder_handle_secure_encoding => true)
167
- @warnings.first.must_match(/no secret/i)
168
- end
169
-
170
- it 'uses a coder' do
171
- identity = Class.new {
172
- attr_reader :calls
173
-
174
- def initialize
175
- @calls = []
176
- end
177
-
178
- def encode(str); @calls << :encode; str; end
179
- def decode(str); @calls << :decode; str; end
180
- }.new
181
- response = response_for(:app => [incrementor, { :coder => identity }])
182
-
183
- response["Set-Cookie"].must_include "rack.session="
184
- response.body.must_equal '{"counter"=>1}'
185
- identity.calls.must_equal [:decode, :encode]
186
- end
187
-
188
- it "creates a new cookie" do
189
- response = response_for(:app => incrementor)
190
- response["Set-Cookie"].must_include "rack.session="
191
- response.body.must_equal '{"counter"=>1}'
192
- end
193
-
194
- it "loads from a cookie" do
195
- response = response_for(:app => incrementor)
196
-
197
- response = response_for(:app => incrementor, :cookie => response)
198
- response.body.must_equal '{"counter"=>2}'
199
-
200
- response = response_for(:app => incrementor, :cookie => response)
201
- response.body.must_equal '{"counter"=>3}'
202
- end
203
-
204
- it "renew session id" do
205
- response = response_for(:app => incrementor)
206
- cookie = response['Set-Cookie']
207
- response = response_for(:app => only_session_id, :cookie => cookie)
208
- cookie = response['Set-Cookie'] if response['Set-Cookie']
209
-
210
- response.body.wont_equal ""
211
- old_session_id = response.body
212
-
213
- response = response_for(:app => renewer, :cookie => cookie)
214
- cookie = response['Set-Cookie'] if response['Set-Cookie']
215
- response = response_for(:app => only_session_id, :cookie => cookie)
216
-
217
- response.body.wont_equal ""
218
- response.body.wont_equal old_session_id
219
- end
220
-
221
- it "destroys session" do
222
- response = response_for(:app => incrementor)
223
- response = response_for(:app => only_session_id, :cookie => response)
224
-
225
- response.body.wont_equal ""
226
- old_session_id = response.body
227
-
228
- response = response_for(:app => destroy_session, :cookie => response)
229
- response = response_for(:app => only_session_id, :cookie => response)
230
-
231
- response.body.wont_equal ""
232
- response.body.wont_equal old_session_id
233
- end
234
-
235
- it "survives broken cookies" do
236
- response = response_for(
237
- :app => incrementor,
238
- :cookie => "rack.session=blarghfasel"
239
- )
240
- response.body.must_equal '{"counter"=>1}'
241
-
242
- response = response_for(
243
- :app => [incrementor, { :secret => "test" }],
244
- :cookie => "rack.session="
245
- )
246
- response.body.must_equal '{"counter"=>1}'
247
- end
248
-
249
- it "barks on too big cookies" do
250
- lambda{
251
- response_for(:app => bigcookie, :request => { :fatal => true })
252
- }.must_raise Rack::MockRequest::FatalWarning
253
- end
254
-
255
- it "loads from a cookie with integrity hash" do
256
- app = [incrementor, { :secret => "test" }]
257
-
258
- response = response_for(:app => app)
259
- response = response_for(:app => app, :cookie => response)
260
- response.body.must_equal '{"counter"=>2}'
261
-
262
- response = response_for(:app => app, :cookie => response)
263
- response.body.must_equal '{"counter"=>3}'
264
-
265
- app = [incrementor, { :secret => "other" }]
266
-
267
- response = response_for(:app => app, :cookie => response)
268
- response.body.must_equal '{"counter"=>1}'
269
- end
270
-
271
- it "loads from a cookie with accept-only integrity hash for graceful key rotation" do
272
- response = response_for(:app => [incrementor, { :secret => "test" }])
273
-
274
- app = [incrementor, { :secret => "test2", :old_secret => "test" }]
275
- response = response_for(:app => app, :cookie => response)
276
- response.body.must_equal '{"counter"=>2}'
277
-
278
- app = [incrementor, { :secret => "test3", :old_secret => "test2" }]
279
- response = response_for(:app => app, :cookie => response)
280
- response.body.must_equal '{"counter"=>3}'
281
- end
282
-
283
- it "ignores tampered with session cookies" do
284
- app = [incrementor, { :secret => "test" }]
285
- response = response_for(:app => app)
286
- response.body.must_equal '{"counter"=>1}'
287
-
288
- response = response_for(:app => app, :cookie => response)
289
- response.body.must_equal '{"counter"=>2}'
290
-
291
- _, digest = response["Set-Cookie"].split("--")
292
- tampered_with_cookie = "hackerman-was-here" + "--" + digest
293
-
294
- response = response_for(:app => app, :cookie => tampered_with_cookie)
295
- response.body.must_equal '{"counter"=>1}'
296
- end
297
-
298
- it "supports either of secret or old_secret" do
299
- app = [incrementor, { :secret => "test" }]
300
- response = response_for(:app => app)
301
- response.body.must_equal '{"counter"=>1}'
302
-
303
- response = response_for(:app => app, :cookie => response)
304
- response.body.must_equal '{"counter"=>2}'
305
-
306
- app = [incrementor, { :old_secret => "test" }]
307
- response = response_for(:app => app)
308
- response.body.must_equal '{"counter"=>1}'
309
-
310
- response = response_for(:app => app, :cookie => response)
311
- response.body.must_equal '{"counter"=>2}'
312
- end
313
-
314
- it "supports custom digest class" do
315
- app = [incrementor, { :secret => "test", hmac: OpenSSL::Digest::SHA256 }]
316
-
317
- response = response_for(:app => app)
318
- response = response_for(:app => app, :cookie => response)
319
- response.body.must_equal '{"counter"=>2}'
320
-
321
- response = response_for(:app => app, :cookie => response)
322
- response.body.must_equal '{"counter"=>3}'
323
-
324
- app = [incrementor, { :secret => "other" }]
325
-
326
- response = response_for(:app => app, :cookie => response)
327
- response.body.must_equal '{"counter"=>1}'
328
- end
329
-
330
- it "can handle Rack::Lint middleware" do
331
- response = response_for(:app => incrementor)
332
-
333
- lint = Rack::Lint.new(session_id)
334
- response = response_for(:app => lint, :cookie => response)
335
- response.body.wont_be :nil?
336
- end
337
-
338
- it "can handle middleware that inspects the env" do
339
- class TestEnvInspector
340
- def initialize(app)
341
- @app = app
342
- end
343
- def call(env)
344
- env.inspect
345
- @app.call(env)
346
- end
347
- end
348
-
349
- response = response_for(:app => incrementor)
350
-
351
- inspector = TestEnvInspector.new(session_id)
352
- response = response_for(:app => inspector, :cookie => response)
353
- response.body.wont_be :nil?
354
- end
355
-
356
- it "returns the session id in the session hash" do
357
- response = response_for(:app => incrementor)
358
- response.body.must_equal '{"counter"=>1}'
359
-
360
- response = response_for(:app => session_id, :cookie => response)
361
- response.body.must_match(/"session_id"=>/)
362
- response.body.must_match(/"counter"=>1/)
363
- end
364
-
365
- it "does not return a cookie if set to secure but not using ssl" do
366
- app = [incrementor, { :secure => true }]
367
-
368
- response = response_for(:app => app)
369
- response["Set-Cookie"].must_be_nil
370
-
371
- response = response_for(:app => app, :request => { "HTTPS" => "on" })
372
- response["Set-Cookie"].wont_be :nil?
373
- response["Set-Cookie"].must_match(/secure/)
374
- end
375
-
376
- it "does not return a cookie if cookie was not read/written" do
377
- response = response_for(:app => nothing)
378
- response["Set-Cookie"].must_be_nil
379
- end
380
-
381
- it "does not return a cookie if cookie was not written (only read)" do
382
- response = response_for(:app => session_id)
383
- response["Set-Cookie"].must_be_nil
384
- end
385
-
386
- it "returns even if not read/written if :expire_after is set" do
387
- app = [nothing, { :expire_after => 3600 }]
388
- request = { "rack.session" => { "not" => "empty" }}
389
- response = response_for(:app => app, :request => request)
390
- response["Set-Cookie"].wont_be :nil?
391
- end
392
-
393
- it "returns no cookie if no data was written and no session was created previously, even if :expire_after is set" do
394
- app = [nothing, { :expire_after => 3600 }]
395
- response = response_for(:app => app)
396
- response["Set-Cookie"].must_be_nil
397
- end
398
-
399
- it "exposes :secret in env['rack.session.option']" do
400
- response = response_for(:app => [session_option[:secret], { :secret => "foo" }])
401
- response.body.must_equal '"foo"'
402
- end
403
-
404
- it "exposes :coder in env['rack.session.option']" do
405
- response = response_for(:app => session_option[:coder])
406
- response.body.must_match(/Base64::Marshal/)
407
- end
408
-
409
- it "allows passing in a hash with session data from middleware in front" do
410
- request = { 'rack.session' => { :foo => 'bar' }}
411
- response = response_for(:app => session_id, :request => request)
412
- response.body.must_match(/foo/)
413
- end
414
-
415
- it "allows modifying session data with session data from middleware in front" do
416
- request = { 'rack.session' => { :foo => 'bar' }}
417
- response = response_for(:app => incrementor, :request => request)
418
- response.body.must_match(/counter/)
419
- response.body.must_match(/foo/)
420
- end
421
-
422
- it "allows more than one '--' in the cookie when calculating digests" do
423
- @counter = 0
424
- app = lambda do |env|
425
- env["rack.session"]["message"] ||= ""
426
- env["rack.session"]["message"] << "#{(@counter += 1).to_s}--"
427
- hash = env["rack.session"].dup
428
- hash.delete("session_id")
429
- Rack::Response.new(hash["message"]).to_a
430
- end
431
- # another example of an unsafe coder is Base64.urlsafe_encode64
432
- unsafe_coder = Class.new {
433
- def encode(hash); hash.inspect end
434
- def decode(str); eval(str) if str; end
435
- }.new
436
- _app = [ app, { :secret => "test", :coder => unsafe_coder } ]
437
- response = response_for(:app => _app)
438
- response.body.must_equal "1--"
439
- response = response_for(:app => _app, :cookie => response)
440
- response.body.must_equal "1--2--"
441
- end
442
- end