class Mechanize::Cookie

This class is used to represent an HTTP Cookie.

Attributes

accessed_at[RW]
comment[RW]
created_at[RW]
domain[RW]
for_domain[RW]

If this flag is true, this cookie will be sent to any host in the domain. If it is false, this cookie will be sent only to the host indicated by the domain.

for_domain?[RW]

If this flag is true, this cookie will be sent to any host in the domain. If it is false, this cookie will be sent only to the host indicated by the domain.

httponly[RW]
httponly?[RW]
max_age[RW]
name[R]
path[RW]
secure[RW]
secure?[RW]
session[RW]
set_domain[RW]
value[RW]
version[RW]

Public Class Methods

new(name, value) click to toggle source
new(name, value, attr_hash)
new(attr_hash)

Creates a cookie object. For each key of attr_hash, the setter is called if defined. Each key can be either a symbol or a string, downcased or not.

e.g.

new("uid", "a12345")
new("uid", "a12345", :domain => 'example.org',
                     :for_domain => true, :expired => Time.now + 7*86400)
new("name" => "uid", "value" => "a12345", "Domain" => 'www.example.org')
# File lib/mechanize/cookie.rb, line 33
def initialize(*args)
  @version = 0     # Netscape Cookie

  @domain = @path = @secure = @comment = @max_age =
    @expires = @comment_url = @discard = @port = @httponly = nil

  @created_at = @accessed_at = Time.now
  case args.size
  when 2
    @name, @value = *args
    @for_domain = false
    return
  when 3
    @name, @value, attr_hash = *args
  when 1
    attr_hash = args.first
  else
    raise ArgumentError, "wrong number of arguments (#{args.size} for 1-3)"
  end
  for_domain = false
  attr_hash.each_pair { |key, val|
    skey = key.to_s.downcase
    skey.sub!(/[!?]\z/, '')
    case skey
    when 'for_domain'
      for_domain = !!val
    when 'name'
      @name = val
    when 'value'
      @value = val
    else
      setter = :"#{skey}="
      send(setter, val) if respond_to?(setter)
    end
  }
  @for_domain = for_domain
end
parse(uri, str, log = Mechanize.log) { |cookie| ... } click to toggle source

Parses a Set-Cookie header line str sent from uri into an array of Cookie objects. Note that this array may contain nil's when some of the cookie-pairs are malformed.

# File lib/mechanize/cookie.rb, line 81
def parse(uri, str, log = Mechanize.log)
  return str.to_s.split(/,(?=[^;,]*=)|,$/).map { |c|
    cookie_elem = c.split(/;+/)
    first_elem = cookie_elem.shift
    first_elem.strip!
    key, value = first_elem.split(/\=/, 2)

    begin
      cookie = new(key, value.dup)
    rescue
      log.warn("Couldn't parse key/value: #{first_elem}") if log
      next
    end

    cookie_elem.each do |pair|
      pair.strip!
      key, value = pair.split(/=/, 2)
      next unless key
      value = WEBrick::HTTPUtils.dequote(value.strip) if value


      case key.downcase
      when 'domain'
        next unless value && !value.empty?
        begin
          cookie.domain = value
          cookie.for_domain = true
        rescue
          log.warn("Couldn't parse domain: #{value}") if log
        end
      when 'path'
        next unless value && !value.empty?
        cookie.path = value
      when 'expires'
        next unless value && !value.empty?
        begin
          cookie.expires = Time::parse(value)
        rescue
          log.warn("Couldn't parse expires: #{value}") if log
        end
      when 'max-age'
        next unless value && !value.empty?
        begin
          cookie.max_age = Integer(value)
        rescue
          log.warn("Couldn't parse max age '#{value}'") if log
        end
      when 'comment'
        next unless value
        cookie.comment = value
      when 'version'
        next unless value
        begin
          cookie.version = Integer(value)
        rescue
          log.warn("Couldn't parse version '#{value}'") if log
          cookie.version = nil
        end
      when 'httponly'
        cookie.httponly = true
      when 'secure'
        cookie.secure = true
      end
    end

    cookie.path    ||= (uri + './').path
    cookie.secure  ||= false
    cookie.domain  ||= uri.host
    cookie.httponly ||= false

    # RFC 6265 4.1.2.2
    cookie.expires   = Time.now + cookie.max_age if cookie.max_age
    cookie.session   = !cookie.expires

    # Move this in to the cookie jar
    yield cookie if block_given?

    cookie
  }
end

Public Instance Methods

acceptable_from_uri?(uri) click to toggle source
# File lib/mechanize/cookie.rb, line 203
def acceptable_from_uri?(uri)
  host = DomainName.new(uri.host)

  # RFC 6265 5.3
  # When the user agent "receives a cookie":
  return host.hostname == domain unless @for_domain

  if host.cookie_domain?(@domain_name)
    true
  elsif host.hostname == domain
    @for_domain = false
    true
  else
    false
  end
end
domain=(domain) click to toggle source

Sets the domain attribute. A leading dot in domain implies turning the for_domain? flag on.

# File lib/mechanize/cookie.rb, line 167
def domain=(domain)
  if DomainName === domain
    @domain_name = domain
  else
    domain.is_a?(String) or
      (domain.respond_to?(:to_str) && (domain = domain.to_str).is_a?(String)) or
      raise TypeError, "#{domain.class} is not a String"
    if domain.start_with?('.')
      @for_domain = true
      domain = domain[1..-1]
    end
    # Do we really need to support this?
    if domain.match(/\A([^:]+):[0-9]+\z/)
      domain = $1
    end
    @domain_name = DomainName.new(domain)
  end
  set_domain(@domain_name.hostname)
end
expired?() click to toggle source
# File lib/mechanize/cookie.rb, line 195
def expired?
  return false unless expires
  Time.now > expires
end
expires() click to toggle source
# File lib/mechanize/cookie.rb, line 191
def expires
  @expires && Time.parse(@expires)
end
expires=(t) click to toggle source
# File lib/mechanize/cookie.rb, line 187
def expires=(t)
  @expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s)
end
init_with(coder) click to toggle source
# File lib/mechanize/cookie.rb, line 229
def init_with(coder)
  yaml_initialize(coder.tag, coder.map)
end
to_s() click to toggle source
# File lib/mechanize/cookie.rb, line 225
def to_s
  "#{@name}=#{@value}"
end
valid_for_uri?(uri) click to toggle source
# File lib/mechanize/cookie.rb, line 220
def valid_for_uri?(uri)
  return false if secure? && uri.scheme != 'https'
  acceptable_from_uri?(uri) && uri.path.start_with?(path)
end
yaml_initialize(tag, map) click to toggle source
# File lib/mechanize/cookie.rb, line 233
def yaml_initialize(tag, map)
  @for_domain = true    # for forward compatibility
  map.each { |key, value|
    case key
    when 'domain'
      self.domain = value # ditto
    else
      instance_variable_set(:"@#{key}", value)
    end
  }
end