Class: CookieJar::Jar

Inherits:
Object
  • Object
show all
Defined in:
lib/cookiejar/jar.rb

Overview

A cookie store for client side usage.

  • Enforces cookie validity rules

  • Returns just the cookies valid for a given URI

  • Handles expiration of cookies

  • Allows for persistence of cookie data (with or without session)

– Internal format:

Internally, the data structure is a set of nested hashes. Domain Level: At the domain level, the hashes are of individual domains, down-cased and without any leading period. For instance, imagine cookies for .foo.com, .bar.com, and .auth.bar.com:

{

"foo.com"      : <host data>,
"bar.com"      : <host data>,
"auth.bar.com" : <host data>

} Lookups are done both for the matching entry, and for an entry without the first segment up to the dot, ie. for /^.?[^.]+.(.*)$/. A lookup of auth.bar.com would match both bar.com and auth.bar.com, but not entries for com or www.auth.bar.com.

Host Level: Entries are in an hash, with keys of the path and values of a hash of cookie names to cookie object

"/" : {"session" : <Cookie>, "cart_id" : <Cookie>
"/protected" : : <Cookie>

}

Paths are given a straight prefix string comparison to match. Further filters <secure, http only, ports> are not represented in this heirarchy.

Cookies returned are ordered solely by specificity (length) of the path.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeJar

Returns a new instance of Jar.



45
46
47
# File 'lib/cookiejar/jar.rb', line 45

def initialize
 @domains = {}
end

Class Method Details

.from_a(cookies) ⇒ Object

Create a new Jar from an array of Cookie objects



96
97
98
99
100
101
102
# File 'lib/cookiejar/jar.rb', line 96

def self.from_a cookies
  jar = new
  cookies.each do |cookie|
    jar.add_cookie cookie
  end
  jar
end

.json_create(o) ⇒ Object

Create a new Jar from a JSON-backed hash.



85
86
87
88
89
90
91
92
93
# File 'lib/cookiejar/jar.rb', line 85

def self.json_create o
  if o.is_a? Hash
    o = o['cookies']
  end
  cookies = o.inject [] do |result, cookie_json|
    result << (Cookie.json_create cookie_json)
  end
  self.from_a cookies
end

Instance Method Details

Add a pre-existing cookie object to the jar.



60
61
62
63
64
# File 'lib/cookiejar/jar.rb', line 60

def add_cookie cookie
   domain_paths = find_or_add_domain_for_cookie cookie
  add_cookie_to_path domain_paths, cookie
  cookie
end

#expire_cookies(session = false) ⇒ Object

Look through the jar for any cookies which have passed their expiration date. Optionally, you can pass true to expire any session cookies as well



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/cookiejar/jar.rb', line 107

def expire_cookies session = false
  @domains.delete_if do |domain, paths|
    paths.delete_if do |path, cookies|
      cookies.delete_if do |cookie_name, cookie|
        cookie.is_expired? || (session && cookie.is_session?)
      end
      cookies.empty?
    end
    paths.empty?
  end
end

Given a request URI, return a string Cookie header.Cookies will be in order per RFC 2965 - sorted by longest path length, but otherwise unordered.

optional arguments are

  • :script - if set, cookies set to be HTTP-only will be ignored



152
153
154
155
156
157
# File 'lib/cookiejar/jar.rb', line 152

def get_cookie_header request_uri, args = { }
	cookies = get_cookies request_uri, args
	cookies.map do |cookie|
	  cookie.to_s
 end.join ";"
end

#get_cookies(request_uri, args = { }) ⇒ Object

Given a request URI, return a sorted list of Cookie objects. Cookies will be in order per RFC 2965 - sorted by longest path length, but otherwise unordered.

optional arguments are

  • :script - if set, cookies set to be HTTP-only will be ignored



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/cookiejar/jar.rb', line 125

def get_cookies request_uri, args = { }
 uri = to_uri request_uri
	hosts = Cookie.compute_search_domains uri
	
	results = []
	hosts.each do |host|
	  domain = find_domain host
	  domain.each do |path, cookies|
		  if uri.path.start_with? path
  		  results += cookies.values.select do |cookie|
    			cookie.should_send? uri, args[:script]
    		end
    	end
  	end
  end
	#Sort by path length, longest first
	results.sort do |lhs, rhs|
	  rhs.path.length <=> lhs.path.length
	end
end

Given a request URI and a literal Set-Cookie header value, attempt to add the cookie to the cookie store.

Returns the Cookie object on success, otherwise raises an InvalidCookieError



54
55
56
57
# File 'lib/cookiejar/jar.rb', line 54

def set_cookie request_uri, cookie_header_value
	cookie = Cookie.from_set_cookie request_uri, cookie_header_value
	add_cookie cookie
end

#to_aObject

Return an array of all cookie objects in the jar



67
68
69
70
71
72
73
74
75
# File 'lib/cookiejar/jar.rb', line 67

def to_a
  result = []
  @domains.values.each do |paths|
    paths.values.each do |cookies|
      cookies.values.inject result, :<<
    end
   end
   result
end

#to_json(*a) ⇒ Object



77
78
79
80
81
82
# File 'lib/cookiejar/jar.rb', line 77

def to_json *a
 {
   'json_class' => self.class.name,
   'cookies' => (to_a.to_json *a)
  }.to_json *a
end