rtomayko-rack-cache 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,18 +32,18 @@ module Rack::Cache
32
32
 
33
33
  # find a cached entry that matches the request.
34
34
  env = request.env
35
- match = entries.detect{ |req,res| requests_match?(res['Vary'], env, req)}
36
- if match
37
- # TODO what if body doesn't exist in entity store?
38
- # reconstruct response object
39
- req, res = match
40
- status = res['X-Status']
41
- body = entity_store.open(res['X-Content-Digest'])
42
- response = Rack::Cache::Response.new(status.to_i, res, body)
43
- response.activate!
35
+ match = entries.detect{|req,res| requests_match?(res['Vary'], env, req)}
36
+ return nil if match.nil?
44
37
 
45
- # Return the cached response
38
+ req, res = match
39
+ if body = entity_store.open(res['X-Content-Digest'])
40
+ response = Rack::Cache::Response.new(res['X-Status'].to_i, res, body)
41
+ response.activate!
46
42
  response
43
+ else
44
+ # TODO the metastore referenced an entity that doesn't exist in
45
+ # the entitystore. we definitely want to return nil but we should
46
+ # also purge the entry from the meta-store when this is detected.
47
47
  end
48
48
  end
49
49
 
@@ -75,7 +75,7 @@ module Rack::Cache
75
75
  (vary == res['Vary']) &&
76
76
  requests_match?(vary, env, stored_env)
77
77
  end
78
- entries.unshift [stored_env, response.headers.dup]
78
+ entries.unshift [stored_env, {}.update(response.headers)]
79
79
  write key, entries
80
80
  end
81
81
 
@@ -61,6 +61,15 @@ module Rack::Cache
61
61
  # Default: 0
62
62
  option_accessor :default_ttl
63
63
 
64
+ # Set of request headers that trigger "private" cache-control behavior
65
+ # on responses that don't explicitly state whether the response is
66
+ # public or private via a Cache-Control directive. Applications that use
67
+ # cookies for authorization may need to add the 'Cookie' header to this
68
+ # list.
69
+ #
70
+ # Default: ['Authorization', 'Cookie']
71
+ option_accessor :private_headers
72
+
64
73
  # The underlying options Hash. During initialization (or outside of a
65
74
  # request), this is a default values Hash. During a request, this is the
66
75
  # Rack environment Hash. The default values Hash is merged in underneath
@@ -111,7 +120,8 @@ module Rack::Cache
111
120
  'rack-cache.storage' => Rack::Cache::Storage.instance,
112
121
  'rack-cache.metastore' => 'heap:/',
113
122
  'rack-cache.entitystore' => 'heap:/',
114
- 'rack-cache.default_ttl' => 0
123
+ 'rack-cache.default_ttl' => 0,
124
+ 'rack-cache.private_headers' => ['Authorization', 'Cookie']
115
125
  }
116
126
  self.options = options
117
127
  end
@@ -34,7 +34,7 @@ module Rack::Cache
34
34
  # and body.
35
35
  def initialize(status, headers, body)
36
36
  @status = status
37
- @headers = headers
37
+ @headers = Rack::Utils::HeaderHash.new(headers)
38
38
  @body = body
39
39
  @now = Time.now
40
40
  @headers['Date'] ||= now.httpdate
@@ -62,7 +62,7 @@ module Rack::Cache
62
62
 
63
63
  # Return the status, headers, and body in a three-tuple.
64
64
  def to_a
65
- [status, headers, body]
65
+ [status, headers.to_hash, body]
66
66
  end
67
67
 
68
68
  # Freezes
data/rack-cache.gemspec CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'rack-cache'
6
- s.version = '0.2.0'
7
- s.date = '2008-10-24'
6
+ s.version = '0.3.0'
7
+ s.date = '2008-12-28'
8
8
 
9
9
  s.description = "HTTP Caching for Rack"
10
10
  s.summary = "HTTP Caching for Rack"
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  doc/layout.html.erb
27
27
  doc/license.markdown
28
28
  doc/rack-cache.css
29
+ doc/server.ru
29
30
  doc/storage.markdown
