Skip to content

Commit ed165c8

Browse files
committed
Allow customisation of non-cached headers
Headers specified in the :non_cached_headers option are included in responses but not stored in cached entities.
1 parent d07cce7 commit ed165c8

File tree

4 files changed

+54
-15
lines changed

4 files changed

+54
-15
lines changed

lib/rack/cache/context.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ def fetch
286286
# Write the response to the cache.
287287
def store(response)
288288
strip_ignore_headers(response)
289-
metastore.store(@request, response, entitystore)
289+
metastore.store(@request, response, entitystore, non_cached_headers)
290290
response.headers['age'] = response.age.to_s
291291
rescue => e
292292
log_error(e)

lib/rack/cache/meta_store.rb

+5-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def lookup(request, entity_store)
5858
# Write a cache entry to the store under the given key. Existing
5959
# entries are read and any that match the response are removed.
6060
# This method calls #write with the new list of cache entries.
61-
def store(request, response, entity_store)
61+
def store(request, response, entity_store, non_cached_headers = [])
6262
key = cache_key(request)
6363
stored_env = persist_request(request)
6464

@@ -98,6 +98,10 @@ def store(request, response, entity_store)
9898
headers = persist_response(response)
9999
headers.delete('age')
100100

101+
pp non_cached_headers
102+
103+
non_cached_headers.each{ |h| headers.delete(h) }
104+
101105
entries.unshift [stored_env, headers]
102106
if request.env['rack-cache.use_native_ttl'] && response.fresh?
103107
write key, entries, response.ttl

lib/rack/cache/options.rb

+20-13
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ def option_name(key)
9393
# Default: []
9494
option_accessor :transfer_headers
9595

96+
# Set of response headers that will be passed to the client when present
97+
# in any responses but will not be stored in cached entries.
98+
#
99+
# Default: []
100+
option_accessor :non_cached_headers
101+
96102
# Set of request headers that trigger "private" cache-control behavior
97103
# on responses that don't explicitly state whether the response is
98104
# public or private via a cache-control directive. Applications that use
@@ -149,19 +155,20 @@ def set(option, value=self, &block)
149155
private
150156
def initialize_options(options={})
151157
@default_options = {
152-
'rack-cache.cache_key' => Key,
153-
'rack-cache.verbose' => true,
154-
'rack-cache.storage' => Rack::Cache::Storage.instance,
155-
'rack-cache.metastore' => 'heap:/',
156-
'rack-cache.entitystore' => 'heap:/',
157-
'rack-cache.default_ttl' => 0,
158-
'rack-cache.ignore_headers' => ['set-cookie'],
159-
'rack-cache.transfer_headers' => [],
160-
'rack-cache.private_headers' => ['Authorization', 'Cookie'],
161-
'rack-cache.allow_reload' => false,
162-
'rack-cache.allow_revalidate' => false,
163-
'rack-cache.use_native_ttl' => false,
164-
'rack-cache.fault_tolerant' => false,
158+
'rack-cache.cache_key' => Key,
159+
'rack-cache.verbose' => true,
160+
'rack-cache.storage' => Rack::Cache::Storage.instance,
161+
'rack-cache.metastore' => 'heap:/',
162+
'rack-cache.entitystore' => 'heap:/',
163+
'rack-cache.default_ttl' => 0,
164+
'rack-cache.ignore_headers' => ['set-cookie'],
165+
'rack-cache.transfer_headers' => [],
166+
'rack-cache.non_cached_headers' => [],
167+
'rack-cache.private_headers' => ['Authorization', 'Cookie'],
168+
'rack-cache.allow_reload' => false,
169+
'rack-cache.allow_revalidate' => false,
170+
'rack-cache.use_native_ttl' => false,
171+
'rack-cache.fault_tolerant' => false,
165172
}
166173
self.options = options
167174
end

test/context_test.rb

+28
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,34 @@
800800
cache.trace.must_include :valid
801801
end
802802

803+
it 'excludes specified headers from being cached in responses' do
804+
count = 0
805+
respond_with do |req,res|
806+
count += 1
807+
res['ETAG'] = '"12345"'
808+
if count == 1
809+
res['not-cached'] = '"1"'
810+
end
811+
res.status = (count == 1) ? 200 : 304
812+
end
813+
814+
get '/', 'rack-cache.non_cached_headers' => ['not-cached']
815+
assert app.called?
816+
assert response.ok?
817+
response.headers.must_include 'not-cached'
818+
cache.trace.must_include :miss
819+
cache.trace.must_include :store
820+
cache.trace.wont_include :ignore
821+
822+
get '/', 'rack-cache.non_cached_headers' => ['not-cached']
823+
assert app.called?
824+
assert response.ok?
825+
response.headers.wont_include 'not-cached'
826+
cache.trace.must_include :stale
827+
cache.trace.must_include :valid
828+
cache.trace.must_include :store
829+
end
830+
803831
it 'replaces cached responses when validation results in non-304 response' do
804832
timestamp = Time.now.httpdate
805833
count = 0

0 commit comments

Comments
 (0)