http-cookie 1.0.0.pre2 → 1.0.0.pre3

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: 653d322460f46234180a90aed35776cd7cd8de38
4
- data.tar.gz: 14c9c551e73f83be713b128d4ae0a0cd0211d9f0
3
+ metadata.gz: 38b7c03ef15bbe6b866f7128b719962c7776fa16
4
+ data.tar.gz: 79078f90e4250e68ec2fa0b6250ee378d7681aea
5
5
  SHA512:
6
- metadata.gz: 528f89eca80703fec30058de9b9772fc0fb83962d6aa17fe07977b8cbb109fe62f63989097520d955f8b70576bc63ea0c3815195d2d6717bfe1d46a87257cfe4
7
- data.tar.gz: 4bf6f20da6f6dc7bfe5ec5980c7298f70c1ebc39024abad55b47d8c9b897d5dfc73f2a4216324ac0e6d884f930e6b401e57cefde0666dc2f88079d0508348b79
6
+ metadata.gz: 41d93c054cda8e2fbb07554de72061fcf6218da13dce541fda0581056315b0d0438307c1f95043d59bce7742e4cee08ea9295f75c7fc1ddf297849cf7ed87ee0
7
+ data.tar.gz: a9cebb93040062c160bccf8758a25898af16f8b8fc2e5118a5cfb7210ba96b2f212b8154ca2b4e1fb1e2e740a5efaffd515bd9addc0ddee3be94d6e93e89f7f9
data/http-cookie.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |gem|
24
24
  gem.extra_rdoc_files = ['README.md', 'LICENSE.txt']
25
25
 
26
26
  gem.add_runtime_dependency("domain_name", ["~> 0.5"])
27
+ gem.add_runtime_dependency("sqlite3", ["~> 1.3.3"])
27
28
  gem.add_development_dependency("bundler", [">= 1.2.0"])
28
29
  gem.add_development_dependency("test-unit", [">= 2.4.3"])
29
30
  gem.add_development_dependency("rake", [">= 0.9.2.2"])
data/lib/http/cookie.rb CHANGED
@@ -386,6 +386,12 @@ class HTTP::Cookie
386
386
  @domain = @domain_name.hostname
387
387
  end
388
388
 
389
+ # Returns the domain, with a dot prefixed only if the domain flag is
390
+ # on.
391
+ def dot_domain
392
+ @for_domain ? '.' << @domain : @domain
393
+ end
394
+
389
395
  # Returns the domain attribute value as a DomainName object.
390
396
  attr_reader :domain_name
391
397
 
@@ -1,5 +1,5 @@
1
1
  module HTTP
2
2
  class Cookie
3
- VERSION = "1.0.0.pre2"
3
+ VERSION = "1.0.0.pre3"
4
4
  end
5
5
  end
@@ -13,6 +13,8 @@ class HTTP::CookieJar
13
13
  # Generates a new cookie jar. The default store class is `:hash`,
14
14
  # which maps to `HTTP::CookieJar::HashStore`. Any given options are
15
15
  # passed through to the initializer of the specified store class.
16
+ # For example, the `:mozilla` (`HTTP::CookieJar::MozillaStore`)
17
+ # store class requires a `:filename` option.
16
18
  def initialize(store = :hash, options = nil)
17
19
  case store
18
20
  when Symbol
@@ -95,9 +97,6 @@ class HTTP::CookieJar
95
97
  if uri
96
98
  uri = URI(uri)
97
99
  return self unless URI::HTTP === uri && uri.host
98
- block = proc { |cookie|
99
- yield cookie if cookie.valid_for_uri?(uri)
100
- }
101
100
  end
102
101
 
103
102
  @store.each(uri, &block)
@@ -28,11 +28,14 @@ class HTTP::CookieJar::CookiestxtSaver < HTTP::CookieJar::AbstractSaver
28
28
  }
29
29
  end
30
30
 
31
+ HTTPONLY_PREFIX = '#HttpOnly_'
32
+ RE_HTTPONLY_PREFIX = /\A#{HTTPONLY_PREFIX}/
33
+
31
34
  # Serializes the cookie into a cookies.txt line.
32
35
  def cookie_to_record(cookie)
