Class: HTTP::CookieJar

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/http/cookie_jar.rb,
lib/http/cookie_jar/hash_store.rb,
lib/http/cookie_jar/mozilla_store.rb

Overview

This class is used to manage the Cookies that have been returned from any particular website.

Defined Under Namespace

Classes: AbstractSaver, AbstractStore, CookiestxtSaver, HashStore, MozillaStore, YAMLSaver

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = nil) ⇒ CookieJar

Generates a new cookie jar.

Available option keywords are as below:

:store : The store class that backs this jar. (default: `:hash`) A symbol addressing a store class, a store class, or an instance of a store class is accepted. Symbols are mapped to store classes, like `:hash` to HTTP::CookieJar::HashStore and `:mozilla` to HTTP::CookieJar::MozillaStore.

Any options given are passed through to the initializer of the specified store class. For example, the `:mozilla` (HTTP::CookieJar::MozillaStore) store class requires a `:filename` option. See individual store classes for details.


69
70
71
72
73
74
75
# File 'lib/http/cookie_jar.rb', line 69

def initialize(options = nil)
  opthash = {
    :store => :hash,
  }
  opthash.update(options) if options
  @store = get_impl(AbstractStore, opthash[:store], opthash)
end

Instance Attribute Details

#storeObject (readonly)

Returns the value of attribute store


30
31
32
# File 'lib/http/cookie_jar.rb', line 30

def store
  @store
end

Class Method Details

.const_missing(name) ⇒ Object


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/http/cookie_jar.rb', line 10

def const_missing(name)
  case name.to_s
  when /\A([A-Za-z]+)Store\z/
    file = 'http/cookie_jar/%s_store' % $1.downcase
  when /\A([A-Za-z]+)Saver\z/
    file = 'http/cookie_jar/%s_saver' % $1.downcase
  end
  begin
    require file
  rescue LoadError
    raise NameError, 'can\'t resolve constant %s; failed to load %s' % [name, file]
  end
  if const_defined?(name)
    const_get(name)
  else
    raise NameError, 'can\'t resolve constant %s after loading %s' % [name, file]
  end
end

Instance Method Details

#add(cookie) ⇒ Object Also known as: <<

Adds a cookie to the jar if it is acceptable, and returns self in any case. A given cookie must have domain and path attributes set, or ArgumentError is raised.

Whether a cookie with the `for_domain` flag on overwrites another with the flag off or vice versa depends on the store used. See individual store classes for that matter.

### Compatibility Note for Mechanize::Cookie users

