http-cookie 1.0.0.pre11 → 1.0.0.pre12

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 74a442b5c8222376568f11b2ed2f3ff948cb297a
4
- data.tar.gz: 27b3d634fdd2e75bff0302f89463b5ed777e936f
3
+ metadata.gz: 2a70ec83e62018ae7621d1eb7ba75f08eea1d696
4
+ data.tar.gz: 9ed2b81801d89bb7adf3f6d97b087421406f4acf
5
5
  SHA512:
6
- metadata.gz: 48ee26913f44add403e4d620e75b6f64156efaf23b37ab30e7c10543bd765a12adaeb25ff7f6c666410b82d291457f049d718ae4d802906be53db5a28638b89c
7
- data.tar.gz: 7703dd086e0802411ab9e7ee9c12278a3321a41a0fcecdb203a6de3e2848c5c73e6e5a4141ccb01f65e165e1f80a3c8b3ea1a60be3505bb5ea1bcfa2bf55fc59
6
+ metadata.gz: f1ba260a8757b9076df6645368f761005cc665ef1c4ae357f102982132ed66253ae7cb49d163430bd3070225524c0cd4a988b2abbc4252e3e68e8376eea68542
7
+ data.tar.gz: bca8c545043e5b4975e32350dcf37f1519a183e3d207bb2692313863104884750ef656ed568106b69beab35e53b0536c36b677846255b1d477af95d022c74bfe
@@ -344,8 +344,8 @@ class HTTP::Cookie
344
344
 
345
345
  # See #name.
346
346
  def name=(name)
347
- name = String.try_convert(name) or
348
- raise TypeError, "#{name.class} is not a String"
347
+ name = (String.try_convert(name) or
348
+ raise TypeError, "#{name.class} is not a String")
349
349
  if name.empty?
350
350
  raise ArgumentError, "cookie name cannot be empty"
