File: //usr/lib/ruby/vendor_ruby/rack/moneta_cookies.rb
require 'moneta'
require 'rack/utils'
module Rack
# A Rack middleware that was made to reuse all moneta transformers
# on the cookie hash.
#
# @example config.ru
# # Add Rack::MonetaCookies somewhere in your rack stack
# use Rack::MonetaCookies
#
# run lambda { |env| [200, {}, []] }
# # But this doesn't do much
#
# @example config.ru
# # Give it some options
# use Rack::MonetaCookies, domain: 'example.com', path: '/path'
#
# @example config.ru
# # Pass it a block like the one passed to Moneta.build
# use Rack::MonetaCookies do
# use :Transformer, key: :prefix, prefix: 'moneta.'
# adapter :Cookie
# end
#
# run lambda { |env|
# req = Rack::Request.new(env)
# req.cookies #=> is now a Moneta store!
# env['rack.request.cookie_hash'] #=> is now a Moneta store!
# req.cookies['key'] #=> retrieves 'moneta.key'
# req.cookies['key'] = 'value' #=> sets 'moneta.key'
# req.cookies.delete('key') #=> removes 'moneta.key'
# [200, {}, []]
# }
#
# @api public
class MonetaCookies
def initialize(app, options = {}, &block)
@app, @pool = app, []
if block
raise ArgumentError, 'Use either block or options' unless options.empty?
@builder = Moneta::Builder.new(&block)
else
@builder = Moneta::Builder.new { adapter :Cookie, options }
end
end
def call(env)
stores = @pool.pop || @builder.build
env['rack.moneta_cookies'] = env['rack.request.cookie_hash'] = stores.last
env['rack.request.cookie_string'] = env['HTTP_COOKIE']
stores.first.reset(Rack::Utils.parse_query(env['HTTP_COOKIE']))
status, headers, body = @app.call(env)
stores.first.cookies.each do |key, cookie|
if cookie == nil
Rack::Utils.delete_cookie_header!(headers, key)
else
Rack::Utils.set_cookie_header!(headers, key, cookie)
end
end
@pool << stores
[status, headers, body]
end
end
end