30
31
  lib/rack/cache.rb
31
32
  lib/rack/cache/config.rb
data/test/cache_test.rb CHANGED
@@ -18,8 +18,8 @@ describe 'Rack::Cache::new' do
18
18
  end
19
19
  it 'sets options provided in the options Hash' do
20
20
  object = Rack::Cache.new(@app, :foo => 'bar', 'foo.bar' => 'bling')
21
- object.options['foo.bar'].should.be == 'bling'
22
- object.options['rack-cache.foo'].should.be == 'bar'
21
+ object.options['foo.bar'].should.equal 'bling'
22
+ object.options['rack-cache.foo'].should.equal 'bar'
23
23
  end
24
24
  it 'takes a block; executes it during initialization' do
25
25
  state, block_scope = 'not invoked', nil
@@ -29,7 +29,7 @@ describe 'Rack::Cache::new' do
29
29
  state = 'invoked'
30
30
  should.respond_to :on
31
31
  end
32
- state.should.be == 'invoked'
32
+ state.should.equal 'invoked'
33
33
  object.should.be block_scope
34
34
  end
35
35
  end
data/test/context_test.rb CHANGED
@@ -15,24 +15,58 @@ describe 'Rack::Cache::Context' do
15
15
  response.headers.should.not.include 'Age'
16
16
  end
17
17
 
18
- it 'passes on requests with Authorization' do
19
- respond_with 200
18
+ it 'does not cache with Authorization request header and non public response' do
19
+ respond_with 200, 'Etag' => '"FOO"'
20
20
  get '/', 'HTTP_AUTHORIZATION' => 'basic foobarbaz'
21
21
 
22
22
  app.should.be.called
23
23
  response.should.be.ok
24
- cache.should.a.performed :pass
24
+ response.headers['Cache-Control'].should.equal 'private'
25
+ cache.should.a.performed :miss
26
+ cache.should.a.performed :fetch
27
+ cache.should.a.not.performed :store
28
+ cache.should.a.performed :deliver
29
+ response.headers.should.not.include 'Age'
30
+ end
31
+
32
+ it 'does cache with Authorization request header and public response' do
33
+ respond_with 200, 'Cache-Control' => 'public', 'ETag' => '"FOO"'
34
+ get '/', 'HTTP_AUTHORIZATION' => 'basic foobarbaz'
35
+
36
+ app.should.be.called
37
+ response.should.be.ok
38
+ cache.should.a.performed :miss
39
+ cache.should.a.performed :fetch
40
+ cache.should.a.performed :store
41
+ response.headers.should.include 'Age'
42
+ response.headers['Cache-Control'].should.equal 'public'
43
+ end
44
+
45
+ it 'does not cache with Cookie header and non public response' do
46
+ respond_with 200, 'Etag' => '"FOO"'
47
+ get '/', 'HTTP_COOKIE' => 'foo=bar'
48
+
49
+ app.should.be.called
50
+ response.should.be.ok
51
+ response.headers['Cache-Control'].should.equal 'private'
52
+ cache.should.a.performed :miss
53
+ cache.should.a.performed :fetch
54
+ cache.should.a.not.performed :store
55
+ cache.should.a.performed :deliver
25
56
  response.headers.should.not.include 'Age'
26
57
  end
27
58
 
28
- it 'passes on requests with a Cookie' do
59
+ it 'does not cache requests with a Cookie header' do
29
60
  respond_with 200
30
61
  get '/', 'HTTP_COOKIE' => 'foo=bar'
31
62
 
32
63
  response.should.be.ok
33
64
  app.should.be.called
34
- cache.should.a.performed :pass
65
+ cache.should.a.performed :miss
66
+ cache.should.a.performed :fetch
67
+ cache.should.a.performed :deliver
35
68
  response.headers.should.not.include 'Age'
69
+ response.headers['Cache-Control'].should.equal 'private'
36
70
  end
37
71
 
38
72
  it 'responds with 304 when If-Modified-Since matches Last-Modified' do
@@ -47,7 +81,7 @@ describe 'Rack::Cache::Context' do
47
81
  get '/',
