Class: Arrow::Cookie

Inherits:
Object show all
Defined in:
lib/arrow/cookie.rb

Overview

The Arrow::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.

VCS Id

  $Id$

Authors

  • Michael Granger

Please see the file LICENSE in the top-level directory for licensing details.

Constant Summary

CookieDateFormat =
'%a, %d-%b-%Y %H:%M:%S GMT'
CookieVersion =

RFC 2109: HTTP State Management Mechanism When it sends a request to an origin server, the user agent sends a Cookie request header to the origin server if it has cookies that are applicable to the request, based on

  * the request-host;
  * the request-URI;
  * the cookie's age.

The syntax for the header is:

cookie = “Cookie:” cookie-version

                           1*((";" | ",") cookie-value)

cookie-value = NAME “=” VALUE [“;” path] [“;” domain] cookie-version = “$Version” “=” value NAME = attr VALUE = value path = “$Path” “=” value domain = “$Domain” “=” value

/\$Version\s*=\s*(.+)\s*[,;]/
CookiePath =
/\$Path/i
CookieDomain =
/\$Domain/i
CTLs =

RFC2068: Hypertext Transfer Protocol — HTTP/1.1 CTL =

                 (octets 0 - 31) and DEL (127)>

token = 1*

tspecials = “(“ | “)” | “<” | “>” | “@“

               | "," | ";" | ":" | "\" | <">
               | "/" | "[" | "]" | "?" | "="
               | "{" | "}" | SP | HT
"[:cntrl:]"
TSpecials =
Regexp.quote ' "(),/:;<=>?@[\\]{}'
NonTokenChar =
/[#{CTLs}#{TSpecials}]/s
HTTPToken =
/\A[^#{CTLs}#{TSpecials}]+\z/s
Seconds =

Number of seconds in the various offset types

{
  's' => 1,
  'm' => 60,
  'h' => 60*60,
  'd' => 60*60*24,
  'M' => 60*60*24*30,
  'y' => 60*60*24*365,
}

Instance Attribute Summary

Class Method Summary

Instance Method Summary

Methods inherited from Object

deprecate_class_method, deprecate_method, inherited

Methods included from Loggable

#log

Constructor Details

- (Cookie) initialize(name, values, options = {})

Create a new Arrow::Cookie object with the specified name and values.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/arrow/cookie.rb', line 145

def initialize( name, values, options={} )
  values = [ values ] unless values.is_a?( Array )
  @name = name
  @values = values

  @domain = nil
  @path = nil
  @secure = false
  @comment = nil
  @max_age = nil
  @expires = nil
  @version = 0
  
  options.each do |meth, val|
    self.__send__( "#{meth}=", val )
  end
end

Instance Attribute Details

- (Object) comment

Because cookies can contain private information about a user, the Cookie attribute allows an origin server to document its intended use of a cookie. The user can inspect the information to decide whether to initiate or continue a session with this cookie.



197
198
199
# File 'lib/arrow/cookie.rb', line 197

def comment
  @comment
end

- (Object) domain

The domain the cookie belongs to



179
180
181
# File 'lib/arrow/cookie.rb', line 179

def domain
  @domain
end

- (Object) expires

The cookie’s expiration (a Time object)



188
189
190
# File 'lib/arrow/cookie.rb', line 188

def expires
  @expires
end

- (Object) max_age

The lifetime of the cookie, in seconds.



191
192
193
# File 'lib/arrow/cookie.rb', line 191

def max_age
  @max_age
end

- (Object) name

The name of the cookie



170
171
172
# File 'lib/arrow/cookie.rb', line 170

def name
  @name
end

- (Object) path

The path the cookie applies to



182
183
184
# File 'lib/arrow/cookie.rb', line 182

def path
  @path
end

- (Object) secure=(value) (writeonly)

The cookie’s ‘secure’ flag.



185
186
187
# File 'lib/arrow/cookie.rb', line 185

def secure=(value)
  @secure = value
end

- (Object) values

The Array of cookie values



173
174
175
# File 'lib/arrow/cookie.rb', line 173

def values
  @values
end

- (Object) version

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



176
177
178
# File 'lib/arrow/cookie.rb', line 176

def version
  @version
end

Class Method Details

+ (Object) dequote(string)

Strip surrounding double quotes from a copy of the specified string and return it.



36
37
38
# File 'lib/arrow/cookie.rb', line 36

def self::dequote( string )
  /^"((?:[^"]+|\\.)*)"/.match( string ) ? $1 : string.dup
