The Strelka::Cookie class, a class for parsing and generating HTTP cookies.
Large parts of this code were copied from the Webrick::Cookie class in the Ruby standard library. The copyright statements for that module are:
Author: IPR -- Internet Programming with Ruby -- writers Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou Copyright (c) 2002 Internet Programming with Ruby writers. All rights reserved.
References:
The format of the date field
Number of seconds in the various offset types
The domain the cookie belongs to
The cookie's expiration (a Time object)
The cookie's HttpOnly flag
The lifetime of the cookie, in seconds.
The name of the cookie
The path the cookie applies to
The cookie's 'secure' flag.
The string value of the cookie
The cookie version. 0 (the default) is fine for most uses
Strip surrounding double quotes from a copy of the specified string and return it.
# File lib/strelka/cookie.rb, line 52
def self::dequote( string )
return string.gsub( /^"|"$/, '' )
end
Create a new Strelka::Cookie object with the
specified name
and values
. Valid options are:
The cookie version. 0 (the default) is fine for most uses
The domain the cookie belongs to.
The path the cookie applies to.
The cookie's 'secure' flag.
The cookie's expiration (a Time object). See expires= for valid values.
The lifetime of the cookie, in seconds.
HttpOnly flag.
# File lib/strelka/cookie.rb, line 115
def initialize( name, value, options={} )
options ||= {}
# self.log.debug "New cookie: %p = %p (%p)" % [ name, value, options ]
@name = name
@value = value
@domain = nil
@path = nil
@secure = false
@httponly = false
@max_age = nil
@expires = nil
@version = 0
# self.log.debug " setting options: %p" % [ options ]
options.each do |meth, val|
self.__send__( "#{meth}=", val )
end
end
Parse the specified 'Cookie:' header
value and return
a Hash of one or more new Strelka::Cookie
objects, keyed by name.
# File lib/strelka/cookie.rb, line 59
def self::parse( header )
return {} if header.nil? or header.empty?
self.log.debug "Parsing cookie header: %p" % [ header ]
cookies = {}
version = 0
header = header.strip
# "$Version" = value
if m = COOKIE_VERSION.match( header )
# self.log.debug " Found cookie version %p" % [ m[:version] ]
version = Integer( dequote(m[:version]) )
header.slice!( COOKIE_VERSION )
end
# cookie-header = "Cookie:" OWS cookie-string OWS
# cookie-string = cookie-pair *( ";" SP cookie-pair )
header.split( /;\x20/ ).each do |cookie_pair|
# self.log.debug " parsing cookie-pair: %p" % [ cookie_pair ]
match = cookie_pair.match( COOKIE_PAIR ) or
raise Strelka::ParseError, "malformed cookie pair: %p" % [ cookie_pair ]
# self.log.debug " matched cookie: %p" % [ match ]
name = match[:cookie_name].untaint
value = match[:cookie_value]
value = self.dequote( value ) if value.start_with?( DQUOTE )
value = nil if value.empty?
cookies[ name.to_sym ] = new( name, value, :version => version )
end
return cookies
end
Fetch the cookie's data after un-base64ing it. This is just a convenience method for:
cookie.value.unpack( 'm' ).first
# File lib/strelka/cookie.rb, line 216
def binary_value
return self.value.unpack( 'm' ).first
end
Store the base64'ed data
as the cookie value. This is just
a convenience method for:
cookie.value = [data].pack('m').strip
# File lib/strelka/cookie.rb, line 204
def binary_value=( data )
# self.log.debug "Setting cookie value to base64ed %p" % [ data ]
self.value = [ data ].pack( 'm' ).strip
end
Set the domain for which the cookie is valid. Leading '.' characters will be stripped.
# File lib/strelka/cookie.rb, line 249
def domain=( newdomain )
if newdomain.nil?
@domain = nil
else
newdomain = newdomain.dup
newdomain.slice!( 0 ) while newdomain.start_with?( '.' )
@domain = newdomain
end
end
Return true
if other_cookie has the same name as the receiver.
# File lib/strelka/cookie.rb, line 319
def eql?( other_cookie )
# self.log.debug "Comparing %p with other cookie: %p" % [ self, other_cookie ]
return (self.name == other_cookie.name) ? true : false
end
Set the cookie expiration to a time in the past
# File lib/strelka/cookie.rb, line 296
def expire!
self.expires = Time.at(0)
end
Set the cookie's expires field. The value can be either a Time object or a String in any of the following formats:
30 seconds from now
ten minutes from now
one hour from now
yesterday (i.e. “ASAP!”)
immediately
in three months
in ten years time
at the indicated time & date
# File lib/strelka/cookie.rb, line 278
def expires=( time )
case time
when NilClass
@expires = nil
when Date
@expires = Time.parse( time.ctime )
when Time
@expires = time
else
@expires = parse_time_delta( time )
end
end
Generate a Fixnum hash value for this object. Uses the hash of the cookie's name.
# File lib/strelka/cookie.rb, line 326
def hash
return self.name.to_s.hash
end
Returns true
if the 'httponly' flag is set
# File lib/strelka/cookie.rb, line 229
def httponly?
return @httponly ? true : false
end
Set the lifetime of the cookie. The value is a decimal non-negative
integer. After delta_seconds
seconds elapse, the client
should discard the cookie. A value of zero means the cookie should be
discarded immediately.
# File lib/strelka/cookie.rb, line 238
def max_age=( delta_seconds )
if delta_seconds.nil?
@max_age = nil
else
@max_age = Integer( delta_seconds )
end
end
Return the cookie's options as a hash.
# File lib/strelka/cookie.rb, line 138
def options
return {
domain: self.domain,
path: self.path,
secure: self.secure?,
httponly: self.httponly?,
expires: self.expires,
max_age: self.max_age,
version: self.version,
}
end
Returns true
if the secure flag is set
# File lib/strelka/cookie.rb, line 223
def secure?
return @secure ? true : false
end
Return the cookie as a String
# File lib/strelka/cookie.rb, line 302
def to_s
rval = "%s=%s" % [ self.name, self.make_valuestring ]
rval << make_field( "Version", self.version ) if self.version.nonzero?
rval << make_field( "Domain", self.domain )
rval << make_field( "Expires", make_cookiedate(self.expires) ) if self.expires
rval << make_field( "Max-Age", self.max_age )
rval << make_field( "Path", self.path )
rval << '; ' << 'HttpOnly' if self.httponly?
rval << '; ' << 'Secure' if self.secure?
return rval
end
Set the new value of the cookie to cookie_octets
. This raises
an exception if cookie_octets
contains any invalid characters.
If your value contains non-US-ASCII characters; control characters; or
comma, semicolon, or backslash.
# File lib/strelka/cookie.rb, line 187
def value=( cookie_octets )
# self.log.debug "Setting cookie value to: %p" % [ cookie_octets ]
raise Strelka::CookieError,
"invalid cookie value; value must be composed of non-control us-ascii characters " +
"other than SPACE, double-quote, comma, semi-colon, and backslash. " +
"Use #base64_value= for storing arbitrary data." unless
cookie_octets =~ /^#{COOKIE_VALUE}$/
@value = cookie_octets
end
Make a uri-escaped value string for the cookie's current
values
.
# File lib/strelka/cookie.rb, line 336
def make_valuestring
return self.value
end