Rails源码研究之ActionController:五,cookies

cookies.rb:
module ActionController
  module Cookies
    protected
      def cookies
        CookieJar.new(self)
      end
  end

  class CookieJar < Hash
    def initialize(controller)
      @controller, @cookies = controller, controller.request.cookies
      super()
      update(@cookies)
    end
    def [](name)
      @cookies[name.to_s].value.first if @cookies[name.to_s] && @cookies[name.to_s].respond_to?(:value)
    end
    def []=(name, options)
      if options.is_a?(Hash)
        options = options.inject({}) { |options, pair| options[pair.first.to_s] = pair.last; options }
        options["name"] = name.to_s
      else
        options = { "name" => name.to_s, "value" => options }
      end

      set_cookie(options)
    end
    def delete(name)
      set_cookie("name" => name.to_s, "value" => "", "expires" => Time.at(0))
    end

    private
      def set_cookie(options)
        options["path"] = "/" unless options["path"]
        cookie = CGI::Cookie.new(options)
        @controller.logger.info "Cookie set: #{cookie}" unless @controller.logger.nil?
        @controller.response.headers["cookie"] << cookie
      end
  end
end

我们看到Cookies模块定义了cookies方法返回初始化的CookieJar类,而CookieJar继承于Hash类,CookieJar初始化时@cookies = controller.request.cookies
CookieJar中重载了[]和[]=方法以及delete方法,这样我们就可以直接在controller里使用cookies[]来得到和设置cookie了
具体操作set_cookie则是在response.headers里加入CGI:Cookie对象
CGI:Cookie的定义见action_controller\cgi_ext\cookie_performance_fix.rb:
CGI.module_eval { remove_const "Cookie" }
class CGI
  class Cookie < DelegateClass(Array)
    ...
  end
end

CGI:Cookie类代理到Array类

你可能感兴趣的:(ext,cgi,Rails,performance)