48
82
  'HTTP_IF_MODIFIED_SINCE' => timestamp
49
83
  app.should.be.called
50
- response.status.should.be == 304
84
+ response.status.should.equal 304
51
85
  response.headers.should.not.include 'Content-Length'
52
86
  response.headers.should.not.include 'Content-Type'
53
87
  response.body.should.empty
@@ -66,7 +100,7 @@ describe 'Rack::Cache::Context' do
66
100
  get '/',
67
101
  'HTTP_IF_NONE_MATCH' => '12345'
68
102
  app.should.be.called
69
- response.status.should.be == 304
103
+ response.status.should.equal 304
70
104
  response.headers.should.not.include 'Content-Length'
71
105
  response.headers.should.not.include 'Content-Type'
72
106
  response.headers.should.include 'Etag'
@@ -101,7 +135,7 @@ describe 'Rack::Cache::Context' do
101
135
  get '/'
102
136
 
103
137
  cache.should.a.not.performed :store
104
- response.status.should.be == response_code
138
+ response.status.should.equal response_code
105
139
  response.headers.should.not.include 'Age'
106
140
  end
107
141
  end
@@ -142,13 +176,13 @@ describe 'Rack::Cache::Context' do
142
176
  get '/'
143
177
 
144
178
  response.should.be.ok
145
- response.body.should.be == 'Hello World'
179
+ response.body.should.equal 'Hello World'
146
180
  response.headers.should.include 'Date'
147
181
  response['Age'].should.not.be.nil
148
182
  response['X-Content-Digest'].should.not.be.nil
149
183
  cache.should.a.performed :miss
150
184
  cache.should.a.performed :store
151
- cache.metastore.to_hash.keys.length.should.be == 1
185
+ cache.metastore.to_hash.keys.length.should.equal 1
152
186
  end
153
187
 
154
188
  it 'caches responses with a max-age directive' do
@@ -156,13 +190,27 @@ describe 'Rack::Cache::Context' do
156
190
  get '/'
157
191
 
158
192
  response.should.be.ok
159
- response.body.should.be == 'Hello World'
193
+ response.body.should.equal 'Hello World'
194
+ response.headers.should.include 'Date'
195
+ response['Age'].should.not.be.nil
196
+ response['X-Content-Digest'].should.not.be.nil
197
+ cache.should.a.performed :miss
198
+ cache.should.a.performed :store
199
+ cache.metastore.to_hash.keys.length.should.equal 1
200
+ end
201
+
202
+ it 'caches responses with a s-maxage directive' do
203
+ respond_with 200, 'Cache-Control' => 's-maxage=5'
204
+ get '/'
205
+
206
+ response.should.be.ok
207
+ response.body.should.equal 'Hello World'
160
208
  response.headers.should.include 'Date'
161
209
  response['Age'].should.not.be.nil
162
210
  response['X-Content-Digest'].should.not.be.nil
163
211
  cache.should.a.performed :miss
164
212
  cache.should.a.performed :store
165
- cache.metastore.to_hash.keys.length.should.be == 1
213
+ cache.metastore.to_hash.keys.length.should.equal 1
166
214
  end
167
215
 
168
216
  it 'caches responses with a Last-Modified validator but no freshness information' do
@@ -170,7 +218,7 @@ describe 'Rack::Cache::Context' do
170
218
  get '/'
171
219
 
172
220
  response.should.be.ok
173
- response.body.should.be == 'Hello World'
221
+ response.body.should.equal 'Hello World'
174
222
  cache.should.a.performed :miss
175
223
  cache.should.a.performed :store
176
224
  end
@@ -180,7 +228,7 @@ describe 'Rack::Cache::Context' do
180
228
  get '/'
181
229
 
182
230
  response.should.be.ok
183
- response.body.should.be == 'Hello World'
231
+ response.body.should.equal 'Hello World'
184
232
  cache.should.a.performed :miss
185
233
  cache.should.a.performed :store
186
234
  end
@@ -196,17 +244,17 @@ describe 'Rack::Cache::Context' do
196
244
  response.headers.should.include 'Date'
