http-cookie 1.0.0.pre12 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 = []