http-cookie 1.0.0.pre12 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  module HTTP
2
2
  class Cookie
3
- VERSION = "1.0.0.pre12"
3
+ VERSION = "1.0.4"
4
4
  end
5
5
  end
@@ -6,9 +6,6 @@ require 'http/cookie'
6
6
  # any particular website.
7
7
 
8
8
  class HTTP::CookieJar
9
- require 'http/cookie_jar/abstract_store'
10
- require 'http/cookie_jar/abstract_saver'
11
-
12
9
  class << self
13
10
  def const_missing(name)
14
11
  case name.to_s
@@ -19,7 +16,7 @@ class HTTP::CookieJar
19
16
  end
20
17
  begin
21
18
  require file
22
- rescue LoadError => e
19
+ rescue LoadError
23
20
  raise NameError, 'can\'t resolve constant %s; failed to load %s' % [name, file]
24
21
  end
25
22
  if const_defined?(name)
@@ -32,16 +29,38 @@ class HTTP::CookieJar
32
29
 
33
30
  attr_reader :store
34
31
 
32
+ def get_impl(base, value, *args)
33
+ case value
34
+ when base
35
+ value
36
+ when Symbol
37
+ begin
38
+ base.implementation(value).new(*args)
39
+ rescue IndexError => e
40
+ raise ArgumentError, e.message
41
+ end
42
+ when Class
43
+ if base >= value
44
+ value.new(*args)
45
+ else
46
+ raise TypeError, 'not a subclass of %s: %s' % [base, value]
47
+ end
48
+ else
49
+ raise TypeError, 'invalid object: %s' % value.inspect
50
+ end
51
+ end
52
+ private :get_impl
53
+
35
54
  # Generates a new cookie jar.
36
55
  #
37
56
  # Available option keywords are as below:
38
57
  #
39
58
  # :store
40
59
  # : The store class that backs this jar. (default: `:hash`)
41
- # A symbol or an instance of a store class is accepted. Symbols are
42
- # mapped to store classes, like `:hash` to
43
- # HTTP::CookieJar::HashStore and `:mozilla` to
44
- # HTTP::CookieJar::MozillaStore.
60
+ # A symbol addressing a store class, a store class, or an instance
61
+ # of a store class is accepted. Symbols are mapped to store
62
+ # classes, like `:hash` to HTTP::CookieJar::HashStore and `:mozilla`
63
+ # to HTTP::CookieJar::MozillaStore.
45
64
  #
46
65
  # Any options given are passed through to the initializer of the
47
66
  # specified store class. For example, the `:mozilla`
@@ -52,16 +71,10 @@ class HTTP::CookieJar
52
71
  :store => :hash,
53
72
  }
54
73
  opthash.update(options) if options
55
- case store = opthash[:store]
56
- when Symbol
57
- @store = AbstractStore.implementation(store).new(opthash)
58
- when AbstractStore
59
- @store = store
60
- else
61
- raise TypeError, 'wrong object given as cookie store: %s' % store.inspect
62
- end
74
+ @store = get_impl(AbstractStore, opthash[:store], opthash)
63
75
  end
64
76
 
77
+ # The copy constructor. Not all backend store classes support cloning.
65
78
  def initialize_copy(other)
66
79
  @store = other.instance_eval { @store.dup }
67
80
  end
@@ -94,7 +107,7 @@ class HTTP::CookieJar
94
107
  begin
95
108
  cookie.acceptable?
96
109
  rescue RuntimeError => e
97
- raise ArgumentError, e.message
110
+ raise ArgumentError, e.message
98
111
  end
99
112
  self
100
113
  end
@@ -139,7 +152,7 @@ class HTTP::CookieJar
139
152
  #
140
153
  # If (and only if) the `uri` option is given, last access time of
141
154
  # each cookie is updated to the current time.
142
- def each(uri = nil, &block)
155
+ def each(uri = nil, &block) # :yield: cookie
143
156
  block_given? or return enum_for(__method__, uri)
144
157
 
145
158
  if uri
@@ -193,6 +206,10 @@ class HTTP::CookieJar
193
206
  #
194
207
  # * `:format`
195
208
  #
209
+ # Specifies the format for saving. A saver class, a symbol
210
+ # addressing a saver class, or a pre-generated instance of a
211
+ # saver class is accepted.
212
+ #
196
213
  # <dl class="rdoc-list note-list">