351
351
  elsif name.match(/[\x00-\x20\x7F,;\\"=]/)
@@ -365,8 +365,8 @@ class HTTP::Cookie
365
365
  self.expires = UNIX_EPOCH
366
366
  return @value = ''
367
367
  end
368
- value = String.try_convert(value) or
369
- raise TypeError, "#{value.class} is not a String"
368
+ value = (String.try_convert(value) or
369
+ raise TypeError, "#{value.class} is not a String")
370
370
  if value.match(/[\x00-\x1F\x7F]/)
371
371
  raise ArgumentError, "invalid cookie value"
372
372
  end
@@ -393,8 +393,8 @@ class HTTP::Cookie
393
393
  when DomainName
394
394
  @domain_name = domain
395
395
  else
396
- domain = String.try_convert(domain) or
397
- raise TypeError, "#{domain.class} is not a String"
396
+ domain = (String.try_convert(domain) or
397
+ raise TypeError, "#{domain.class} is not a String")
398
398
  if domain.start_with?('.')
399
399
  for_domain = true
400
400
  domain = domain[1..-1]
@@ -438,8 +438,8 @@ class HTTP::Cookie
438
438
 
439
439
  # See #path.
440
440
  def path=(path)
441
- path = String.try_convert(path) or
442
- raise TypeError, "#{path.class} is not a String"
441
+ path = (String.try_convert(path) or
442
+ raise TypeError, "#{path.class} is not a String")
443
443
  @path = path.start_with?('/') ? path : '/'
444
444
  end
445
445
 
@@ -564,9 +564,9 @@ class HTTP::Cookie
564
564
  def acceptable?
565
565
  case
566
566
  when @domain.nil?
567
- raise ArgumentError, "domain is missing"
567
+ raise "domain is missing"
568
568
  when @path.nil?
569
- raise ArgumentError, "path is missing"
569
+ raise "path is missing"
570
570
  when @origin.nil?
571
571
  true
572
572
  else
@@ -574,8 +574,8 @@ class HTTP::Cookie
574
574
  end
575
575
  end
576
576
 
577
- # Tests if it is OK to send this cookie to a given `uri`. A runtime
578
- # error is raised if the cookie's domain is unknown.
577
+ # Tests if it is OK to send this cookie to a given `uri`. A
578
+ # RuntimeError is raised if the cookie's domain is unknown.
579
579
  def valid_for_uri?(uri)
580
580
  if @domain.nil?
581
581
  raise "cannot tell if this cookie is valid because the domain is unknown"
@@ -1,5 +1,5 @@
1
1
  module HTTP
2
2
  class Cookie
3
- VERSION = "1.0.0.pre11"
3
+ VERSION = "1.0.0.pre12"
4
4
  end
5
5
  end
@@ -9,6 +9,27 @@ class HTTP::CookieJar
9
9
  require 'http/cookie_jar/abstract_store'
10
10
  require 'http/cookie_jar/abstract_saver'
11
11
 
12
+ class << self
13
+ def const_missing(name)
14
+ case name.to_s
15
+ when /\A([A-Za-z]+)Store\z/
16
+ file = 'http/cookie_jar/%s_store' % $1.downcase
17
+ when /\A([A-Za-z]+)Saver\z/
18
+ file = 'http/cookie_jar/%s_saver' % $1.downcase
19
+ end
20
+ begin
21
+ require file
22
+ rescue LoadError => e
23
+ raise NameError, 'can\'t resolve constant %s; failed to load %s' % [name, file]
24
+ end
25
+ if const_defined?(name)
26
+ const_get(name)
27
+ else
28
+ raise NameError, 'can\'t resolve constant %s after loading %s' % [name, file]
29
+ end
30
+ end
31
+ end
32
+
12
33
  attr_reader :store
13
34
 
14
35
  # Generates a new cookie jar.
@@ -69,7 +90,12 @@ class HTTP::CookieJar
69
90
  # jar.origin = origin
70
91
  # jar.add(cookie) # acceptance check is performed
71
92
  def add(cookie)
72
- @store.add(cookie) if cookie.acceptable?
93
+ @store.add(cookie) if
94
+ begin
95
+ cookie.acceptable?
96
+ rescue RuntimeError => e
97
+ raise ArgumentError, e.message
98
+ end
73
99
  self
74
100
  end
75
101
  alias << add
@@ -26,7 +26,7 @@ class HTTP::CookieJar::AbstractSaver
26
26
  end
27
27
 
28
28
  def default_options
29
- {}
29
+ # {}
30
30
  end
31
31
  private :default_options
32
32
 
@@ -42,10 +42,10 @@ class HTTP::CookieJar::AbstractSaver
42
42
  end
43
43
 
44
44
  def save(io, jar)
45
- raise
45
+ # self
46
46
  end
47
47
 
48
48
  def load(io, jar)
49
- raise
49
+ # self
50
50
  end
51
51
  end
@@ -30,7 +30,7 @@ class HTTP::CookieJar::AbstractStore
30
30
  end
31
31
 
32
32
  def default_options
33
- {}
33
+ # {}
34
34
  end
35
35
  private :default_options
36
36
 
@@ -46,18 +46,15 @@ class HTTP::CookieJar::AbstractStore
46
46
  end
47
47
 
48
48
  def initialize_copy(other)
49
- raise
50
- self
49
+ # self
51
50
  end
52
51
 
53
52
  def add(cookie)
54
- raise
55
- self
53
+ # self
56
54
  end
57
55
 
58
56
  def delete(cookie)
59
- raise
60
- self
57
+ # self
61
58
  end
62
59
 
63
60
  # Iterates over all cookies that are not expired.
@@ -70,35 +67,34 @@ class HTTP::CookieJar::AbstractStore
70
67
  # If (and only if) the +uri+ option is given, last access time of
71
68
  # each cookie is updated to the current time.
72
69
  def each(uri = nil, &block)
73
- if uri
74
- raise
75
- else
76
- synchronize {
77
- raise
78
- }
79
- end
80
- self
70
+ # if uri
71
+ # ...
72
+ # else
73
+ # synchronize {
74
+ # ...
75
+ # }
76
+ # end
77
+ # self
81
78
  end
82
79
  include Enumerable
83
80
 
84
81
  def empty?
85
- raise
82
+ # true or false
86
83
  end
87
84
 
88
85
  def clear
89
- raise
90
- self
86
+ # self
91
87
  end
92
88
 
93
89
  def cleanup(session = false)
94
- if session
95
- select { |cookie| cookie.session? || cookie.expired? }
96
- else
97
- select(&:expired?)
98
- end.each { |cookie|
99
- delete(cookie)
100
- }
101
- # subclasses can optionally remove over-the-limit cookies.
102
- self
90
+ # if session
91
+ # select { |cookie| cookie.session? || cookie.expired? }
92
+ # else
93
+ # select(&:expired?)
94
+ # end.each { |cookie|
95
+ # delete(cookie)
96
+ # }
97
+ # # subclasses can optionally remove over-the-limit cookies.
98
+ # self
103
99
  end
104
100
  end
@@ -9,6 +9,7 @@ class HTTP::CookieJar
9
9
  # Session cookies are stored separately on memory and will not be
10
10
  # stored persistently in the SQLite3 database.
11
11
  class MozillaStore < AbstractStore
12
+ # :stopdoc:
12
13
  SCHEMA_VERSION = 5
13
14
 
14
15
  def default_options
@@ -32,6 +33,41 @@ class HTTP::CookieJar
32
33
  appId inBrowserElement
33
34
  ]
34
35
 
36
+ SQL = {}
37
+
38
+ Callable = proc { |obj, meth, *args|
39
+ proc {
40
+ obj.__send__(meth, *args)
41
+ }
42
+ }
43
+
44
+ class Database < SQLite3::Database
45
+ def initialize(file, options = {})
46
+ @stmts = []
47
+ options = {
48
+ :results_as_hash => true,
49
+ }.update(options)
50
+ super
51
+ end
52
+
53
+ def prepare(sql)
54
+ case st = super
55
+ when SQLite3::Statement
56
+ @stmts << st
57
+ end
58
+ st
59
+ end
60
+
61
+ def close
62
+ return self if closed?
63
+ @stmts.reject! { |st|
64
+ st.closed? || st.close
65
+ }
66
+ super
67
+ end
68
+ end
69
+ # :startdoc:
70
+
35
71
  # Generates a Mozilla cookie store. If the file does not exist,
36
72
  # it is created. If it does and its schema is old, it is
37
73
  # automatically upgraded with a new schema keeping the existing
@@ -58,22 +94,32 @@ class HTTP::CookieJar
58
94
 
59
95
  @filename = options[:filename] or raise ArgumentError, ':filename option is missing'
60
96
 
61
- @sjar = HashStore.new
62
- @db = SQLite3::Database.new(@filename)
63
- @db.results_as_hash = true
97
+ @sjar = HTTP::CookieJar::HashStore.new
98
+
99
+ @db = Database.new(@filename)
100
+
101
+ @stmt = Hash.new { |st, key|
102
+ st[key] = @db.prepare(SQL[key])
103
+ }
104
+
105
+ ObjectSpace.define_finalizer(self, Callable[@db, :close])
64
106
 
65
107
  upgrade_database
66
108
 
67
109
  @gc_index = 0
68
110
  end
69
111
 
112
+ def initialize_copy(other)
113
+ raise TypeError, 'can\'t clone %s' % self.class
114
+ end
115
+
70
116
  # The file name of the SQLite3 database given in initialization.
71
117
  attr_reader :filename
72
118
 
73
119
  # Closes the SQLite3 database. After closing, any operation may
74
120
  # raise an error.
75
121
  def close
76
- @db.close
122
+ @db.closed? || @db.close
77
123
  self
78
124
  end
79
125
 
@@ -126,6 +172,13 @@ class HTTP::CookieJar
126
172
  SQL
127
173
  end
128
174
 
175
+ def db_prepare(sql)
176
+ st = @db.prepare(sql)
177
+ yield st
178
+ ensure
179
+ st.close if st
180
+ end
181
+
129
182
  def upgrade_database
130
183
  loop {
131
184
  case schema_version
@@ -138,28 +191,28 @@ class HTTP::CookieJar
138
191
  when 2
139
192
  @db.execute("ALTER TABLE moz_cookies ADD baseDomain TEXT")
140
193
 
141
- st_update = @db.prepare("UPDATE moz_cookies SET baseDomain = :baseDomain WHERE id = :id")
142
-
143
- @db.execute("SELECT id, host FROM moz_cookies") { |row|
144
- domain_name = DomainName.new(row[:host])
145
- domain = domain_name.domain || domain_name.hostname
146
- st_update.execute(:baseDomain => domain, :id => row[:id])
194
+ db_prepare("UPDATE moz_cookies SET baseDomain = :baseDomain WHERE id = :id") { |st_update|
195
+ @db.execute("SELECT id, host FROM moz_cookies") { |row|
196
+ domain_name = DomainName.new(row['host'][/\A\.?(.*)/, 1])
197
+ domain = domain_name.domain || domain_name.hostname
198
+ st_update.execute(:baseDomain => domain, :id => row['id'])
199
+ }
147
200
  }
148
201
 
149
202
  @db.execute("CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)")
150
203
  self.schema_version += 1
151
204
  when 3
152
- st_delete = @db.prepare("DELETE FROM moz_cookies WHERE id = :id")
153
-
154
- prev_row = nil
155
- @db.execute(<<-'SQL') { |row|
156
- SELECT id, name, host, path FROM moz_cookies
157
- ORDER BY name ASC, host ASC, path ASC, expiry ASC
158
- SQL
159
- if %w[name host path].all? { |col| row[col] == prev_row[col] }
160
- st_delete.execute(prev_row['id'])
161
- end
162
- prev_row = row
205
+ db_prepare("DELETE FROM moz_cookies WHERE id = :id") { |st_delete|
206
+ prev_row = nil
207
+ @db.execute(<<-'SQL') { |row|
208
+ SELECT id, name, host, path FROM moz_cookies
209
+ ORDER BY name ASC, host ASC, path ASC, expiry ASC
210
+ SQL
211
+ if %w[name host path].all? { |col| prev_row and row[col] == prev_row[col] }
212
+ st_delete.execute(prev_row['id'])
213
+ end
214
+ prev_row = row
215
+ }
163
216
  }
164
217
 
165
218
  @db.execute("ALTER TABLE moz_cookies ADD creationTime INTEGER")
@@ -192,14 +245,15 @@ class HTTP::CookieJar
192
245
  end
193
246
  end
194
247
 
195
- def db_add(cookie)
196
- @st_add ||=
197
- @db.prepare('INSERT OR REPLACE INTO moz_cookies (%s) VALUES (%s)' % [
198
- ALL_COLUMNS.join(', '),
199
- ALL_COLUMNS.map { |col| ":#{col}" }.join(', ')
200
- ])
248
+ SQL[:add] = <<-'SQL' % [
249
+ INSERT OR REPLACE INTO moz_cookies (%s) VALUES (%s)
250
+ SQL
251
+ ALL_COLUMNS.join(', '),
252
+ ALL_COLUMNS.map { |col| ":#{col}" }.join(', ')
253
+ ]
201
254
 
202
- @st_add.execute({
255
+ def db_add(cookie)
256
+ @stmt[:add].execute({
203
257
  :baseDomain => cookie.domain_name.domain || cookie.domain,
204
258
  :appId => @app_id,
205
259
  :inBrowserElement => @in_browser_element ? 1 : 0,
@@ -217,18 +271,17 @@ class HTTP::CookieJar
217
271
  self
218
272
  end
219
273
 
274
+ SQL[:delete] = <<-'SQL'
275
+ DELETE FROM moz_cookies
276
+ WHERE appId = :appId AND
277
+ inBrowserElement = :inBrowserElement AND
278
+ name = :name AND
279
+ host = :host AND
280
+ path = :path
281
+ SQL
282
+
220
283
  def db_delete(cookie)
221
- @st_delete ||=
222
- @db.prepare(<<-'SQL')
223
- DELETE FROM moz_cookies
224
- WHERE appId = :appId AND
225
- inBrowserElement = :inBrowserElement AND
226
- name = :name AND
227
- host = :host AND
228
- path = :path
229
- SQL
230
-
231
- @st_delete.execute({
284
+ @stmt[:delete].execute({
232
285
  :appId => @app_id,
233
286
  :inBrowserElement => @in_browser_element ? 1 : 0,
234
287
  :name => cookie.name,
@@ -255,25 +308,34 @@ class HTTP::CookieJar
255
308
  db_delete(cookie)
256
309
  end
257
310
 
311
+ SQL[:cookies_for_domain] = <<-'SQL'
312
+ SELECT * FROM moz_cookies
313
+ WHERE baseDomain = :baseDomain AND
314
+ appId = :appId AND
315
+ inBrowserElement = :inBrowserElement AND
316
+ expiry >= :expiry
317
+ SQL
318
+
319
+ SQL[:update_lastaccessed] = <<-'SQL'
320
+ UPDATE moz_cookies
321
+ SET lastAccessed = :lastAccessed
322
+ WHERE id = :id
323
+ SQL
324
+
325
+ SQL[:all_cookies] = <<-'SQL'
326
+ SELECT * FROM moz_cookies
327
+ WHERE appId = :appId AND
328
+ inBrowserElement = :inBrowserElement AND
329
+ expiry >= :expiry
330
+ SQL
331
+
258
332
  def each(uri = nil, &block)
259
333
  now = Time.now
260
334
  if uri
261
- @st_cookies_for_domain ||=
262
- @db.prepare(<<-'SQL')
263
- SELECT * FROM moz_cookies
264
- WHERE baseDomain = :baseDomain AND
265
- appId = :appId AND
266
- inBrowserElement = :inBrowserElement AND
267
- expiry >= :expiry
268
- SQL
269
-
270
- @st_update_lastaccessed ||=
271
- @db.prepare("UPDATE moz_cookies SET lastAccessed = :lastAccessed where id = :id")
272
-
273
335
  thost = DomainName.new(uri.host)
274
336
  tpath = uri.path
275
337
 
276
- @st_cookies_for_domain.execute({
338
+ @stmt[:cookies_for_domain].execute({
277
339
  :baseDomain => thost.domain || thost.hostname,
278
340
  :appId => @app_id,
279
341
  :inBrowserElement => @in_browser_element ? 1 : 0,
@@ -289,15 +351,15 @@ class HTTP::CookieJar
289
351
  attrs[:domain] = row['host']
290
352
  attrs[:path] = row['path']
291
353
  attrs[:expires_at] = Time.at(row['expiry'])
292
- attrs[:accessed_at] = Time.at(row['lastAccessed'])
293
- attrs[:created_at] = Time.at(row['creationTime'])
354
+ attrs[:accessed_at] = Time.at(row['lastAccessed'] || 0)
355
+ attrs[:created_at] = Time.at(row['creationTime'] || 0)
294
356
  attrs[:secure] = secure
295
357
  attrs[:httponly] = row['isHttpOnly'] != 0
296
358
  })
297
359
 
298
360
  if cookie.valid_for_uri?(uri)
299
361
  cookie.accessed_at = now
300
- @st_update_lastaccessed.execute({
362
+ @stmt[:update_lastaccessed].execute({
301
363
  'lastAccessed' => now.to_i,
302
364
  'id' => row['id'],
303
365
  })
@@ -306,15 +368,7 @@ class HTTP::CookieJar
306
368
  }
307
369
  @sjar.each(uri, &block)
308
370
  else
309
- @st_all_cookies ||=
310
- @db.prepare(<<-'SQL')
311
- SELECT * FROM moz_cookies
312
- WHERE appId = :appId AND
313
- inBrowserElement = :inBrowserElement AND
314
- expiry >= :expiry
315
- SQL
316
-
317
- @st_all_cookies.execute({
371
+ @stmt[:all_cookies].execute({
318
372
  :appId => @app_id,
319
373
  :inBrowserElement => @in_browser_element ? 1 : 0,
320
374
  :expiry => now.to_i,
@@ -325,8 +379,8 @@ class HTTP::CookieJar
325
379
  attrs[:domain] = row['host']
326
380
  attrs[:path] = row['path']
327
381
  attrs[:expires_at] = Time.at(row['expiry'])
328
- attrs[:accessed_at] = Time.at(row['lastAccessed'])
329
- attrs[:created_at] = Time.at(row['creationTime'])
382
+ attrs[:accessed_at] = Time.at(row['lastAccessed'] || 0)
383
+ attrs[:created_at] = Time.at(row['creationTime'] || 0)
330
384
  attrs[:secure] = row['isSecure'] != 0
331
385
  attrs[:httponly] = row['isHttpOnly'] != 0
332
386
  })
@@ -344,11 +398,12 @@ class HTTP::CookieJar
344
398
  self
345
399
  end
346
400
 
347
- def count
348
- @st_count ||=
349
- @db.prepare("SELECT COUNT(id) FROM moz_cookies")
401
+ SQL[:count] = <<-'SQL'
402
+ SELECT COUNT(id) FROM moz_cookies
403
+ SQL
350
404
 
351
- @st_count.execute.first[0]
405
+ def count
406
+ @stmt[:count].execute.first[0]
352
407
  end
353
408
  protected :count
354
409
 
@@ -356,44 +411,43 @@ class HTTP::CookieJar
356
411
  @sjar.empty? && count == 0
357
412
  end
358
413
 
359
- def cleanup(session = false)
360
- @st_delete_expired ||=
361
- @db.prepare("DELETE FROM moz_cookies WHERE expiry < :expiry")
362
-
363
- @st_overusing_domains ||=
364
- @db.prepare(<<-'SQL')
365
- SELECT LTRIM(host, '.') domain, COUNT(*) count
366
- FROM moz_cookies
367
- GROUP BY domain
368
- HAVING count > :count
369
- SQL
370
-
371
- @st_delete_per_domain_overuse ||=
372
- @db.prepare(<<-'SQL')
373
- DELETE FROM moz_cookies WHERE id IN (
374
- SELECT id FROM moz_cookies
375
- WHERE LTRIM(host, '.') = :domain
376
- ORDER BY creationtime
377
- LIMIT :limit)
378
- SQL
379
- @st_delete_total_overuse ||=
380
- @db.prepare(<<-'SQL')
381
- DELETE FROM moz_cookies WHERE id IN (
382
- SELECT id FROM moz_cookies ORDER BY creationTime ASC LIMIT :limit
383
- )
384
- SQL
414
+ SQL[:delete_expired] = <<-'SQL'
415
+ DELETE FROM moz_cookies WHERE expiry < :expiry
416
+ SQL
417
+
418
+ SQL[:overusing_domains] = <<-'SQL'
419
+ SELECT LTRIM(host, '.') domain, COUNT(*) count
420
+ FROM moz_cookies
421
+ GROUP BY domain
422
+ HAVING count > :count
423
+ SQL
424
+
425
+ SQL[:delete_per_domain_overuse] = <<-'SQL'
426
+ DELETE FROM moz_cookies WHERE id IN (
427
+ SELECT id FROM moz_cookies
428
+ WHERE LTRIM(host, '.') = :domain
429
+ ORDER BY creationtime
430
+ LIMIT :limit)
431
+ SQL
432
+
433
+ SQL[:delete_total_overuse] = <<-'SQL'
434
+ DELETE FROM moz_cookies WHERE id IN (
435
+ SELECT id FROM moz_cookies ORDER BY creationTime ASC LIMIT :limit
436
+ )
437
+ SQL
385
438
 
439
+ def cleanup(session = false)
386
440
  synchronize {
387
441
  break if @gc_index == 0
388
442
 
389
- @st_delete_expired.execute({ 'expiry' => Time.now.to_i })
443
+ @stmt[:delete_expired].execute({ 'expiry' => Time.now.to_i })
390
444
 
391
- @st_overusing_domains.execute({
445
+ @stmt[:overusing_domains].execute({
392
446
  'count' => HTTP::Cookie::MAX_COOKIES_PER_DOMAIN
393
447
  }).each { |row|
394
448
  domain, count = row['domain'], row['count']
395
449
 
396
- @st_delete_per_domain_overuse.execute({
450
+ @stmt[:delete_per_domain_overuse].execute({
397
451
  'domain' => domain,
398
452
  'limit' => count - HTTP::Cookie::MAX_COOKIES_PER_DOMAIN,
399
453
  })
@@ -402,7 +456,7 @@ class HTTP::CookieJar
402
456
  overrun = count - HTTP::Cookie::MAX_COOKIES_TOTAL
403
457
 
404
458
  if overrun > 0
405
- @st_delete_total_overuse.execute({ 'limit' => overrun })
459
+ @stmt[:delete_total_overuse].execute({ 'limit' => overrun })
406
460
  end
407
461
 
408
462
  @gc_index = 0
@@ -38,6 +38,10 @@ class HTTP::CookieJar::YAMLSaver < HTTP::CookieJar::AbstractSaver
38
38
  data.each { |domain, paths|
39
39
  paths.each { |path, names|
40
40
  names.each { |cookie_name, cookie_hash|
41
+ if cookie_hash.respond_to?(:ivars)
42
+ # YAML::Object of Syck
43
+ cookie_hash = cookie_hash.ivars
44
+ end
41
45
  cookie = HTTP::Cookie.new(cookie_hash)
42
46
  jar.add(cookie)
43
47
  }
@@ -19,3 +19,7 @@ module Enumerable
19
19
  result
20
20
  end
21
21
  end
22
+
23
+ def test_file(filename)
24
+ File.expand_path(filename, File.dirname(__FILE__))
25
+ end
@@ -0,0 +1,101 @@
1
+ ---
2
+ google.com:
3
+ /:
4
+ PREF: !ruby/object:Mechanize::Cookie
5
+ version: 0
6
+ port:
7
+ discard:
8
+ comment_url:
9
+ expires: Tue, 24 Mar 2065 08:20:15 GMT
10
+ max_age:
11
+ comment:
12
+ secure: false
13
+ path: /
14
+ domain: google.com
15
+ accessed_at: 2013-03-24 17:20:15.822619000 +09:00
16
+ created_at: 2013-03-24 17:20:15.822619000 +09:00
17
+ name: PREF
18
+ value: ID=7571a59c059e09db:FF=0:TM=1364199615:LM=1364199615:S=BxUqnqPrchd2cVmC
19
+ for_domain: true
20
+ domain_name: !ruby/object:DomainName
21
+ ipaddr:
22
+ hostname: google.com
23
+ uri_host: google.com
24
+ tld: com
25
+ canonical_tld_p: true
26
+ domain: google.com
27
+ session: false
28
+ NID: !ruby/object:Mechanize::Cookie
29
+ version: 0
30
+ port:
31
+ discard:
32
+ comment_url:
33
+ expires: Sun, 23 Sep 2063 08:20:15 GMT
34
+ max_age:
35
+ comment:
36
+ secure: false
37
+ path: /
38
+ domain: google.com
39
+ accessed_at: 2013-03-24 17:20:15.828434000 +09:00
40
+ created_at: 2013-03-24 17:20:15.828434000 +09:00
41
+ name: NID
42
+ value: 67=Kn2osS6wOzILpl7sCM1QIDmGg2VESBiwCyt6zx4vOVSWKOYDlwGIpgIGrpD8FpkbS9eqizo3QWFa5YkOygnCF6vRIQpbvlTxWB2Hq1Oo-qXWy0317yCqQ-B25eJLfUcC
43
+ for_domain: true
44
+ domain_name: !ruby/object:DomainName
45
+ ipaddr:
46
+ hostname: google.com
47
+ uri_host: google.com
48
+ tld: com
49
+ canonical_tld_p: true
50
+ domain: google.com
51
+ session: false
52
+ google.co.jp:
53
+ /:
54
+ PREF: !ruby/object:Mechanize::Cookie
55
+ version: 0
56
+ port:
57
+ discard:
58
+ comment_url:
59
+ expires: Tue, 24 Mar 2065 08:20:16 GMT
60
+ max_age:
61
+ comment:
62
+ secure: false
63
+ path: /
64
+ domain: google.co.jp
65
+ accessed_at: 2013-03-24 17:20:17.136581000 +09:00
66
+ created_at: 2013-03-24 17:20:17.136581000 +09:00
67
+ name: PREF
68
+ value: ID=cb25dd1567d8b5c8:FF=0:TM=1364199616:LM=1364199616:S=c3PbhRq79Wo5T_vV
69
+ for_domain: true
70
+ domain_name: !ruby/object:DomainName
71
+ ipaddr:
72
+ hostname: google.co.jp
73
+ uri_host: google.co.jp
74
+ tld: jp
75
+ canonical_tld_p: true
76
+ domain: google.co.jp
77
+ session: false
78
+ NID: !ruby/object:Mechanize::Cookie
79
+ version: 0
80
+ port:
81
+ discard:
82
+ comment_url:
83
+ expires: Sun, 23 Sep 2063 08:20:16 GMT
84
+ max_age:
85
+ comment:
86
+ secure: false
87
+ path: /
88
+ domain: google.co.jp
89
+ accessed_at: 2013-03-24 17:20:17.139782000 +09:00
90
+ created_at: 2013-03-24 17:20:17.139782000 +09:00
91
+ name: NID
92
+ value: 67=GS7P-68zgm_KRA0e0dpN_XbYpmw9uBDe56qUeoCGiSRTahsM7dtOBCKfCoIFRKlzSuOiwJQdIZNpwv3DSXQNHXDKltucgfv2qkHlGeoj8-5VlowPXLLesz2VIpLOLw-a
93
+ for_domain: true
94
+ domain_name: !ruby/object:DomainName
95
+ ipaddr:
96
+ hostname: google.co.jp
97
+ uri_host: google.co.jp
98
+ tld: jp
99
+ canonical_tld_p: true
100
+ domain: google.co.jp
101
+ session: false
@@ -3,11 +3,10 @@ require File.expand_path('helper', File.dirname(__FILE__))
3
3
 
4
4
  class TestHTTPCookie < Test::Unit::TestCase
5
5
  def silently
6
- warn_level = $VERBOSE
7
- $VERBOSE = false
8
- res = yield
6
+ warn_level, $VERBOSE = $VERBOSE, false
7
+ yield
8
+ ensure
9
9
  $VERBOSE = warn_level
10
- res
11
10
  end
12
11
 
13
12
  def setup
@@ -523,7 +522,7 @@ class TestHTTPCookie < Test::Unit::TestCase
523
522
  assert_equal 'key', cookie.name
524
523
  assert_equal 'value', cookie.value
525
524
  assert_equal nil, cookie.expires
526
- assert_raises(ArgumentError) {
525
+ assert_raises(RuntimeError) {
527
526
  cookie.acceptable?
528
527
  }
529
528
 
@@ -534,7 +533,7 @@ class TestHTTPCookie < Test::Unit::TestCase
534
533
  assert_equal 'key', cookie.name
535
534
  assert_equal 'value', cookie.value
536
535
  assert_equal expires, cookie.expires
537
- assert_raises(ArgumentError) {
536
+ assert_raises(RuntimeError) {
538
537
  cookie.acceptable?
539
538
  }
540
539
 
@@ -543,7 +542,7 @@ class TestHTTPCookie < Test::Unit::TestCase
543
542
  assert_equal 'value', cookie.value
544
543
  assert_equal expires, cookie.expires
545
544
  assert_equal false, cookie.for_domain?
546
- assert_raises(ArgumentError) {
545
+ assert_raises(RuntimeError) {
547
546
  # domain and path are missing
548
547
  cookie.acceptable?
549
548
  }
@@ -553,7 +552,7 @@ class TestHTTPCookie < Test::Unit::TestCase
553
552
  assert_equal 'value', cookie.value
554
553
  assert_equal expires, cookie.expires
555
554
  assert_equal true, cookie.for_domain?
556
- assert_raises(ArgumentError) {
555
+ assert_raises(RuntimeError) {
557
556
  # path is missing
558
557
  cookie.acceptable?
559
558
  }
@@ -563,7 +562,7 @@ class TestHTTPCookie < Test::Unit::TestCase
563
562
  assert_equal 'value', cookie.value
564
563
  assert_equal expires, cookie.expires
565
564
  assert_equal false, cookie.for_domain?
566
- assert_raises(ArgumentError) {
565
+ assert_raises(RuntimeError) {
567
566
  # path is missing
568
567
  cookie.acceptable?
569
568
  }
@@ -574,7 +573,7 @@ class TestHTTPCookie < Test::Unit::TestCase
574
573
  assert_equal expires, cookie.expires
575
574
  assert_equal 'example.org', cookie.domain
576
575
  assert_equal true, cookie.for_domain?
577
- assert_raises(ArgumentError) {
576
+ assert_raises(RuntimeError) {
578
577
  # path is missing
579
578
  cookie.acceptable?
580
579
  }
@@ -849,7 +848,7 @@ class TestHTTPCookie < Test::Unit::TestCase
849
848
  cookie.domain = d
850
849
  assert_equal nil, cookie.domain, "domain=#{d.inspect}"
851
850
  assert_equal nil, cookie.domain_name, "domain=#{d.inspect}"
852
- assert_raises(ArgumentError) {
851
+ assert_raises(RuntimeError) {
853
852
  cookie.acceptable?
854
853
  }
855
854
 
@@ -2,25 +2,7 @@ require File.expand_path('helper', File.dirname(__FILE__))
2
2
  require 'tmpdir'
3
3
 
4
4
  module TestHTTPCookieJar
5
- class TestBasic < Test::Unit::TestCase
6
- def test_store
7
- jar = HTTP::CookieJar.new(:store => :hash)
8
- assert_instance_of HTTP::CookieJar::HashStore, jar.store
9
-
10
- assert_raises(IndexError) {
11
- jar = HTTP::CookieJar.new(:store => :nonexistent)
12
- }
13
-
14
- jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore.new)
15
- assert_instance_of HTTP::CookieJar::HashStore, jar.store
16
-
17
- assert_raises(TypeError) {
18
- jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore)
19
- }
20
- end
21
- end
22
-
23
- module Tests
5
+ module CommonTests
24
6
  def setup(options = nil, options2 = nil)
25
7
  default_options = {
26
8
  :store => :hash,
@@ -34,9 +16,9 @@ module TestHTTPCookieJar
34
16
  @jar2 = HTTP::CookieJar.new(new_options2)
35
17
  end
36
18
 
37
- def hash_store?
38
- @store_type == :hash
39
- end
19
+ #def hash_store?
20
+ # @store_type == :hash
21
+ #end
40
22
 
41
23
  def mozilla_store?
42
24
  @store_type == :mozilla
@@ -505,6 +487,32 @@ module TestHTTPCookieJar
505
487
  assert_equal(5, @jar.cookies(url).length)
506
488
  end
507
489
 
490
+ def test_load_yaml_mechanize
491
+ @jar.load(test_file('mechanize.yml'), :yaml)
492
+
493
+ assert_equal 4, @jar.to_a.size
494
+
495
+ com_nid, com_pref = @jar.cookies('http://www.google.com/')
496
+
497
+ assert_equal 'NID', com_nid.name
498
+ assert_equal 'Sun, 23 Sep 2063 08:20:15 GMT', com_nid.expires.httpdate
499
+ assert_equal 'google.com', com_nid.domain_name.hostname
500
+
501
+ assert_equal 'PREF', com_pref.name
502
+ assert_equal 'Tue, 24 Mar 2065 08:20:15 GMT', com_pref.expires.httpdate
503
+ assert_equal 'google.com', com_pref.domain_name.hostname
504
+
505
+ cojp_nid, cojp_pref = @jar.cookies('http://www.google.co.jp/')
506
+
507
+ assert_equal 'NID', cojp_nid.name
508
+ assert_equal 'Sun, 23 Sep 2063 08:20:16 GMT', cojp_nid.expires.httpdate
509
+ assert_equal 'google.co.jp', cojp_nid.domain_name.hostname
510
+
511
+ assert_equal 'PREF', cojp_pref.name
512
+ assert_equal 'Tue, 24 Mar 2065 08:20:16 GMT', cojp_pref.expires.httpdate
513
+ assert_equal 'google.co.jp', cojp_pref.domain_name.hostname
514
+ end
515
+
508
516
  def test_expire_cookies
509
517
  url = URI 'http://rubyforge.org/'
510
518
 
@@ -744,17 +752,116 @@ module TestHTTPCookieJar
744
752
  end
745
753
 
746
754
  class WithHashStore < Test::Unit::TestCase
747
- include Tests
755
+ include CommonTests
756
+
757
+ def test_new
758
+ jar = HTTP::CookieJar.new(:store => :hash)
759
+ assert_instance_of HTTP::CookieJar::HashStore, jar.store
760
+
761
+ assert_raises(IndexError) {
762
+ jar = HTTP::CookieJar.new(:store => :nonexistent)
763
+ }
764
+
765
+ jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore.new)
766
+ assert_instance_of HTTP::CookieJar::HashStore, jar.store
767
+
768
+ assert_raises(TypeError) {
769
+ jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore)
770
+ }
771
+ end
772
+
748
773
  end
749
774
 
750
775
  class WithMozillaStore < Test::Unit::TestCase
751
- include Tests
776
+ include CommonTests
752
777
 
753
778
  def setup
754
779
  super(
755
780
  { :store => :mozilla, :filename => ":memory:" },
756
781
  { :store => :mozilla, :filename => ":memory:" })
757
782
  end
783
+
784
+ def add_and_delete(jar)
785
+ jar.parse("name=Akinori; Domain=rubyforge.org; Expires=Sun, 08 Aug 2076 19:00:00 GMT; Path=/",
786
+ 'http://rubyforge.org/')
787
+ jar.parse("country=Japan; Domain=rubyforge.org; Expires=Sun, 08 Aug 2076 19:00:00 GMT; Path=/",
788
+ 'http://rubyforge.org/')
789
+ jar.delete(HTTP::Cookie.new("name", :domain => 'rubyforge.org'))
790
+ end
791
+
792
+ def test_close
793
+ add_and_delete(@jar)
794
+
795
+ assert_not_send [@jar.store, :closed?]
796
+ @jar.store.close
797
+ assert_send [@jar.store, :closed?]
798
+ @jar.store.close # should do nothing
799
+ assert_send [@jar.store, :closed?]
800
+ end
801
+
802
+ def test_finalizer
803
+ db = nil
804
+ loop {
805
+ jar = HTTP::CookieJar.new(:store => :mozilla, :filename => ':memory:')
806
+ add_and_delete(jar)
807
+ db = jar.store.instance_variable_get(:@db)
808
+ class << db
809
+ alias close_orig close
810
+ def close
811
+ STDERR.print "[finalizer is called]"
812
+ STDERR.flush
813
+ close_orig
814
+ end
815
+ end
816
+ break
817
+ }
818
+ end
819
+
820
+ def test_upgrade_mozillastore
821
+ Dir.mktmpdir { |dir|
822
+ filename = File.join(dir, 'cookies.sqlite')
823
+
824
+ sqlite = SQLite3::Database.new(filename)
825
+ sqlite.execute(<<-'SQL')
826
+ CREATE TABLE moz_cookies (
827
+ id INTEGER PRIMARY KEY,
828
+ name TEXT,
829
+ value TEXT,
830
+ host TEXT,
831
+ path TEXT,
832
+ expiry INTEGER,
833
+ isSecure INTEGER,
834
+ isHttpOnly INTEGER)
835
+ SQL
836
+ sqlite.execute(<<-'SQL')
837
+ PRAGMA user_version = 1
838
+ SQL
839
+
840
+ begin
841
+ st_insert = sqlite.prepare(<<-'SQL')
842
+ INSERT INTO moz_cookies (
843
+ id, name, value, host, path, expiry, isSecure, isHttpOnly
844
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
845
+ SQL
846
+
847
+ st_insert.execute(1, 'name1', 'value1', '.example.co.jp', '/', 2312085765, 0, 0)
848
+ st_insert.execute(2, 'name1', 'value2', '.example.co.jp', '/', 2312085765, 0, 0)
849
+ st_insert.execute(3, 'name1', 'value3', 'www.example.co.jp', '/', 2312085765, 0, 0)
850
+ ensure
851
+ st_insert.close if st_insert
852
+ end
853
+
854
+ sqlite.close
855
+ jar = HTTP::CookieJar.new(:store => :mozilla, :filename => filename)
856
+
857
+ assert_equal 2, jar.to_a.size
858
+ assert_equal 2, jar.cookies('http://www.example.co.jp/').size
859
+
860
+ cookie, *rest = jar.cookies('http://host.example.co.jp/')
861
+ assert_send [rest, :empty?]
862
+ assert_equal 'value2', cookie.value
863
+ }
864
+ end
758
865
  end if begin
759
866
  require 'sqlite3'
760
867
  true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http-cookie
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre11
4
+ version: 1.0.0.pre12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akinori MUSHA
@@ -143,6 +143,7 @@ files:
143
143
  - lib/http/cookie_jar/mozilla_store.rb
144
144
  - lib/http/cookie_jar/yaml_saver.rb
145
145
  - test/helper.rb
146
+ - test/mechanize.yml
146
147
  - test/simplecov_start.rb
147
148
  - test/test_http_cookie.rb
148
149
  - test/test_http_cookie_jar.rb
@@ -171,6 +172,7 @@ specification_version: 4
171
172
  summary: A Ruby library to handle HTTP Cookies
172
173
  test_files:
173
174
  - test/helper.rb
175
+ - test/mechanize.yml
174
176
  - test/simplecov_start.rb
175
177
  - test/test_http_cookie.rb
176
178
  - test/test_http_cookie_jar.rb