In HTTP::Cookie, each cookie object can store its origin URI (cf. #origin). While the origin URI of a cookie can be set manually by #origin=, one is typically given in its generation. To be more specific, HTTP::Cookie.new takes an `:origin` option and HTTP::Cookie.parse takes one via the second argument.

# Mechanize::Cookie
jar.add(origin, cookie)
jar.add!(cookie)    # no acceptance check is performed

# HTTP::Cookie
jar.origin = origin
jar.add(cookie)     # acceptance check is performed

105
106
107
108
109
110
111
112
113
# File 'lib/http/cookie_jar.rb', line 105

def add(cookie)
  @store.add(cookie) if
    begin
      cookie.acceptable?
    rescue RuntimeError => e
      raise ArgumentError, e.message
    end
  self
end

#cleanup(session = false) ⇒ Object

Removes expired cookies and returns self. If `session` is true, all session cookies are removed as well.


340
341
342
343
# File 'lib/http/cookie_jar.rb', line 340

def cleanup(session = false)
  @store.cleanup session
  self
end

#clearObject

Clears the cookie jar and returns self.


333
334
335
336
# File 'lib/http/cookie_jar.rb', line 333

def clear
  @store.clear
  self
end

#cookies(url = nil) ⇒ Object

Gets an array of cookies sorted by the path and creation time. If `url` is given, only ones that should be sent to the URL/URI are selected, with the access time of each of them updated.


130
131
132
# File 'lib/http/cookie_jar.rb', line 130

def cookies(url = nil)
  each(url).sort
end

#delete(cookie) ⇒ Object

Deletes a cookie that has the same name, domain and path as a given cookie from the jar and returns self.

How the `for_domain` flag value affects the set of deleted cookies depends on the store used. See individual store classes for that matter.


122
123
124
125
# File 'lib/http/cookie_jar.rb', line 122

def delete(cookie)
  @store.delete(cookie)
  self
end

#each(uri = nil, &block) ⇒ Object

Iterates over all cookies that are not expired in no particular order.

An optional argument `uri` specifies a URI/URL indicating the destination of the cookies being selected. Every cookie yielded should be good to send to the given URI, i.e. cookie.valid_for_uri?(uri) evaluates to true.

If (and only if) the `uri` option is given, last access time of each cookie is updated to the current time.


155
156
157
158
159
160
161
162
163
164
165
# File 'lib/http/cookie_jar.rb', line 155

def each(uri = nil, &block) # :yield: cookie
  block_given? or return enum_for(__method__, uri)

  if uri
    uri = URI(uri)
    return self unless URI::HTTP === uri && uri.host
  end

  @store.each(uri, &block)
  self
end

#empty?(url = nil) ⇒ Boolean

Tests if the jar is empty. If `url` is given, tests if there is no cookie for the URL.

Returns:

  • (Boolean)

136
137
138
139
140
141
142
143
# File 'lib/http/cookie_jar.rb', line 136

def empty?(url = nil)
  if url
    each(url) { return false }
    return true
  else
    @store.empty?
  end
end

#initialize_copy(other) ⇒ Object

The copy constructor. Not all backend store classes support cloning.


78
79
80
# File 'lib/http/cookie_jar.rb', line 78

def initialize_copy(other)
  @store = other.instance_eval { @store.dup }
end

#load(readable, *options) ⇒ Object

call-seq:

jar.load(filename_or_io, **options)
jar.load(filename_or_io, format = :yaml, **options)

Loads cookies recorded in a file or an IO in the format specified into the jar and returns self. If a given object responds to #read it is taken as an IO, or taken as a filename otherwise.

Available option keywords are below:

  • `:format`

    Specifies the format for loading.  A saver class, a symbol
    addressing a saver class, or a pre-generated instance of a
    saver class is accepted.
    
    <dl class="rdoc-list note-list">
      <dt>:yaml</dt>
      <dd>YAML structure (default)</dd>
      <dt>:cookiestxt</dt>
      <dd>Mozilla's cookies.txt format</dd>
    </dl>
    

All options given are passed through to the underlying cookie saver module's constructor.


294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/http/cookie_jar.rb', line 294

def load(readable, *options)
  opthash = {
    :format => :yaml,
    :session => false,
  }
  case options.size
  when 0
  when 1
    case options = options.first
    when Symbol
      opthash[:format] = options
    else
      if hash = Hash.try_convert(options)
        opthash.update(hash)
      end
    end
  when 2
    opthash[:format], options = options
    if hash = Hash.try_convert(options)
      opthash.update(hash)
    end
  else
    raise ArgumentError, 'wrong number of arguments (%d for 1-3)' % (1 + options.size)
  end

  saver = get_impl(AbstractSaver, opthash[:format], opthash)

  if readable.respond_to?(:write)
    saver.load(readable, self)
  else
    File.open(readable, 'r') { |io|
      saver.load(io, self)
    }
  end

  self
end

#parse(set_cookie, origin, options = nil) ⇒ Object

Parses a Set-Cookie field value `set_cookie` assuming that it is sent from a source URL/URI `origin`, and adds the cookies parsed as valid and considered acceptable to the jar. Returns an array of cookies that have been added.

If a block is given, it is called for each cookie and the cookie is added only if the block returns a true value.

`jar.parse(set_cookie, origin)` is a shorthand for this:

HTTP::Cookie.parse(set_cookie, origin) { |cookie|
  jar.add(cookie)
}

See HTTP::Cookie.parse for available options.


183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/http/cookie_jar.rb', line 183

def parse(set_cookie, origin, options = nil) # :yield: cookie
  if block_given?
    HTTP::Cookie.parse(set_cookie, origin, options).tap { |cookies|
      cookies.select! { |cookie|
        yield(cookie) && add(cookie)
      }
    }
  else
    HTTP::Cookie.parse(set_cookie, origin, options) { |cookie|
      add(cookie)
    }
  end
end

#save(writable, *options) ⇒ Object

call-seq:

jar.save(filename_or_io, **options)
jar.save(filename_or_io, format = :yaml, **options)

Saves the cookie jar into a file or an IO in the format specified and returns self. If a given object responds to #write it is taken as an IO, or taken as a filename otherwise.

Available option keywords are below:

  • `:format`

    Specifies the format for saving.  A saver class, a symbol
    addressing a saver class, or a pre-generated instance of a
    saver class is accepted.
    
    <dl class="rdoc-list note-list">
      <dt>:yaml</dt>
      <dd>YAML structure (default)</dd>
      <dt>:cookiestxt</dt>
      <dd>Mozilla's cookies.txt format</dd>
    </dl>
    
  • `:session`

    <dl class="rdoc-list note-list">
      <dt>true</dt>
      <dd>Save session cookies as well.</dd>
      <dt>false</dt>
      <dd>Do not save session cookies. (default)</dd>
    </dl>
    

All options given are passed through to the underlying cookie saver module's constructor.


231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/http/cookie_jar.rb', line 231

def save(writable, *options)
  opthash = {
    :format => :yaml,
    :session => false,
  }
  case options.size
  when 0
  when 1
    case options = options.first
    when Symbol
      opthash[:format] = options
    else
      if hash = Hash.try_convert(options)
        opthash.update(hash)
      end
    end
  when 2
    opthash[:format], options = options
    if hash = Hash.try_convert(options)
      opthash.update(hash)
    end
  else
    raise ArgumentError, 'wrong number of arguments (%d for 1-3)' % (1 + options.size)
  end

  saver = get_impl(AbstractSaver, opthash[:format], opthash)

  if writable.respond_to?(:write)
    saver.save(writable, self)
  else
    File.open(writable, 'w') { |io|
      saver.save(io, self)
    }
  end

  self
end