33
36
  cookie.instance_eval {
34
37
  [
35
- @domain,
38
+ @httponly ? HTTPONLY_PREFIX + dot_domain : dot_domain,
36
39
  @for_domain ? True : False,
37
40
  @path,
38
41
  @secure ? True : False,
@@ -46,7 +49,15 @@ class HTTP::CookieJar::CookiestxtSaver < HTTP::CookieJar::AbstractSaver
46
49
  # Parses a line from cookies.txt and returns a cookie object if the
47
50
  # line represents a cookie record or returns nil otherwise.
48
51
  def parse_record(line)
49
- return nil if line.match(/^#/)
52
+ case line
53
+ when RE_HTTPONLY_PREFIX
54
+ httponly = true
55
+ line = $'
56
+ when /\A#/
57
+ return nil
58
+ else
59
+ httponly = false
60
+ end
50
61
 
51
62
  domain,
52
63
  s_for_domain, # Whether this cookie is for domain
@@ -68,6 +79,7 @@ class HTTP::CookieJar::CookiestxtSaver < HTTP::CookieJar::AbstractSaver
68
79
  :for_domain => s_for_domain == True,
69
80
  :path => path,
70
81
  :secure => s_secure == True,
82
+ :httponly => httponly,
71
83
  :expires => expires,
72
84
  :version => 0)
73
85
  end
@@ -9,11 +9,12 @@ end
9
9
  # :startdoc:
10
10
 
11
11
  class HTTP::CookieJar
12
+ # A store class that uses a hash of hashes.
12
13
  class HashStore < AbstractStore
13
- GC_THRESHOLD = HTTP::Cookie::MAX_COOKIES_TOTAL / 20
14
-
15
14
  def default_options
16
- {}
15
+ {
16
+ :gc_threshold => HTTP::Cookie::MAX_COOKIES_TOTAL / 20
17
+ }
17
18
  end
18
19
 
19
20
  def initialize(options = nil)
@@ -40,18 +41,20 @@ class HTTP::CookieJar
40
41
 
41
42
  def add(cookie)
42
43
  path_cookies = ((@jar[cookie.domain_name.hostname] ||= {})[cookie.path] ||= {})
44
+ path_cookies[cookie.name] = cookie
45
+ cleanup if (@gc_index += 1) >= @gc_threshold
46
+ self
47
+ end
43
48
 
44
- if cookie.expired?
45
- path_cookies.delete(cookie.name)
46
- else
47
- path_cookies[cookie.name] = cookie
48
- cleanup if (@gc_index += 1) >= GC_THRESHOLD
49
- end
50
-
49
+ def delete(cookie)
50
+ path_cookies = ((@jar[cookie.domain_name.hostname] ||= {})[cookie.path] ||= {})
51
+ path_cookies.delete(cookie.name)
51
52
  self
52
53
  end
54
+ private :delete
53
55
 
54
56
  def each(uri = nil)
57
+ now = Time.now
55
58
  if uri
56
59
  thost = DomainName.new(uri.host)
57
60
  tpath = uri.path
@@ -60,11 +63,13 @@ class HTTP::CookieJar
60
63
  paths.each { |path, hash|
61
64
  next unless HTTP::Cookie.path_match?(path, tpath)
62
65
  hash.delete_if { |name, cookie|
63
- if cookie.expired?
66
+ if cookie.expired?(now)
64
67
  true
65
68
  else
66
- cookie.accessed_at = Time.now
67
- yield cookie
69
+ if cookie.valid_for_uri?(uri)
70
+ cookie.accessed_at = now
71
+ yield cookie
72
+ end
68
73
  false
69
74
  end
70
75
  }
@@ -74,7 +79,7 @@ class HTTP::CookieJar
74
79
  @jar.each { |domain, paths|
75
80
  paths.each { |path, hash|
76
81
  hash.delete_if { |name, cookie|
77
- if cookie.expired?
82
+ if cookie.expired?(now)
78
83
  true
79
84
  else
80
85
  yield cookie
@@ -97,14 +102,14 @@ class HTTP::CookieJar
97
102
  end
98
103
 
99
104
  def cleanup(session = false)
105
+ now = Time.now
100
106
  all_cookies = []
101
-
102
107
  @jar.each { |domain, paths|
103
108
  domain_cookies = []
104
109
 
105
110
  paths.each { |path, hash|
106
111
  hash.delete_if { |name, cookie|
107
- if cookie.expired? || (session && cookie.session?)
112
+ if cookie.expired?(now) || (session && cookie.session?)
108
113
  true
109
114
  else
110
115
  domain_cookies << cookie
@@ -116,7 +121,7 @@ class HTTP::CookieJar
116
121
  if (debt = domain_cookies.size - HTTP::Cookie::MAX_COOKIES_PER_DOMAIN) > 0
117
122
  domain_cookies.sort_by!(&:created_at)
118
123
  domain_cookies.slice!(0, debt).each { |cookie|
119
- add(cookie.expire!)
124
+ delete(cookie)
120
125
  }
121
126
  end
122
127
 
@@ -126,7 +131,7 @@ class HTTP::CookieJar
126
131
  if (debt = all_cookies.size - HTTP::Cookie::MAX_COOKIES_TOTAL) > 0
127
132
  all_cookies.sort_by!(&:created_at)
128
133
  all_cookies.slice!(0, debt).each { |cookie|
129
- add(cookie.expire!)
134
+ delete(cookie)
130
135
  }
131
136
  end
132
137
 
@@ -0,0 +1,327 @@
1
+ require 'http/cookie_jar'
2
+ require 'sqlite3'
3
+
4
+ class HTTP::CookieJar
5
+ class MozillaStore < AbstractStore
6
+ SCHEMA_VERSION = 5
7
+
8
+ def default_options
9
+ {
10
+ :gc_threshold => HTTP::Cookie::MAX_COOKIES_TOTAL / 20,
11
+ :app_id => 0,
12
+ :in_browser_element => false,
13
+ }
14
+ end
15
+
16
+ ALL_COLUMNS = %w[
17
+ baseDomain
18
+ appId inBrowserElement
19
+ name value
20
+ host path
21
+ expiry creationTime lastAccessed
22
+ isSecure isHttpOnly
23
+ ]
24
+ UK_COLUMNS = %w[
25
+ name host path
26
+ appId inBrowserElement
27
+ ]
28
+
29
+ def initialize(options = nil)
30
+ super
31
+
32
+ @filename = options[:filename] or raise ArgumentError, ':filename option is missing'
33
+
34
+ @db = SQLite3::Database.new(@filename)
35
+ @db.results_as_hash = true
36
+
37
+ upgrade_database
38
+
39
+ @gc_index = 0
40
+ end
41
+
42
+ def schema_version
43
+ @schema_version ||= @db.execute("PRAGMA user_version").first[0]
44
+ rescue SQLite3::SQLException
45
+ @logger.warn "couldn't get schema version!" if @logger
46
+ return nil
47
+ end
48
+
49
+ protected
50
+
51
+ def schema_version=(version)
52
+ @db.execute("PRAGMA user_version = %d" % version)
53
+ @schema_version = version
54
+ end
55
+
56
+ def create_table
57
+ self.schema_version = SCHEMA_VERSION
58
+ @db.execute("DROP TABLE IF EXISTS moz_cookies")
59
+ @db.execute(<<-'SQL')
60
+ CREATE TABLE moz_cookies (
61
+ id INTEGER PRIMARY KEY,
62
+ baseDomain TEXT,
63
+ appId INTEGER DEFAULT 0,
64
+ inBrowserElement INTEGER DEFAULT 0,
65
+ name TEXT,
66
+ value TEXT,
67
+ host TEXT,
68
+ path TEXT,
69
+ expiry INTEGER,
70
+ lastAccessed INTEGER,
71
+ creationTime INTEGER,
72
+ isSecure INTEGER,
73
+ isHttpOnly INTEGER,
74
+ CONSTRAINT moz_uniqueid UNIQUE (name, host, path, appId, inBrowserElement)
75
+ )
76
+ SQL
77
+ @db.execute(<<-'SQL')
78
+ CREATE INDEX moz_basedomain
79
+ ON moz_cookies (baseDomain,
80
+ appId,
81
+ inBrowserElement);
82
+ SQL
83
+ end
84
+
85
+ def upgrade_database
86
+ loop {
87
+ case schema_version
88
+ when nil, 0
89
+ self.schema_version = SCHEMA_VERSION
90
+ break
91
+ when 1
92
+ @db.execute("ALTER TABLE moz_cookies ADD lastAccessed INTEGER")
93
+ self.schema_version += 1
94
+ when 2
95
+ @db.execute("ALTER TABLE moz_cookies ADD baseDomain TEXT")
96
+
97
+ st_update = @db.prepare("UPDATE moz_cookies SET baseDomain = :baseDomain WHERE id = :id")
98
+
99
+ @db.execute("SELECT id, host FROM moz_cookies") { |row|
100
+ domain = DomainName.new(row[:host]).domain
101
+ st_update.execute(:baseDomain => domain, :id => row[:id])
102
+ }
103
+
104
+ @db.execute("CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)")
105
+ self.schema_version += 1
106
+ when 3
107
+ st_delete = @db.prepare("DELETE FROM moz_cookies WHERE id = :id")
108
+
109
+ prev_row = nil
110
+ @db.execute(<<-'SQL') { |row|
111
+ SELECT id, name, host, path FROM moz_cookies
112
+ ORDER BY name ASC, host ASC, path ASC, expiry ASC
113
+ SQL
114
+ if %w[name host path].all? { |col| row[col] == prev_row[col] }
115
+ st_delete.execute(prev_row['id'])
116
+ end
117
+ prev_row = row
118
+ }
119
+
120
+ @db.execute("ALTER TABLE moz_cookies ADD creationTime INTEGER")
121
+ @db.execute("UPDATE moz_cookies SET creationTime = (SELECT id WHERE id = moz_cookies.id)")
122
+ @db.execute("CREATE UNIQUE INDEX moz_uniqueid ON moz_cookies (name, host, path)")
123
+ self.schema_version += 1
124
+ when 4
125
+ @db.execute("ALTER TABLE moz_cookies RENAME TO moz_cookies_old")
126
+ @db.execute("DROP INDEX moz_basedomain")
127
+ create_table
128
+ @db.execute(<<-'SQL')
129
+ INSERT INTO moz_cookies
130
+ (baseDomain, appId, inBrowserElement, name, value, host, path, expiry,
131
+ lastAccessed, creationTime, isSecure, isHttpOnly)
132
+ SELECT baseDomain, 0, 0, name, value, host, path, expiry,
133
+ lastAccessed, creationTime, isSecure, isHttpOnly
134
+ FROM moz_cookies_old
135
+ SQL
136
+ @db.execute("DROP TABLE moz_cookies_old")
137
+ @logger.info("Upgraded database to schema version %d" % schema_version) if @logger
138
+ else
139
+ break
140
+ end
141
+ }
142
+
143
+ begin
144
+ @db.execute("SELECT %s from moz_cookies limit 1" % ALL_COLUMNS.join(', '))
145
+ rescue SQLite3::SQLException
146
+ create_table
147
+ end
148
+ end
149
+
150
+ public
151
+
152
+ def add(cookie)
153
+ @st_add ||=
154
+ @db.prepare('INSERT OR REPLACE INTO moz_cookies (%s) VALUES (%s)' % [
155
+ ALL_COLUMNS.join(', '),
156
+ ALL_COLUMNS.map { |col| ":#{col}" }.join(', ')
157
+ ])
158
+
159
+ @st_add.execute({
160
+ :baseDomain => cookie.domain_name.domain,
161
+ :appId => @app_id,
162
+ :inBrowserElement => @in_browser_element ? 1 : 0,
163
+ :name => cookie.name, :value => cookie.value,
164
+ :host => cookie.dot_domain,
165
+ :path => cookie.path,
166
+ :expiry => cookie.expires_at.to_i,
167
+ :creationTime => cookie.created_at.to_i,
168
+ :lastAccessed => cookie.accessed_at.to_i,
169
+ :isSecure => cookie.secure? ? 1 : 0,
170
+ :isHttpOnly => cookie.httponly? ? 1 : 0,
171
+ })
172
+ cleanup if (@gc_index += 1) >= @gc_threshold
173
+
174
+ self
175
+ end
176
+
177
+ def each(uri = nil)
178
+ now = Time.now
179
+ if uri
180
+ @st_cookies_for_domain ||=
181
+ @db.prepare(<<-'SQL')
182
+ SELECT * FROM moz_cookies
183
+ WHERE baseDomain = :baseDomain AND
184
+ appId = :appId AND
185
+ inBrowserElement = :inBrowserElement AND
186
+ expiry >= :expiry
187
+ SQL
188
+
189
+ @st_update_lastaccessed ||=
190
+ @db.prepare("UPDATE moz_cookies SET lastAccessed = :lastAccessed where id = :id")
191
+
192
+ thost = DomainName.new(uri.host)
193
+ tpath = HTTP::Cookie.normalize_path(uri.path)
194
+
195
+ @st_cookies_for_domain.execute({
196
+ :baseDomain => thost.domain_name.domain,
197
+ :appId => @app_id,
198
+ :inBrowserElement => @in_browser_element ? 1 : 0,
199
+ :expiry => now.to_i,
200
+ }).each { |row|
201
+ if secure = row['isSecure'] != 0
202
+ next unless URI::HTTPS === uri
203
+ end
204
+
205
+ cookie = HTTP::Cookie.new({}.tap { |attrs|
206
+ attrs[:name] = row['name']
207
+ attrs[:value] = row['value']
208
+ attrs[:domain] = row['host']
209
+ attrs[:path] = row['path']
210
+ attrs[:expires_at] = Time.at(row['expiry'])
211
+ attrs[:accessed_at] = Time.at(row['lastAccessed'])
212
+ attrs[:created_at] = Time.at(row['creationTime'])
213
+ attrs[:secure] = secure
214
+ attrs[:httponly] = row['isHttpOnly'] != 0
215
+ })
216
+
217
+ if cookie.valid_for_uri?(uri)
218
+ cookie.accessed_at = now
219
+ @st_update_lastaccessed.execute({
220
+ 'lastAccessed' => now.to_i,
221
+ 'id' => row['id'],
222
+ })
223
+ yield cookie
224
+ end
225
+ }
226
+ else
227
+ @st_all_cookies ||=
228
+ @db.prepare(<<-'SQL')
229
+ SELECT * FROM moz_cookies
230
+ WHERE appId = :appId AND
231
+ inBrowserElement = :inBrowserElement AND
232
+ expiry >= :expiry
233
+ SQL
234
+
235
+ @st_all_cookies.execute({
236
+ :appId => @app_id,
237
+ :inBrowserElement => @in_browser_element ? 1 : 0,
238
+ :expiry => now.to_i,
239
+ }).each { |row|
240
+ cookie = HTTP::Cookie.new({}.tap { |attrs|
241
+ attrs[:name] = row['name']
242
+ attrs[:value] = row['value']
243
+ attrs[:domain] = row['host']
244
+ attrs[:path] = row['path']
245
+ attrs[:expires_at] = Time.at(row['expiry'])
246
+ attrs[:accessed_at] = Time.at(row['lastAccessed'])
247
+ attrs[:created_at] = Time.at(row['creationTime'])
248
+ attrs[:secure] = row['isSecure'] != 0
249
+ attrs[:httponly] = row['isHttpOnly'] != 0
250
+ })
251
+
252
+ yield cookie
253
+ }
254
+ end
255
+ self
256
+ end
257
+
258
+ def clear
259
+ @db.execute("DELETE FROM moz_cookies")
260
+ self
261
+ end
262
+
263
+ def count
264
+ @st_count ||=
265
+ @db.prepare("SELECT COUNT(id) FROM moz_cookies")
266
+
267
+ @st_count.execute.first[0]
268
+ end
269
+ protected :count
270
+
271
+ def empty?
272
+ count == 0
273
+ end
274
+
275
+ def cleanup(session = false)
276
+ now = Time.now
277
+ all_cookies = []
278
+
279
+ @st_delete_expired ||=
280
+ @db.prepare("DELETE FROM moz_cookies WHERE expiry < :expiry")
281
+
282
+ @st_overusing_domains ||=
283
+ @db.prepare(<<-'SQL')
284
+ SELECT LTRIM(host, '.') domain, COUNT(*) count
285
+ FROM moz_cookies
286
+ GROUP BY domain
287
+ HAVING count > :count
288
+ SQL
289
+
290
+ @st_delete_per_domain_overuse ||=
291
+ @db.prepare(<<-'SQL')
292
+ DELETE FROM moz_cookies WHERE id IN (
293
+ SELECT id FROM moz_cookies
294
+ WHERE LTRIM(host, '.') = :domain
295
+ ORDER BY creationtime
296
+ LIMIT :limit)
297
+ SQL
298
+ @st_delete_total_overuse ||=
299
+ @db.prepare(<<-'SQL')
300
+ DELETE FROM moz_cookies WHERE id IN (
301
+ SELECT id FROM moz_cookies ORDER BY creationTime ASC LIMIT :limit
302
+ )
303
+ SQL
304
+
305
+ @st_delete_expired.execute({ 'expiry' => now.to_i })
306
+
307
+ @st_overusing_domains.execute({
308
+ 'count' => HTTP::Cookie::MAX_COOKIES_PER_DOMAIN
309
+ }).each { |row|
310
+ domain, count = row['domain'], row['count']
311
+
312
+ @st_delete_per_domain_overuse.execute({
313
+ 'domain' => domain,
314
+ 'limit' => count - HTTP::Cookie::MAX_COOKIES_PER_DOMAIN,
315
+ })
316
+ }
317
+
318
+ overrun = count - HTTP::Cookie::MAX_COOKIES_TOTAL
319
+
320
+ if overrun > 0
321
+ @st_delete_total_overuse.execute({ 'limit' => overrun })
322
+ end
323
+
324
+ @gc_index = 0
325
+ end
326
+ end
327
+ end
@@ -162,6 +162,7 @@ class TestHTTPCookie < Test::Unit::TestCase
162
162
 
163
163
  assert_equal 'example.com', cookie.domain
164
164
  assert cookie.for_domain?
165
+ assert_equal '.example.com', cookie.dot_domain
165
166
  end
166
167
 
167
168
  def test_parse_domain_no_dot
@@ -173,6 +174,7 @@ class TestHTTPCookie < Test::Unit::TestCase
173
174
 
174
175
  assert_equal 'example.com', cookie.domain
175
176
  assert cookie.for_domain?
177
+ assert_equal '.example.com', cookie.dot_domain
176
178
  end
177
179
 
178
180
  def test_parse_domain_none
@@ -184,6 +186,7 @@ class TestHTTPCookie < Test::Unit::TestCase
184
186
 
185
187
  assert_equal 'example.com', cookie.domain
186
188
  assert !cookie.for_domain?
189
+ assert_equal 'example.com', cookie.dot_domain
187
190
  end
188
191
 
189
192
  def test_parse_max_age
@@ -360,20 +360,31 @@ class TestHTTPCookieJar < Test::Unit::TestCase
360
360
  :value => 'Foo#Baz',
361
361
  :path => '/foo/',
362
362
  :for_domain => false))
363
+ h_cookie = HTTP::Cookie.new(cookie_values(:name => 'Quux',
364
+ :value => 'Foo#Quux',
365
+ :httponly => true))
363
366
 
364
367
  @jar.add(cookie)
365
368
  @jar.add(s_cookie)
366
369
  @jar.add(cookie2)
370
+ @jar.add(h_cookie)
367
371
 
368
- assert_equal(3, @jar.cookies(url).length)
372
+ assert_equal(4, @jar.cookies(url).length)
369
373
 
370
374
  Dir.mktmpdir do |dir|
371
- @jar.save(File.join(dir, "cookies.txt"), :cookiestxt)
375
+ filename = File.join(dir, "cookies.txt")
376
+ @jar.save(filename, :cookiestxt)
377
+
378
+ content = File.read(filename)
379
+
380
+ assert_match(/^\.rubyforge\.org\t.*\tFoo\t/, content)
381
+ assert_match(/^rubyforge\.org\t.*\tBaz\t/, content)
382
+ assert_match(/^#HttpOnly_\.rubyforge\.org\t/, content)
372
383
 
373
384
  jar = HTTP::CookieJar.new
374
- jar.load(File.join(dir, "cookies.txt"), :cookiestxt) # HACK test the format
385
+ jar.load(filename, :cookiestxt) # HACK test the format
375
386
  cookies = jar.cookies(url)
376
- assert_equal(2, cookies.length)
387
+ assert_equal(3, cookies.length)
377
388
  cookies.each { |cookie|
378
389
  case cookie.name
379
390
  when 'Foo'
@@ -382,18 +393,27 @@ class TestHTTPCookieJar < Test::Unit::TestCase
382
393
  assert_equal 'rubyforge.org', cookie.domain
383
394
  assert_equal true, cookie.for_domain
384
395
  assert_equal '/', cookie.path
396
+ assert_equal false, cookie.httponly?
385
397
  when 'Baz'
386
398
  assert_equal 'Foo#Baz', cookie.value
387
399
  assert_equal 'rubyforge.org', cookie.domain
388
400
  assert_equal false, cookie.for_domain
389
401
  assert_equal '/foo/', cookie.path
402
+ assert_equal false, cookie.httponly?
403
+ when 'Quux'
404
+ assert_equal 'Foo#Quux', cookie.value
405
+ assert_equal expires, cookie.expires
406
+ assert_equal 'rubyforge.org', cookie.domain
407
+ assert_equal true, cookie.for_domain
408
+ assert_equal '/', cookie.path
409
+ assert_equal true, cookie.httponly?
390
410
  else
391
411
  raise
392
412
  end
393
413
  }
394
414
  end
395
415
 
396
- assert_equal(3, @jar.cookies(url).length)
416
+ assert_equal(4, @jar.cookies(url).length)
397
417
  end
398
418
 
399
419
  def test_expire_cookies
@@ -514,8 +534,7 @@ class TestHTTPCookieJar < Test::Unit::TestCase
514
534
  assert_equal('Foo1 Foo2', @jar.cookies(surl).map { |c| c.name }.sort.join(' ') )
515
535
  end
516
536
 
517
- def test_max_cookies
518
- jar = HTTP::CookieJar.new
537
+ def h_test_max_cookies(jar, slimit)
519
538
  limit_per_domain = HTTP::Cookie::MAX_COOKIES_PER_DOMAIN
520
539
  uri = URI('http://www.example.org/')
521
540
  date = Time.at(Time.now.to_i + 86400)
@@ -540,7 +559,6 @@ class TestHTTPCookieJar < Test::Unit::TestCase
540
559
  }.sort
541
560
 
542
561
  hlimit = HTTP::Cookie::MAX_COOKIES_TOTAL
543
- slimit = hlimit + HTTP::CookieJar::HashStore::GC_THRESHOLD
544
562
 
545
563
  n = hlimit / limit_per_domain * 2
546
564
 
@@ -569,4 +587,23 @@ class TestHTTPCookieJar < Test::Unit::TestCase
569
587
  cookie.domain == cookie.value
570
588
  }
571
589
  end
590
+
591
+ def test_max_cookies_hashstore
592
+ gc_threshold = 150
593
+ h_test_max_cookies(
594
+ HTTP::CookieJar.new(:hash,
595
+ :gc_threshold => gc_threshold),
596
+ HTTP::Cookie::MAX_COOKIES_TOTAL + gc_threshold)
597
+ end
598
+
599
+ def test_max_cookies_mozillastore
600
+ gc_threshold = 150
601
+ Dir.mktmpdir { |dir|
602
+ h_test_max_cookies(
603
+ HTTP::CookieJar.new(:mozilla,
604
+ :gc_threshold => gc_threshold,
605
+ :filename => File.join(dir, "cookies.sqlite")),
606
+ HTTP::Cookie::MAX_COOKIES_TOTAL + gc_threshold)
607
+ }
608
+ end
572
609
  end
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.pre2
4
+ version: 1.0.0.pre3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akinori MUSHA
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-03-22 00:00:00.000000000 Z
14
+ date: 2013-03-27 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: domain_name
@@ -27,6 +27,20 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0.5'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sqlite3
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ~>
35
+ - !ruby/object:Gem::Version
36
+ version: 1.3.3
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.3.3
30
44
  - !ruby/object:Gem::Dependency
31
45
  name: bundler
32
46
  requirement: !ruby/object:Gem::Requirement
@@ -125,6 +139,7 @@ files:
125
139
  - lib/http/cookie_jar/abstract_store.rb
126
140
  - lib/http/cookie_jar/cookiestxt_saver.rb
127
141
  - lib/http/cookie_jar/hash_store.rb
142
+ - lib/http/cookie_jar/mozilla_store.rb
128
143
  - lib/http/cookie_jar/yaml_saver.rb
129
144
  - test/helper.rb
130
145
  - test/simplecov_start.rb