197
245
  cache.should.a.performed :miss
198
246
  cache.should.a.performed :store
199
- response.body.should.be == 'Hello World'
247
+ response.body.should.equal 'Hello World'
200
248
 
201
249
  get '/'
202
250
  response.should.be.ok
203
251
  app.should.not.be.called
204
- response['Date'].should.be == responses.first['Date']
205
- response['Age'].to_i.should.be > 0
252
+ response['Date'].should.equal responses.first['Date']
253
+ response['Age'].to_i.should.satisfy { |age| age > 0 }
206
254
  response['X-Content-Digest'].should.not.be.nil
207
255
  cache.should.a.performed :hit
208
256
  cache.should.a.not.performed :fetch
209
- response.body.should.be == 'Hello World'
257
+ response.body.should.equal 'Hello World'
210
258
  end
211
259
 
212
260
  it 'hits cached response with max-age directive' do
@@ -220,17 +268,73 @@ describe 'Rack::Cache::Context' do
220
268
  response.headers.should.include 'Date'
221
269
  cache.should.a.performed :miss
222
270
  cache.should.a.performed :store
223
- response.body.should.be == 'Hello World'
271
+ response.body.should.equal 'Hello World'
224
272
 
225
273
  get '/'
226
274
  response.should.be.ok
227
275
  app.should.not.be.called
228
- response['Date'].should.be == responses.first['Date']
229
- response['Age'].to_i.should.be > 0
276
+ response['Date'].should.equal responses.first['Date']
277
+ response['Age'].to_i.should.satisfy { |age| age > 0 }
230
278
  response['X-Content-Digest'].should.not.be.nil
231
279
  cache.should.a.performed :hit
232
280
  cache.should.a.not.performed :fetch
233
- response.body.should.be == 'Hello World'
281
+ response.body.should.equal 'Hello World'
282
+ end
283
+
284
+ it 'hits cached response with s-maxage directive' do
285
+ respond_with 200,
286
+ 'Date' => (Time.now - 5).httpdate,
287
+ 'Cache-Control' => 's-maxage=10, max-age=0'
288
+
289
+ get '/'
290
+ app.should.be.called
291
+ response.should.be.ok
292
+ response.headers.should.include 'Date'
293
+ cache.should.a.performed :miss
294
+ cache.should.a.performed :store
295
+ response.body.should.equal 'Hello World'
296
+
297
+ get '/'
298
+ response.should.be.ok
299
+ app.should.not.be.called
300
+ response['Date'].should.equal responses.first['Date']
301
+ response['Age'].to_i.should.satisfy { |age| age > 0 }
302
+ response['X-Content-Digest'].should.not.be.nil
303
+ cache.should.a.performed :hit
304
+ cache.should.a.not.performed :fetch
305
+ response.body.should.equal 'Hello World'
306
+ end
307
+
308
+ it 'assigns default_ttl when response has no freshness information' do
309
+ respond_with 200
310
+
311
+ get '/', 'rack-cache.default_ttl' => 10
312
+ app.should.be.called
313
+ response.should.be.ok
314
+ cache.should.a.performed :miss
315
+ cache.should.a.performed :store
316
+ response.body.should.equal 'Hello World'
317
+ response['Cache-Control'].should.include 's-maxage=10'
318
+
319
+ get '/', 'rack-cache.default_ttl' => 10
320
+ response.should.be.ok
321
+ app.should.not.be.called
322
+ cache.should.a.performed :hit
323
+ cache.should.a.not.performed :fetch
324
+ response.body.should.equal 'Hello World'
325
+ end
326
+
327
+ it 'does not assign default_ttl when response has must-revalidate directive' do
328
+ respond_with 200,
329
+ 'Cache-Control' => 'must-revalidate'
330
+
331
+ get '/', 'rack-cache.default_ttl' => 10
332
+ app.should.be.called
333
+ response.should.be.ok
334
+ cache.should.a.performed :miss
335
+ cache.should.a.not.performed :store
336
+ response['Cache-Control'].should.not.include 's-maxage'
337
+ response.body.should.equal 'Hello World'
234
338
  end
