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