197
214
  # <dt>:yaml</dt>
198
215
  # <dd>YAML structure (default)</dd>
@@ -210,7 +227,7 @@ class HTTP::CookieJar
210
227
  # </dl>
211
228
  #
212
229
  # All options given are passed through to the underlying cookie
213
- # saver module.
230
+ # saver module's constructor.
214
231
  def save(writable, *options)
215
232
  opthash = {
216
233
  :format => :yaml,
@@ -223,20 +240,20 @@ class HTTP::CookieJar
223
240
  when Symbol
224
241
  opthash[:format] = options
225
242
  else
226
- opthash.update(options) if options
243
+ if hash = Hash.try_convert(options)
244
+ opthash.update(hash)
245
+ end
227
246
  end
228
247
  when 2
229
248
  opthash[:format], options = options
230
- opthash.update(options) if options
249
+ if hash = Hash.try_convert(options)
250
+ opthash.update(hash)
251
+ end
231
252
  else
232
253
  raise ArgumentError, 'wrong number of arguments (%d for 1-3)' % (1 + options.size)
233
254
  end
234
255
 
235
- begin
236
- saver = AbstractSaver.implementation(opthash[:format]).new(opthash)
237
- rescue IndexError => e
238
- raise ArgumentError, e.message
239
- end
256
+ saver = get_impl(AbstractSaver, opthash[:format], opthash)
240
257
 
241
258
  if writable.respond_to?(:write)
242
259
  saver.save(writable, self)
@@ -261,6 +278,10 @@ class HTTP::CookieJar
261
278
  #
262
279
  # * `:format`
263
280
  #
281
+ # Specifies the format for loading. A saver class, a symbol
282
+ # addressing a saver class, or a pre-generated instance of a
283
+ # saver class is accepted.
284
+ #
264
285
  # <dl class="rdoc-list note-list">
265
286
  # <dt>:yaml</dt>
266
287
  # <dd>YAML structure (default)</dd>
@@ -269,7 +290,7 @@ class HTTP::CookieJar
269
290
  # </dl>
270
291
  #
271
292
  # All options given are passed through to the underlying cookie
272
- # saver module.
293
+ # saver module's constructor.
273
294
  def load(readable, *options)
274
295
  opthash = {
275
296
  :format => :yaml,
@@ -282,20 +303,20 @@ class HTTP::CookieJar
282
303
  when Symbol
283
304
  opthash[:format] = options
284
305
  else
285
- opthash.update(options) if options
306
+ if hash = Hash.try_convert(options)
307
+ opthash.update(hash)
308
+ end
286
309
  end
287
310
  when 2
288
311
  opthash[:format], options = options
289
- opthash.update(options) if options
312
+ if hash = Hash.try_convert(options)
313
+ opthash.update(hash)
314
+ end
290
315
  else
291
316
  raise ArgumentError, 'wrong number of arguments (%d for 1-3)' % (1 + options.size)
292
317
  end
293
318
 
294
- begin
295
- saver = AbstractSaver.implementation(opthash[:format]).new(opthash)
296
- rescue IndexError => e
297
- raise ArgumentError, e.message
298
- end
319
+ saver = get_impl(AbstractSaver, opthash[:format], opthash)
299
320
 
300
321
  if readable.respond_to?(:write)
301
322
  saver.load(readable, self)
@@ -314,7 +335,8 @@ class HTTP::CookieJar
314
335
  self
315
336
  end
316
337
 
317
- # Removes expired cookies and returns self.
338
+ # Removes expired cookies and returns self. If `session` is true,
339
+ # all session cookies are removed as well.
318
340
  def cleanup(session = false)
319
341
  @store.cleanup session
320
342
  self
@@ -1,3 +1,6 @@
1
+ # :markup: markdown
2
+
3
+ # An abstract superclass for all saver classes.
1
4
  class HTTP::CookieJar::AbstractSaver
2
5
  class << self
3
6
  @@class_map = {}
@@ -16,20 +19,25 @@ class HTTP::CookieJar::AbstractSaver
16
19
  end
17
20
  end
18
21
 
19
- def inherited(subclass)
22
+ def inherited(subclass) # :nodoc:
20
23
  @@class_map[class_to_symbol(subclass)] = subclass
21
24
  end
22
25
 
23
- def class_to_symbol(klass)
26
+ def class_to_symbol(klass) # :nodoc:
24
27
  klass.name[/[^:]+?(?=Saver$|$)/].downcase.to_sym
25
28
  end
26
29
  end
27
30
 
31
+ # Defines options and their default values.
28
32
  def default_options
29
33
  # {}
30
34
  end
31
35
  private :default_options
32
36
 
37
+ # :call-seq:
38
+ # new(**options)
39
+ #
40
+ # Called by the constructor of each subclass using super().
33
41
  def initialize(options = nil)
34
42
  options ||= {}
35
43
  @logger = options[:logger]
@@ -41,10 +49,16 @@ class HTTP::CookieJar::AbstractSaver
41
49
  }
42
50
  end
43
51
 
52
+ # Implements HTTP::CookieJar#save().
53
+ #
54
+ # This is an abstract method that each subclass must override.
44
55
  def save(io, jar)
45
56
  # self
46
57
  end
47
58
 
59
+ # Implements HTTP::CookieJar#load().
60
+ #
61
+ # This is an abstract method that each subclass must override.
48
62
  def load(io, jar)
49
63
  # self
50
64
  end
@@ -1,5 +1,7 @@
1
+ # :markup: markdown
1
2
  require 'monitor'
2
3
 
4
+ # An abstract superclass for all store classes.
3
5
  class HTTP::CookieJar::AbstractStore
4
6
  include MonitorMixin
5
7
 
@@ -15,25 +17,30 @@ class HTTP::CookieJar::AbstractStore
15
17
  begin
16
18
  require 'http/cookie_jar/%s_store' % symbol
17
19
  @@class_map.fetch(symbol)
18
- rescue LoadError, IndexError
19
- raise IndexError, 'cookie store unavailable: %s' % symbol.inspect
20
+ rescue LoadError, IndexError => e
21
+ raise IndexError, 'cookie store unavailable: %s, error: %s' % symbol.inspect, e.message
20
22
  end
21
23
  end
22
24
 
23
- def inherited(subclass)
25
+ def inherited(subclass) # :nodoc:
24
26
  @@class_map[class_to_symbol(subclass)] = subclass
25
27
  end
26
28
 
27
- def class_to_symbol(klass)
29
+ def class_to_symbol(klass) # :nodoc:
28
30
  klass.name[/[^:]+?(?=Store$|$)/].downcase.to_sym
29
31
  end
30
32
  end
31
33
 
34
+ # Defines options and their default values.
32
35
  def default_options
33
36
  # {}
34
37
  end
35
38
  private :default_options
36
39
 
40
+ # :call-seq:
41
+ # new(**options)
42
+ #
43
+ # Called by the constructor of each subclass using super().
37
44
  def initialize(options = nil)
38
45
  super() # MonitorMixin
39
46
  options ||= {}
@@ -45,14 +52,21 @@ class HTTP::CookieJar::AbstractStore
45
52
  }
