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

The format of the date field

UNIT_SECONDS

Number of seconds in the various offset types

Attributes

domain[R]

The domain the cookie belongs to

expires[R]

The cookie's expiration (a Time object)

httponly[RW]

The cookie's HttpOnly flag

max_age[R]

The lifetime of the cookie, in seconds.

name[RW]

The name of the cookie

path[RW]

The path the cookie applies to

secure[W]

The cookie's 'secure' flag.

value[R]

The string value of the cookie

version[RW]

The cookie version. 0 (the default) is fine for most uses

Public Class Methods

dequote( string ) click to toggle source

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
new( name, value, options={} ) click to toggle source

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( header ) click to toggle source

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

binary_value() click to toggle source

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
Also aliased as: wrapped_value
binary_value=( data ) click to toggle source

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
Also aliased as: wrapped_value=
domain=( newdomain ) click to toggle source

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
eql?( other_cookie ) click to toggle source

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
expire!() click to toggle source

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
expires=( time ) click to toggle source

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
hash() click to toggle source

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
httponly?() click to toggle source

Returns true if the 'httponly' flag is set

# File lib/strelka/cookie.rb, line 229
def httponly?
        return @httponly ? true : false
end
max_age=( delta_seconds ) click to toggle source

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
options() click to toggle source

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
secure?() click to toggle source

Returns true if the secure flag is set

# File lib/strelka/cookie.rb, line 223
def secure?
        return @secure ? true : false
end
to_s() click to toggle source

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
value=( cookie_octets ) click to toggle source

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
wrapped_value()
Alias for: binary_value
wrapped_value=( data )
Alias for: binary_value=

Protected Instance Methods

make_valuestring() click to toggle source

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_cookiedate( date ) click to toggle source

Make an RFC2109-formatted date out of date.

# File lib/strelka/cookie.rb, line 374
def make_cookiedate( date )
        return date.gmtime.strftime( COOKIE_DATE_FORMAT )
end
make_field( field_name, value ) click to toggle source

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_time_delta( time ) click to toggle source

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( val ) click to toggle source

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