end

+ (Object) parse(header)

Parse the specified ‘Cookie:’ header value and return a Hash of one or more new Arrow::Cookie objects, keyed by name.



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
# File 'lib/arrow/cookie.rb', line 90

def self::parse( header )
  return {} if header.nil? or header.empty?
  Arrow::Logger[self].debug "Parsing cookie header: %p" % [ header ]
  cookies = []
  version = 0
  header = header.strip

  # "$Version" = value
  if CookieVersion.match( header )
    Arrow::Logger[self].debug "  Found cookie version %p" % [ $1 ]
    version = Integer( dequote($1) )
    header.slice!( CookieVersion )
  end

  # 1*((";" | ",") NAME "=" VALUE [";" path] [";" domain])
  header.split( /[,;]\s*/ ).each do |pair|
    Arrow::Logger[self].debug "  Found pair %p" % [ pair ]
    key, valstr = pair.split( /=/, 2 ).collect {|s| s.strip }
    
    case key
    when CookiePath
      Arrow::Logger[self].debug "    -> cookie-path %p" % [ valstr ]
      cookies.last.path = dequote( valstr ) unless cookies.empty?

    when CookieDomain
      Arrow::Logger[self].debug "    -> cookie-domain %p" % [ valstr ]
      cookies.last.domain = dequote( valstr ) unless cookies.empty?

    when HTTPToken
      values = parse_valuestring( valstr )
      Arrow::Logger[self].debug "    -> cookie-values %p" % [ values ]
      cookies << new( key, values, :version => version )
      
    else
      Arrow::Logger[self].warning \
        "Malformed cookie header %p: %p is not a valid token; ignoring" %
        [ header, key ]
    end
  end

  # Turn the array into a Hash, ignoring all but the first instance of
  # a cookie with the same name
  return cookies.inject({}) do |hash,cookie|
    hash[cookie.name] = cookie unless hash.key?( cookie.name )
    hash
  end
end

+ (Object) parse_valuestring(valstr)

Parse a cookie value string, returning an Array of Strings



42
43
44
45
46
47
# File 'lib/arrow/cookie.rb', line 42

def self::parse_valuestring( valstr )
  return [] unless valstr
  valstr = dequote( valstr )

  return valstr.split('&').collect{|str| URI.unescape(str) }
end

Instance Method Details

- (Boolean) eql?(other_cookie)

Return true if other_cookie has the same name as the receiver.

Returns:

  • (Boolean)


289
290
291
# File 'lib/arrow/cookie.rb', line 289

def eql?( other_cookie )
  return (self.name == other_cookie.name) ? true : false
end

- (Object) expire!

Set the cookie expiration to a time in the past



265
266
267
# File 'lib/arrow/cookie.rb', line 265

def expire!
  self.expires = Time.at(0)
end

- (Object) hash

Generate a Fixnum hash value for this object. Uses the hash of the cookie’s name.



295
296
297
# File 'lib/arrow/cookie.rb', line 295

def hash
  return self.name.hash
end

- (Boolean) secure?

Returns true if the secure flag is set

Returns:

  • (Boolean)


207
208
209
# File 'lib/arrow/cookie.rb', line 207

def secure?
  return @secure ? true : false
end

- (Object) to_s

Return the cookie as a String



272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/arrow/cookie.rb', line 272

def to_s
  rval = "%s=%s" % [ self.name, make_valuestring(self.values) ]

  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( "Comment", self.comment )
  rval << make_field( "Path", self.path )

  rval << "; " << "Secure" if self.secure?

  return rval
end

- (Object) value

Return the first value stored in the cookie as a String.



201
202
203
# File 'lib/arrow/cookie.rb', line 201

def value
  @values.first
end