46
53
  end
47
54
 
55
+ # This is an abstract method that each subclass must override.
48
56
  def initialize_copy(other)
49
57
  # self
50
58
  end
51
59
 
60
+ # Implements HTTP::CookieJar#add().
61
+ #
62
+ # This is an abstract method that each subclass must override.
52
63
  def add(cookie)
53
64
  # self
54
65
  end
55
66
 
67
+ # Implements HTTP::CookieJar#delete().
68
+ #
69
+ # This is an abstract method that each subclass must override.
56
70
  def delete(cookie)
57
71
  # self
58
72
  end
@@ -66,7 +80,9 @@ class HTTP::CookieJar::AbstractStore
66
80
  #
67
81
  # If (and only if) the +uri+ option is given, last access time of
68
82
  # each cookie is updated to the current time.
69
- def each(uri = nil, &block)
83
+ #
84
+ # This is an abstract method that each subclass must override.
85
+ def each(uri = nil, &block) # :yield: cookie
70
86
  # if uri
71
87
  # ...
72
88
  # else
@@ -78,14 +94,22 @@ class HTTP::CookieJar::AbstractStore
78
94
  end
79
95
  include Enumerable
80
96
 
97
+ # Implements HTTP::CookieJar#empty?().
81
98
  def empty?
82
- # true or false
99
+ each { return false }
100
+ true
83
101
  end
