http-cookie 1.0.0.pre11 → 1.0.0.pre12

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