class Faraday::HttpCache::Storage

Faraday::HttpCache::Storage.new(:memory_store, serializer: Marshal)
# Creates a new Storage using Marshal for serialization.
Faraday::HttpCache::Storage.new(Rails.cache)
# Reuse some other instance of an ActiveSupport::Cache::Store object.
Faraday::HttpCache::Storage.new(:mem_cache_store)
# Creates a new Storage using a MemCached backend from ActiveSupport.
Examples
Internal: A wrapper around an ActiveSupport::CacheStore to store responses.

def assert_valid_store!

Returns nothing.

Raises an 'ArgumentError'.

expect API ('read' and 'write').
Internal: Checks if the given cache object supports the
def assert_valid_store!
  unless cache.respond_to?(:read) && cache.respond_to?(:write) && cache.respond_to?(:delete)
    raise ArgumentError.new("#{cache.inspect} is not a valid cache store as it does not responds to 'read', 'write' or 'delete'.")
  end
end

def cache_key_for(url)

Returns a String.

url - The request URL.

account the current serializer to avoid cross serialization issues.
Internal: Computes the cache key for a specific request, taking in
def cache_key_for(url)
  prefix = (@serializer.is_a?(Module) ? @serializer : @serializer.class).name
  Digest::SHA1.hexdigest("#{prefix}#{url}")
end

def delete(url)

def delete(url)
  cache_key = cache_key_for(url)
  cache.delete(cache_key)
end

def deserialize_entry(*objects)

def deserialize_entry(*objects)
  objects.map { |object| deserialize_object(object) }
end

def deserialize_object(object)

def deserialize_object(object)
  @serializer.load(object).each_with_object({}) do |(key, value), hash|
    hash[key.to_sym] = value
  end
end

def initialize(options = {})

respond to 'dump' and 'load'.
:serializer - A serializer object that should
respond to 'read', 'write', and 'delete'.
:store - An cache store object that should
:logger - A Logger object to be used to emit warnings.
options - Storage options (default: {}).

Internal: Initialize a new Storage object with a cache backend.
def initialize(options = {})
  @cache = options[:store] || MemoryStore.new
  @serializer = options[:serializer] || JSON
  @logger = options[:logger]
  assert_valid_store!
end

def lookup_response(request, entries)

Returns a Hash or nil.

entries - An Array of pairs of Hashes (request, response).
request.
request - A Faraday::HttpCache::::Request instance of the incoming HTTP

the given request.
Internal: Retrieve a response Hash from the list of entries that match
def lookup_response(request, entries)
  if entries
    entries = entries.map { |entry| deserialize_entry(*entry) }
    _, response = entries.find { |req, res| response_matches?(request, req, res) }
    response
  end
end

def read(request, klass = Faraday::HttpCache::Response)

Returns an instance of 'klass'.

klass - The Class to be instantiated with the stored response.
request.
request - A Faraday::HttpCache::::Request instance of the incoming HTTP

HTTP request.
Internal: Attempt to retrieve an stored response that suits the incoming
def read(request, klass = Faraday::HttpCache::Response)
  cache_key = cache_key_for(request.url)
  entries = cache.read(cache_key)
  response = lookup_response(request, entries)
  if response
    klass.new(response)
  end
end

def response_matches?(request, cached_request, cached_response)

Returns true or false.

cached_response - The Hash of the response that was cached.
cached_request - The Hash of the request that was cached.
current HTTP request.
request - A Faraday::HttpCache::::Request instance of the

request.
Internal: Check if a cached response and request matches the given
def response_matches?(request, cached_request, cached_response)
  request.method.to_s == cached_request[:method].to_s &&
    vary_matches?(cached_response, request, cached_request)
end

def serialize_entry(*objects)

def serialize_entry(*objects)
  objects.map { |object| serialize_object(object) }
end

def serialize_object(object)

def serialize_object(object)
  @serializer.dump(object)
end

def vary_matches?(cached_response, request, cached_request)

def vary_matches?(cached_response, request, cached_request)
  headers = Faraday::Utils::Headers.new(cached_response[:response_headers])
  vary = headers['Vary'].to_s
  vary.empty? || (vary != '*' && vary.split(/[\s,]+/).all? do |header|
    request.headers[header] == cached_request[:headers][header]
  end)
end

def warn(message)

def warn(message)
  @logger.warn(message) if @logger
end

def write(request, response)

Returns nothing.

response - The Faraday::HttpCache::Response instance to be stored.
request.
request - A Faraday::HttpCache::::Request instance of the executed HTTP

Internal: Store a response inside the cache.
def write(request, response)
  key = cache_key_for(request.url)
  entry = serialize_entry(request.serializable_hash, response.serializable_hash)
  entries = cache.read(key) || []
  entries = entries.dup if entries.frozen?
  entries.reject! do |(cached_request, cached_response)|
    response_matches?(request, deserialize_object(cached_request), deserialize_object(cached_response))
  end
  entries << entry
  cache.write(key, entries)
rescue Encoding::UndefinedConversionError => e
  warn "Response could not be serialized: #{e.message}. Try using Marshal to serialize."
  raise e
end