235
339
 
236
340
  it 'fetches full response when cache stale and no validators present' do
@@ -245,23 +349,23 @@ describe 'Rack::Cache::Context' do
245
349
  response.headers.should.include 'Age'
246
350
  cache.should.a.performed :miss
247
351
  cache.should.a.performed :store
248
- response.body.should.be == 'Hello World'
352
+ response.body.should.equal 'Hello World'
249
353
 
250
354
  # go in and play around with the cached metadata directly ...
251
- cache.metastore.to_hash.values.length.should.be == 1
355
+ cache.metastore.to_hash.values.length.should.equal 1
252
356
  cache.metastore.to_hash.values.first.first[1]['Expires'] = Time.now.httpdate
253
357
 
254
358
  # build subsequent request; should be found but miss due to freshness
255
359
  get '/'
256
360
  app.should.be.called
257
361
  response.should.be.ok
258
- response['Age'].to_i.should.be == 0
362
+ response['Age'].to_i.should.equal 0
259
363
  response.headers.should.include 'X-Content-Digest'
260
364
  cache.should.a.not.performed :hit
261
365
  cache.should.a.not.performed :miss
262
366
  cache.should.a.performed :fetch
263
367
  cache.should.a.performed :store
264
- response.body.should.be == 'Hello World'
368
+ response.body.should.equal 'Hello World'
265
369
  end
266
370
 
267
371
  it 'validates cached responses with Last-Modified and no freshness information' do
@@ -280,7 +384,7 @@ describe 'Rack::Cache::Context' do
280
384
  response.should.be.ok
281
385
  response.headers.should.include 'Last-Modified'
282
386
  response.headers.should.include 'X-Content-Digest'
283
- response.body.should.be == 'Hello World'
387
+ response.body.should.equal 'Hello World'
284
388
  cache.should.a.performed :miss
285
389
  cache.should.a.performed :store
286
390
 
@@ -290,9 +394,9 @@ describe 'Rack::Cache::Context' do
290
394
  response.should.be.ok
291
395
  response.headers.should.include 'Last-Modified'
292
396
  response.headers.should.include 'X-Content-Digest'
293
- response['Age'].to_i.should.be == 0
294
- response['X-Origin-Status'].should.be == '304'
295
- response.body.should.be == 'Hello World'
397
+ response['Age'].to_i.should.equal 0
398
+ response['X-Origin-Status'].should.equal '304'
399
+ response.body.should.equal 'Hello World'
296
400
  cache.should.a.not.performed :miss
297
401
  cache.should.a.performed :fetch
298
402
  cache.should.a.performed :store
@@ -314,7 +418,7 @@ describe 'Rack::Cache::Context' do
314
418
  response.should.be.ok
315
419
  response.headers.should.include 'Etag'
316
420
  response.headers.should.include 'X-Content-Digest'
317
- response.body.should.be == 'Hello World'
421
+ response.body.should.equal 'Hello World'
318
422
  cache.should.a.performed :miss
319
423
  cache.should.a.performed :store
320
424
 
@@ -324,9 +428,9 @@ describe 'Rack::Cache::Context' do
324
428
  response.should.be.ok
325
429
  response.headers.should.include 'Etag'
326
430
  response.headers.should.include 'X-Content-Digest'
327
- response['Age'].to_i.should.be == 0
328
- response['X-Origin-Status'].should.be == '304'
329
- response.body.should.be == 'Hello World'
431
+ response['Age'].to_i.should.equal 0
432
+ response['X-Origin-Status'].should.equal '304'
433
+ response.body.should.equal 'Hello World'
330
434
  cache.should.a.not.performed :miss
331
435
  cache.should.a.performed :fetch
332
436
  cache.should.a.performed :store
@@ -348,22 +452,58 @@ describe 'Rack::Cache::Context' do
348
452
 
349
453
  # first request should fetch from backend and store in cache
350
454
  get '/'
351
- response.status.should.be == 200
352
- response.body.should.be == 'first response'
455
+ response.status.should.equal 200
456
+ response.body.should.equal 'first response'
353
457
 
