Permalink
Browse files

Disable client reload and revalidate requests by default

This was causing all kinds of confusion since refreshing in
the browser always caused a cache miss. People assumed that
rack-cache wasn't working at all. The allow_reload and
allow_revalidate options now default to false. This breaks
with RFC 2616 but is the desired config in a majority of
gateway cache scenarios.
  • Loading branch information...
1 parent 0956b10 commit d2681527c53ef14ce7dd7835e596341fdf23b32c @rtomayko rtomayko committed May 25, 2009
Showing with 65 additions and 10 deletions.
  1. +7 −0 CHANGES
  2. +28 −2 doc/configuration.markdown
  3. +2 −2 lib/rack/cache/options.rb
  4. +28 −6 test/context_test.rb
View
@@ -4,6 +4,13 @@
memcache-client library. These are the default unless the memcached
library has already been required.
+ * The "allow_reload" and "allow_revalidate" options now default to
+ false instead of true. This means we break with RFC 2616 out of
+ the box but this is the expected configuration in a huge majority
+ of gateway cache scenarios. See the docs on configuration
+ options for more information on these options:
+ http://tomayko.com/src/rack-cache/configuration
+
## 0.4.0 / March 2009
* Ruby 1.9.1 / Rack 1.0 compatible.
@@ -16,8 +16,8 @@ __Environment__.
When the __Rack::Cache__ object is instantiated:
use Rack::Cache,
- :verbose => true,
- :metastore => 'memcached://localhost:11211/',
+ :verbose => true,
+ :metastore => 'memcached://localhost:11211/',
:entitystore => 'file:/var/cache/rack'
Using __Rack__'s __Environment__:
@@ -81,6 +81,32 @@ If any of these headers are present in the request, the response is considered
private and will not be cached _unless_ the response is explicitly marked public
(e.g., `Cache-Control: public`).
+### `allow_reload`
+
+A boolean specifying whether reload requests sent by the client should be
+honored by the cache. When this option is enabled (`rack-cache.allow_reload`
+is `true`), requests that include a `Cache-Control: no-cache` header cause
+the cache to discard anything it has stored for the request and ask that the
+response be fully generated.
+
+Most browsers include a `Cache-Control: no-cache` header when the user performs
+a "hard refresh" (e.g., holding `Shift` while clicking the "Refresh" button).
+
+*IMPORTANT: Enabling this option globally allows all clients to break your cache.*
+
+### `allow_revalidate`
+
+A boolean specifying whether revalidate requests sent by the client should be
+honored by the cache. When this option is enabled (`rack-cache.allow_revalidate`
+is `true`), requests that include a `Cache-Control: max-age=0` header cause the
+cache to assume its copy of the response is stale, resulting in a conditional
+GET / validation request to be sent to the server.
+
+Most browsers include a `Cache-Control: max-age=0` header when the user performs
+a refresh (e.g., clicking the "Refresh" button).
+
+*IMPORTANT: Enabling this option globally allows all clients to break your cache.*
+
### `cache_key`
TODO: Document custom cache keys
@@ -133,8 +133,8 @@ def initialize_options(options={})
'rack-cache.entitystore' => 'heap:/',
'rack-cache.default_ttl' => 0,
'rack-cache.private_headers' => ['Authorization', 'Cookie'],
- 'rack-cache.allow_reload' => true,
- 'rack-cache.allow_revalidate' => true
+ 'rack-cache.allow_reload' => false,
+ 'rack-cache.allow_revalidate' => false
}
self.options = options
end
View
@@ -124,7 +124,8 @@
response.headers.should.include 'Age'
end
- it 'reloads responses when cache hits but no-cache request directive present' do
+ it 'reloads responses when cache hits but no-cache request directive present ' +
+ 'when allow_reload is set true' do
count = 0
respond_with 200, 'Cache-Control' => 'max-age=10000' do |req,res|
count+= 1
@@ -141,14 +142,16 @@
response.body.should.equal 'Hello World'
cache.trace.should.include :fresh
- get '/', 'HTTP_CACHE_CONTROL' => 'no-cache'
+ get '/',
+ 'rack-cache.allow_reload' => true,
+ 'HTTP_CACHE_CONTROL' => 'no-cache'
response.should.be.ok
response.body.should.equal 'Goodbye World'
cache.trace.should.include :reload
cache.trace.should.include :store
end
- it 'does not reload responses when allow_reload is set false' do
+ it 'does not reload responses when allow_reload is set false (default)' do
count = 0
respond_with 200, 'Cache-Control' => 'max-age=10000' do |req,res|
count+= 1
@@ -171,9 +174,17 @@
response.should.be.ok
response.body.should.equal 'Hello World'
cache.trace.should.not.include :reload
+
+ # test again without explicitly setting the allow_reload option to false
+ get '/',
+ 'HTTP_CACHE_CONTROL' => 'no-cache'
+ response.should.be.ok
+ response.body.should.equal 'Hello World'
+ cache.trace.should.not.include :reload
end
- it 'revalidates fresh cache entry when max-age request directive is exceeded' do
+ it 'revalidates fresh cache entry when max-age request directive is exceeded ' +
+ 'when allow_revalidate option is set true' do
count = 0
respond_with do |req,res|
count+= 1
@@ -192,15 +203,17 @@
response.body.should.equal 'Hello World'
cache.trace.should.include :fresh
- get '/', 'HTTP_CACHE_CONTROL' => 'max-age=0'
+ get '/',
+ 'rack-cache.allow_revalidate' => true,
+ 'HTTP_CACHE_CONTROL' => 'max-age=0'
response.should.be.ok
response.body.should.equal 'Goodbye World'
cache.trace.should.include :stale
cache.trace.should.include :invalid
cache.trace.should.include :store
end
- it 'does not revalidate fresh cache entry when enable_revalidate option is set false' do
+ it 'does not revalidate fresh cache entry when enable_revalidate option is set false (default)' do
count = 0
respond_with do |req,res|
count+= 1
@@ -227,6 +240,15 @@
cache.trace.should.not.include :stale
cache.trace.should.not.include :invalid
cache.trace.should.include :fresh
+
+ # test again without explicitly setting the allow_revalidate option to false
+ get '/',
+ 'HTTP_CACHE_CONTROL' => 'max-age=0'
+ response.should.be.ok
+ response.body.should.equal 'Hello World'
+ cache.trace.should.not.include :stale
+ cache.trace.should.not.include :invalid
+ cache.trace.should.include :fresh
end
it 'fetches response from backend when cache misses' do
respond_with 200, 'Expires' => (Time.now + 5).httpdate

0 comments on commit d268152

Please sign in to comment.