mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* lib/webrick/cookie.rb (parse): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56262 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			188 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			188 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
# frozen_string_literal: false
 | 
						|
require 'cgi/util'
 | 
						|
class CGI
 | 
						|
  # Class representing an HTTP cookie.
 | 
						|
  #
 | 
						|
  # In addition to its specific fields and methods, a Cookie instance
 | 
						|
  # is a delegator to the array of its values.
 | 
						|
  #
 | 
						|
  # See RFC 2965.
 | 
						|
  #
 | 
						|
  # == Examples of use
 | 
						|
  #   cookie1 = CGI::Cookie.new("name", "value1", "value2", ...)
 | 
						|
  #   cookie1 = CGI::Cookie.new("name" => "name", "value" => "value")
 | 
						|
  #   cookie1 = CGI::Cookie.new('name'     => 'name',
 | 
						|
  #                             'value'    => ['value1', 'value2', ...],
 | 
						|
  #                             'path'     => 'path',   # optional
 | 
						|
  #                             'domain'   => 'domain', # optional
 | 
						|
  #                             'expires'  => Time.now, # optional
 | 
						|
  #                             'secure'   => true,     # optional
 | 
						|
  #                             'httponly' => true      # optional
 | 
						|
  #                             )
 | 
						|
  #
 | 
						|
  #   cgi.out("cookie" => [cookie1, cookie2]) { "string" }
 | 
						|
  #
 | 
						|
  #   name     = cookie1.name
 | 
						|
  #   values   = cookie1.value
 | 
						|
  #   path     = cookie1.path
 | 
						|
  #   domain   = cookie1.domain
 | 
						|
  #   expires  = cookie1.expires
 | 
						|
  #   secure   = cookie1.secure
 | 
						|
  #   httponly = cookie1.httponly
 | 
						|
  #
 | 
						|
  #   cookie1.name     = 'name'
 | 
						|
  #   cookie1.value    = ['value1', 'value2', ...]
 | 
						|
  #   cookie1.path     = 'path'
 | 
						|
  #   cookie1.domain   = 'domain'
 | 
						|
  #   cookie1.expires  = Time.now + 30
 | 
						|
  #   cookie1.secure   = true
 | 
						|
  #   cookie1.httponly = true
 | 
						|
  class Cookie < Array
 | 
						|
    @@accept_charset="UTF-8" unless defined?(@@accept_charset)
 | 
						|
 | 
						|
    # Create a new CGI::Cookie object.
 | 
						|
    #
 | 
						|
    # :call-seq:
 | 
						|
    #   Cookie.new(name_string,*value)
 | 
						|
    #   Cookie.new(options_hash)
 | 
						|
    #
 | 
						|
    # +name_string+::
 | 
						|
    #   The name of the cookie; in this form, there is no #domain or
 | 
						|
    #   #expiration.  The #path is gleaned from the +SCRIPT_NAME+ environment
 | 
						|
    #   variable, and #secure is false.
 | 
						|
    # <tt>*value</tt>::
 | 
						|
    #   value or list of values of the cookie
 | 
						|
    # +options_hash+::
 | 
						|
    #   A Hash of options to initialize this Cookie.  Possible options are:
 | 
						|
    #
 | 
						|
    #   name:: the name of the cookie.  Required.
 | 
						|
    #   value:: the cookie's value or list of values.
 | 
						|
    #   path:: the path for which this cookie applies.  Defaults to the
 | 
						|
    #          the value of the +SCRIPT_NAME+ environment variable.
 | 
						|
    #   domain:: the domain for which this cookie applies.
 | 
						|
    #   expires:: the time at which this cookie expires, as a +Time+ object.
 | 
						|
    #   secure:: whether this cookie is a secure cookie or not (default to
 | 
						|
    #            false).  Secure cookies are only transmitted to HTTPS
 | 
						|
    #            servers.
 | 
						|
    #   httponly:: whether this cookie is a HttpOnly cookie or not (default to
 | 
						|
    #            false).  HttpOnly cookies are not available to javascript.
 | 
						|
    #
 | 
						|
    #   These keywords correspond to attributes of the cookie object.
 | 
						|
    def initialize(name = "", *value)
 | 
						|
      @domain = nil
 | 
						|
      @expires = nil
 | 
						|
      if name.kind_of?(String)
 | 
						|
        @name = name
 | 
						|
        %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
 | 
						|
        @path = ($1 or "")
 | 
						|
        @secure = false
 | 
						|
        @httponly = false
 | 
						|
        return super(value)
 | 
						|
      end
 | 
						|
 | 
						|
      options = name
 | 
						|
      unless options.has_key?("name")
 | 
						|
        raise ArgumentError, "`name' required"
 | 
						|
      end
 | 
						|
 | 
						|
      @name = options["name"]
 | 
						|
      value = Array(options["value"])
 | 
						|
      # simple support for IE
 | 
						|
      if options["path"]
 | 
						|
        @path = options["path"]
 | 
						|
      else
 | 
						|
        %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
 | 
						|
        @path = ($1 or "")
 | 
						|
      end
 | 
						|
      @domain = options["domain"]
 | 
						|
      @expires = options["expires"]
 | 
						|
      @secure = options["secure"] == true
 | 
						|
      @httponly = options["httponly"] == true
 | 
						|
 | 
						|
      super(value)
 | 
						|
    end
 | 
						|
 | 
						|
    # Name of this cookie, as a +String+
 | 
						|
    attr_accessor :name
 | 
						|
    # Path for which this cookie applies, as a +String+
 | 
						|
    attr_accessor :path
 | 
						|
    # Domain for which this cookie applies, as a +String+
 | 
						|
    attr_accessor :domain
 | 
						|
    # Time at which this cookie expires, as a +Time+
 | 
						|
    attr_accessor :expires
 | 
						|
    # True if this cookie is secure; false otherwise
 | 
						|
    attr_reader :secure
 | 
						|
    # True if this cookie is httponly; false otherwise
 | 
						|
    attr_reader :httponly
 | 
						|
 | 
						|
    # Returns the value or list of values for this cookie.
 | 
						|
    def value
 | 
						|
      self
 | 
						|
    end
 | 
						|
 | 
						|
    # Replaces the value of this cookie with a new value or list of values.
 | 
						|
    def value=(val)
 | 
						|
      replace(Array(val))
 | 
						|
    end
 | 
						|
 | 
						|
    # Set whether the Cookie is a secure cookie or not.
 | 
						|
    #
 | 
						|
    # +val+ must be a boolean.
 | 
						|
    def secure=(val)
 | 
						|
      @secure = val if val == true or val == false
 | 
						|
      @secure
 | 
						|
    end
 | 
						|
 | 
						|
    # Set whether the Cookie is a httponly cookie or not.
 | 
						|
    #
 | 
						|
    # +val+ must be a boolean.
 | 
						|
    def httponly=(val)
 | 
						|
      @httponly = !!val
 | 
						|
    end
 | 
						|
 | 
						|
    # Convert the Cookie to its string representation.
 | 
						|
    def to_s
 | 
						|
      val = collect{|v| CGI.escape(v) }.join("&")
 | 
						|
      buf = "#{@name}=#{val}"
 | 
						|
      buf << "; domain=#{@domain}" if @domain
 | 
						|
      buf << "; path=#{@path}"     if @path
 | 
						|
      buf << "; expires=#{CGI::rfc1123_date(@expires)}" if @expires
 | 
						|
      buf << "; secure"            if @secure
 | 
						|
      buf << "; HttpOnly"          if @httponly
 | 
						|
      buf
 | 
						|
    end
 | 
						|
 | 
						|
    # Parse a raw cookie string into a hash of cookie-name=>Cookie
 | 
						|
    # pairs.
 | 
						|
    #
 | 
						|
    #   cookies = CGI::Cookie.parse("raw_cookie_string")
 | 
						|
    #     # { "name1" => cookie1, "name2" => cookie2, ... }
 | 
						|
    #
 | 
						|
    def self.parse(raw_cookie)
 | 
						|
      cookies = Hash.new([])
 | 
						|
      return cookies unless raw_cookie
 | 
						|
 | 
						|
      raw_cookie.split(/;\s?/).each do |pairs|
 | 
						|
        name, values = pairs.split('=',2)
 | 
						|
        next unless name and values
 | 
						|
        name = CGI.unescape(name)
 | 
						|
        values ||= ""
 | 
						|
        values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) }
 | 
						|
        if cookies.has_key?(name)
 | 
						|
          values = cookies[name].value + values
 | 
						|
        end
 | 
						|
        cookies[name] = Cookie.new(name, *values)
 | 
						|
      end
 | 
						|
 | 
						|
      cookies
 | 
						|
    end
 | 
						|
 | 
						|
    # A summary of cookie string.
 | 
						|
    def inspect
 | 
						|
      "#<CGI::Cookie: #{self.to_s.inspect}>"
 | 
						|
    end
 | 
						|
 | 
						|
  end # class Cookie
 | 
						|
end
 | 
						|
 | 
						|
 |