354
458
  # second request is validated, is invalid, and replaces cached entry
355
459
  get '/'
356
- response.status.should.be == 200
357
- response.body.should.be == 'second response'
460
+ response.status.should.equal 200
461
+ response.body.should.equal 'second response'
358
462
 
359
463
  # third respone is validated, valid, and returns cached entry
360
464
  get '/'
361
- response.status.should.be == 200
362
- response.body.should.be == 'second response'
465
+ response.status.should.equal 200
466
+ response.body.should.equal 'second response'
467
+
468
+ count.should.equal 3
469
+ end
470
+
471
+ it 'passes HEAD requests through directly on pass' do
472
+ respond_with do |req,res|
473
+ res.status = 200
474
+ res.body = []
475
+ req.request_method.should.equal 'HEAD'
476
+ end
477
+
478
+ cache_config do
479
+ on(:receive) { pass! }
480
+ end
481
+
482
+ head '/'
483
+ app.should.be.called
484
+ response.body.should.equal ''
485
+ end
486
+
487
+ it 'uses cache to respond to HEAD requests when fresh' do
488
+ respond_with do |req,res|
489
+ res['Cache-Control'] = 'max-age=10'
490
+ res.body = ['Hello World']
491
+ req.request_method.should.not.equal 'HEAD'
492
+ end
493
+
494
+ get '/'
495
+ app.should.be.called
496
+ response.status.should.equal 200
497
+ response.body.should.equal 'Hello World'
363
498
 
364
- count.should.be == 3
499
+ head '/'
500
+ app.should.not.be.called
501
+ response.status.should.equal 200
502
+ response.body.should.equal ''
503
+ response['Content-Length'].should.equal 'Hello World'.length.to_s
365
504
  end
366
505
 
506
+
367
507
  describe 'with responses that include a Vary header' do
368
508
  before(:each) do
369
509
  count = 0
@@ -380,7 +520,7 @@ describe 'Rack::Cache::Context' do
380
520
  'HTTP_ACCEPT' => 'text/html',
381
521
  'HTTP_USER_AGENT' => 'Bob/1.0'
382
522
  response.should.be.ok
383
- response.body.should.be == 'Bob/1.0'
523
+ response.body.should.equal 'Bob/1.0'
384
524
  cache.should.a.performed :miss
385
525
  cache.should.a.performed :store
386
526
 
@@ -388,7 +528,7 @@ describe 'Rack::Cache::Context' do
388
528
  'HTTP_ACCEPT' => 'text/html',
389
529
  'HTTP_USER_AGENT' => 'Bob/1.0'
390
530
  response.should.be.ok
391
- response.body.should.be == 'Bob/1.0'
531
+ response.body.should.equal 'Bob/1.0'
392
532
  cache.should.a.performed :hit
393
533
  cache.should.a.not.performed :fetch
394
534
  response.headers.should.include 'X-Content-Digest'
@@ -399,36 +539,36 @@ describe 'Rack::Cache::Context' do
399
539
  'HTTP_ACCEPT' => 'text/html',
400
540
  'HTTP_USER_AGENT' => 'Bob/1.0'
401
541
  response.should.be.ok
402
- response.body.should.be == 'Bob/1.0'
403
- response['X-Response-Count'].should.be == '1'
542
+ response.body.should.equal 'Bob/1.0'
543
+ response['X-Response-Count'].should.equal '1'
404
544
 
405
545
  get '/',
406
546
  'HTTP_ACCEPT' => 'text/html',
407
547
  'HTTP_USER_AGENT' => 'Bob/2.0'
408
548
  cache.should.a.performed :miss
409
549
  cache.should.a.performed :store
410
- response.body.should.be == 'Bob/2.0'
411
- response['X-Response-Count'].should.be == '2'
550
+ response.body.should.equal 'Bob/2.0'
551
+ response['X-Response-Count'].should.equal '2'
412
552
 
413
553
  get '/',
414
554
  'HTTP_ACCEPT' => 'text/html',
415
555
  'HTTP_USER_AGENT' => 'Bob/1.0'
