class Strelka::Cookie
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:
Constants
- COOKIE_DATE_FORMAT
The format of the date field
- UNIT_SECONDS
Number of seconds in the various offset types
Attributes
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
Public Class Methods
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:
- version
-
The cookie version. 0 (the default) is fine for most uses
- domain
-
The domain the cookie belongs to.
- path
-
The path the cookie applies to.
- secure
-
The cookie's 'secure' flag.
- expires
-
The cookie's expiration (a Time object). See expires= for valid values.
- max_age
-
The lifetime of the cookie, in seconds.
- httponly
-
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] 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
Public Instance Methods
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:
- +30s
-
30 seconds from now
- +10m
-
ten minutes from now
- +1h
-
one hour from now
- -1d
-
yesterday (i.e. “ASAP!”)
- now
-
immediately
- +3M
-
in three months
- +10y
-
in ten years time
- Thursday, 25-Apr-1999 00:40:33 GMT
-
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
Protected Instance Methods
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
Private Instance Methods
Make a cookie field for appending to the outgoing header for the specified value
and field_name
. If value
is nil, an empty string will be returned.
# File lib/strelka/cookie.rb, line 348 def make_field( field_name, value ) return '' if value.nil? || (value.is_a?(String) && value.empty?) return "; %s=%s" % [ field_name.capitalize, value ] end
Parse a time delta like those accepted by expires=
into a Time object.
# File lib/strelka/cookie.rb, line 360 def parse_time_delta( time ) return Time.now if time.nil? || time == 'now' return Time.at( Integer(time) ) if /^\d+$/.match( time ) if /^([+-]?(?:\d+|\d*\.\d*))([mhdMy]?)/.match( time ) offset = (UNIT_SECONDS[$2] || 1) * Integer($1) return Time.now + offset end return Time.parse( time ) end
Quote a copy of the given string and return it.
# File lib/strelka/cookie.rb, line 380 def quote( val ) return %q{"%s"} % [ val.to_s.gsub(/"/, '\\"') ] end