class Async::HTTP::Cache::General
def cacheable?(request)
def cacheable?(request) # We don't support caching requests which have a body: if request.body return false end # We can't cache upgraded requests: if request.protocol return false end # We only support caching GET and HEAD requests: unless request.method == 'GET' || request.method == 'HEAD' return false end if request.headers[AUTHORIZATION] return false end if request.headers[COOKIE] return false end # Otherwise, we can cache it: return true end
def call(request)
def call(request) key = self.key(request) cache_control = request.headers[CACHE_CONTROL] unless cache_control&.no_cache? if response = @store.lookup(key, request) Console.logger.debug(self) {"Cache hit for #{key}..."} @count += 1 # Return the cached response: return response end end unless cache_control&.no_store? if cacheable?(request) return wrap(key, request, super) end end return super end
def close
def close @store.close ensure super end
def initialize(app, store: Store.default)
def initialize(app, store: Store.default) super(app) @count = 0 @store = store end
def key(request)
def key(request) @store.normalize(request) [request.authority, request.method, request.path] end
def wrap(key, request, response)
def wrap(key, request, response) if response.status != 200 return response end if request.head? and body = response.body unless body.empty? Console.logger.warn(self) {"HEAD request resulted in non-empty body!"} return response end end return Body.wrap(response) do |response, body| Console.logger.debug(self) {"Updating cache for #{key}..."} @store.insert(key, request, Response.new(response, body)) end end