416
556
  cache.should.a.performed :hit
417
- response.body.should.be == 'Bob/1.0'
418
- response['X-Response-Count'].should.be == '1'
557
+ response.body.should.equal 'Bob/1.0'
558
+ response['X-Response-Count'].should.equal '1'
419
559
 
420
560
  get '/',
421
561
  'HTTP_ACCEPT' => 'text/html',
422
562
  'HTTP_USER_AGENT' => 'Bob/2.0'
423
563
  cache.should.a.performed :hit
424
- response.body.should.be == 'Bob/2.0'
425
- response['X-Response-Count'].should.be == '2'
564
+ response.body.should.equal 'Bob/2.0'
565
+ response['X-Response-Count'].should.equal '2'
426
566
 
427
567
  get '/',
428
568
  'HTTP_USER_AGENT' => 'Bob/2.0'
429
569
  cache.should.a.performed :miss
430
- response.body.should.be == 'Bob/2.0'
431
- response['X-Response-Count'].should.be == '3'
570
+ response.body.should.equal 'Bob/2.0'
571
+ response['X-Response-Count'].should.equal '3'
432
572
  end
433
573
  end
434
574
 
@@ -441,7 +581,7 @@ describe 'Rack::Cache::Context' do
441
581
  on(:receive) { error! }
442
582
  end
443
583
  get '/'
444
- response.status.should.be == 500
584
+ response.status.should.equal 500
445
585
  response.body.should.be.empty
446
586
  cache.should.a.performed :error
447
587
  end
@@ -451,7 +591,7 @@ describe 'Rack::Cache::Context' do
451
591
  on(:receive) { error! 505 }
452
592
  end
453
593
  get '/'
454
- response.status.should.be == 505
594
+ response.status.should.equal 505
455
595
  end
456
596
 
457
597
  it 'sets the status and headers with args: status, Hash' do
@@ -459,8 +599,8 @@ describe 'Rack::Cache::Context' do
459
599
  on(:receive) { error! 504, 'Content-Type' => 'application/x-foo' }
460
600
  end
461
601
  get '/'
462
- response.status.should.be == 504
463
- response['Content-Type'].should.be == 'application/x-foo'
602
+ response.status.should.equal 504
603
+ response['Content-Type'].should.equal 'application/x-foo'
464
604
  response.body.should.be.empty
465
605
  end
466
606
 
@@ -469,8 +609,8 @@ describe 'Rack::Cache::Context' do
469
609
  on(:receive) { error! 503, 'foo bar baz' }
470
610
  end
471
611
  get '/'
472
- response.status.should.be == 503
473
- response.body.should.be == 'foo bar baz'
612
+ response.status.should.equal 503
613
+ response.body.should.equal 'foo bar baz'
474
614
  end
475
615
 
476
616
  it 'sets the status and body with args: status, Array' do
@@ -478,8 +618,8 @@ describe 'Rack::Cache::Context' do
478
618
  on(:receive) { error! 503, ['foo bar baz'] }
479
619
  end
480
620
  get '/'
481
- response.status.should.be == 503
482
- response.body.should.be == 'foo bar baz'
621
+ response.status.should.equal 503
622
+ response.body.should.equal 'foo bar baz'
483
623
  end
484
624
 
485
625
  it 'fires the error event before finishing' do
@@ -488,16 +628,16 @@ describe 'Rack::Cache::Context' do
488
628
  on(:receive) { error! }
489
629
  on(:error) {
490
630
  fired = true
491
- response.status.should.be == 500
631
+ response.status.should.equal 500
492
632
  response['Content-Type'] = 'application/x-foo'
493
633
  response.body = ['overridden response body']
494
634
  }
495
635
  end
496
636
  get '/'
497
637
  fired.should.be true
498
- response.status.should.be == 500
499
- response.body.should.be == 'overridden response body'
500
- response['Content-Type'].should.be == 'application/x-foo'
638
+ response.status.should.equal 500
639
+ response.body.should.equal 'overridden response body'
640
+ response['Content-Type'].should.equal 'application/x-foo'
501
641
  end
502
642
 
503
643
  end