84
102
 
103
+ # Implements HTTP::CookieJar#clear().
104
+ #
105
+ # This is an abstract method that each subclass must override.
85
106
  def clear
86
107
  # self
87
108
  end
88
109
 
110
+ # Implements HTTP::CookieJar#cleanup().
111
+ #
112
+ # This is an abstract method that each subclass must override.
89
113
  def cleanup(session = false)
90
114
  # if session
91
115
  # select { |cookie| cookie.session? || cookie.expired? }
@@ -1,9 +1,25 @@
1
+ # :markup: markdown
1
2
  require 'http/cookie_jar'
2
3
 
3
4
  # CookiestxtSaver saves and loads cookies in the cookies.txt format.
4
5
  class HTTP::CookieJar::CookiestxtSaver < HTTP::CookieJar::AbstractSaver
5
- True = "TRUE"
6
- False = "FALSE"
6
+ # :singleton-method: new
7
+ # :call-seq:
8
+ # new(**options)
9
+ #
10
+ # Available option keywords are below:
11
+ #
12
+ # * `:header`
13
+ #
14
+ # Specifies the header line not including a line feed, which is
15
+ # only used by #save(). None is output if nil is
16
+ # given. (default: `"# HTTP Cookie File"`)
17
+ #
18
+ # * `:linefeed`
19
+ #
20
+ # Specifies the line separator (default: `"\n"`).
21
+
22
+ ##
7
23
 
8
24
  def save(io, jar)
9
25
  io.puts @header if @header
@@ -28,8 +44,13 @@ class HTTP::CookieJar::CookiestxtSaver < HTTP::CookieJar::AbstractSaver
28
44
  }
29
45
  end
30
46
 
47
+ # :stopdoc:
48
+ True = "TRUE"
49
+ False = "FALSE"
50
+
31
51
  HTTPONLY_PREFIX = '#HttpOnly_'
32
52
  RE_HTTPONLY_PREFIX = /\A#{HTTPONLY_PREFIX}/
53
+ # :startdoc:
33
54
 
34
55
  # Serializes the cookie into a cookies.txt line.
35
56
  def cookie_to_record(cookie)
@@ -1,13 +1,6 @@
1
+ # :markup: markdown
1
2
  require 'http/cookie_jar'
2
3
 
3
- # :stopdoc:
4
- class Array
5
- def sort_by!(&block)
6
- replace(sort_by(&block))
7
- end unless method_defined?(:sort_by!)
8
- end
9
- # :startdoc:
10
-
11
4
  class HTTP::CookieJar
12
5
  # A store class that uses a hash-based cookie store.
13
6
  #
@@ -26,6 +19,9 @@ class HTTP::CookieJar
26
19
  }
27
20
  end
28
21
 
22
+ # :call-seq:
23
+ # new(**options)
24
+ #
29
25
  # Generates a hash based cookie store.
30
26
  #
31
27
  # Available option keywords are as below:
@@ -50,6 +46,7 @@ class HTTP::CookieJar
50
46
  @gc_index = 0
51
47
  end
52
48
 
49
+ # The copy constructor. This store class supports cloning.
53
50
  def initialize_copy(other)
54
51
  @jar = Marshal.load(Marshal.dump(other.instance_variable_get(:@jar)))
55
52
  end
@@ -67,13 +64,11 @@ class HTTP::CookieJar
67
64
  self
68
65
  end
69
66
 
70
- def each(uri = nil)
67
+ def each(uri = nil) # :yield: cookie
71
68
  now = Time.now
72
69
  if uri
73
- thost = DomainName.new(uri.host)
74
70
  tpath = uri.path
75
71
  @jar.each { |domain, paths|
76
- next unless thost.cookie_domain?(domain)
77
72
  paths.each { |path, hash|
78
73
  next unless HTTP::Cookie.path_match?(path, tpath)
79
74
  hash.delete_if { |name, cookie|
@@ -113,10 +108,6 @@ class HTTP::CookieJar
113
108
  self
114
109
  end
115
110
 
116
- def empty?
117
- @jar.empty?
118
- end
119
-
120
111
  def cleanup(session = false)
121
112
  now = Time.now
122
113
  all_cookies = []