/usr/lib/ruby/vendor_ruby/mechanize/cookie.rb is in ruby-mechanize 2.3-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | require 'time'
require 'webrick/httputils'
require 'domain_name'
# This class is used to represent an HTTP Cookie.
class Mechanize::Cookie
attr_reader :name
attr_accessor :value, :version
attr_accessor :domain, :path, :secure
attr_accessor :comment, :max_age
attr_accessor :session
attr_accessor :created_at
attr_accessor :accessed_at
# :call-seq:
# new(name, value)
# 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')
#
def initialize(*args)
@version = 0 # Netscape Cookie
@domain = @path = @secure = @comment = @max_age =
@expires = @comment_url = @discard = @port = 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
# 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+.
attr_accessor :for_domain
alias for_domain? for_domain
class << self
# 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.
def parse(uri, str, log = Mechanize.log)
return str.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 'secure'
cookie.secure = true
end
end
cookie.path ||= (uri + './').path
cookie.secure ||= false
cookie.domain ||= uri.host
# 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
end
alias set_domain domain=
# Sets the domain attribute. A leading dot in +domain+ implies
# turning the +for_domain?+ flag on.
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
def expires=(t)
@expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s)
end
def expires
@expires && Time.parse(@expires)
end
def expired?
return false unless expires
Time.now > expires
end
alias secure? secure
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
def valid_for_uri?(uri)
return false if secure? && uri.scheme != 'https'
acceptable_from_uri?(uri) && uri.path.start_with?(path)
end
def to_s
"#{@name}=#{@value}"
end
def init_with(coder)
yaml_initialize(coder.tag, coder.map)
end
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
end
|