Class: HTTP::CookieJar::MozillaStore
- Inherits:
-
AbstractStore
- Object
- AbstractStore
- HTTP::CookieJar::MozillaStore
- Defined in:
- lib/http/cookie_jar/mozilla_store.rb
Overview
A store class that uses Mozilla compatible SQLite3 database as backing store.
Session cookies are stored separately on memory and will not be stored persistently in the SQLite3 database.
Defined Under Namespace
Classes: Database
Constant Summary collapse
- SCHEMA_VERSION =
:stopdoc:
7
- ALL_COLUMNS =
%w[ baseDomain originAttributes name value host path expiry creationTime lastAccessed isSecure isHttpOnly appId inBrowserElement ]
- SQL =
{}
- Callable =
proc { |obj, meth, *args| proc { obj.__send__(meth, *args) } }
Instance Attribute Summary collapse
-
#filename ⇒ Object
readonly
The file name of the SQLite3 database given in initialization.
Instance Method Summary collapse
- #add(cookie) ⇒ Object
- #cleanup(session = false) ⇒ Object
- #clear ⇒ Object
-
#close ⇒ Object
Closes the SQLite3 database.
-
#closed? ⇒ Boolean
Tests if the SQLite3 database is closed.
- #default_options ⇒ Object
- #delete(cookie) ⇒ Object
-
#each(uri = nil, &block) ⇒ Object
:yield: cookie.
-
#initialize(options = nil) ⇒ MozillaStore
constructor
:call-seq: new(**options).
-
#initialize_copy(other) ⇒ Object
Raises TypeError.
-
#schema_version ⇒ Object
Returns the schema version of the database.
Methods inherited from AbstractStore
class_to_symbol, #empty?, implementation, inherited
Constructor Details
#initialize(options = nil) ⇒ MozillaStore
:call-seq:
new(**)
Generates a Mozilla cookie store. If the file does not exist, it is created. If it does and its schema is old, it is automatically upgraded with a new schema keeping the existing data.
Available option keywords are as below:
:filename : A file name of the SQLite3 database to open. This option is mandatory.
:gc_threshold : GC threshold; A GC happens when this many times cookies have been stored (default: ‘HTTP::Cookie::MAX_COOKIES_TOTAL / 20`)
:app_id : application ID (default: ‘0`) to have per application jar.
:in_browser_element : a flag to tell if cookies are stored in an in browser element. (default: ‘false`)
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 92 def initialize( = nil) super @origin_attributes = encode_www_form({}.tap { |params| params['appId'] = @app_id if @app_id.nonzero? params['inBrowserElement'] = 1 if @in_browser_element }) @filename = [:filename] or raise ArgumentError, ':filename option is missing' @sjar = HTTP::CookieJar::HashStore.new @db = Database.new(@filename) @stmt = Hash.new { |st, key| st[key] = @db.prepare(SQL[key]) } ObjectSpace.define_finalizer(self, Callable[@db, :close]) upgrade_database @gc_index = 0 end |
Instance Attribute Details
#filename ⇒ Object (readonly)
The file name of the SQLite3 database given in initialization.
123 124 125 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 123 def filename @filename end |
Instance Method Details
#add(cookie) ⇒ Object
422 423 424 425 426 427 428 429 430 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 422 def add() if .session? @sjar.add() db_delete() else @sjar.delete() db_add() end end |
#cleanup(session = false) ⇒ Object
551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 551 def cleanup(session = false) synchronize { break if @gc_index == 0 @stmt[:delete_expired].execute({ 'expiry' => Time.now.to_i }) @stmt[:overusing_domains].execute({ 'count' => HTTP::Cookie::MAX_COOKIES_PER_DOMAIN }).each { |row| domain, count = row['domain'], row['count'] @stmt[:delete_per_domain_overuse].execute({ 'domain' => domain, 'limit' => count - HTTP::Cookie::MAX_COOKIES_PER_DOMAIN, }) } overrun = count - HTTP::Cookie::MAX_COOKIES_TOTAL if overrun > 0 @stmt[:delete_total_overuse].execute({ 'limit' => overrun }) end @gc_index = 0 } self end |
#clear ⇒ Object
520 521 522 523 524 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 520 def clear @db.execute("DELETE FROM moz_cookies") @sjar.clear self end |
#close ⇒ Object
Closes the SQLite3 database. After closing, any operation may raise an error.
127 128 129 130 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 127 def close @db.closed? || @db.close self end |
#closed? ⇒ Boolean
Tests if the SQLite3 database is closed.
133 134 135 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 133 def closed? @db.closed? end |
#default_options ⇒ Object
15 16 17 18 19 20 21 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 15 def { :gc_threshold => HTTP::Cookie::MAX_COOKIES_TOTAL / 20, :app_id => 0, :in_browser_element => false, } end |
#delete(cookie) ⇒ Object
432 433 434 435 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 432 def delete() @sjar.delete() db_delete() end |
#each(uri = nil, &block) ⇒ Object
:yield: cookie
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 458 def each(uri = nil, &block) # :yield: cookie now = Time.now if uri thost = DomainName.new(uri.host) @stmt[:cookies_for_domain].execute({ :baseDomain => thost.domain || thost.hostname, :appId => @app_id, :inBrowserElement => @in_browser_element ? 1 : 0, :expiry => now.to_i, }).each { |row| if secure = row['isSecure'] != 0 next unless URI::HTTPS === uri end = HTTP::Cookie.new({}.tap { |attrs| attrs[:name] = row['name'] attrs[:value] = row['value'] attrs[:domain] = row['host'] attrs[:path] = row['path'] attrs[:expires_at] = Time.at(row['expiry']) attrs[:accessed_at] = deserialize_usectime(row['lastAccessed']) attrs[:created_at] = deserialize_usectime(row['creationTime']) attrs[:secure] = secure attrs[:httponly] = row['isHttpOnly'] != 0 }) if .valid_for_uri?(uri) .accessed_at = now @stmt[:update_lastaccessed].execute({ 'lastAccessed' => serialize_usectime(now), 'id' => row['id'], }) yield end } @sjar.each(uri, &block) else @stmt[:all_cookies].execute({ :appId => @app_id, :inBrowserElement => @in_browser_element ? 1 : 0, :expiry => now.to_i, }).each { |row| = HTTP::Cookie.new({}.tap { |attrs| attrs[:name] = row['name'] attrs[:value] = row['value'] attrs[:domain] = row['host'] attrs[:path] = row['path'] attrs[:expires_at] = Time.at(row['expiry']) attrs[:accessed_at] = deserialize_usectime(row['lastAccessed']) attrs[:created_at] = deserialize_usectime(row['creationTime']) attrs[:secure] = row['isSecure'] != 0 attrs[:httponly] = row['isHttpOnly'] != 0 }) yield } @sjar.each(&block) end self end |
#initialize_copy(other) ⇒ Object
Raises TypeError. Cloning is inhibited in this store class.
118 119 120 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 118 def initialize_copy(other) raise TypeError, 'can\'t clone %s' % self.class end |
#schema_version ⇒ Object
Returns the schema version of the database.
138 139 140 141 142 143 |
# File 'lib/http/cookie_jar/mozilla_store.rb', line 138 def schema_version @schema_version ||= @db.execute("PRAGMA user_version").first["user_version"] rescue SQLite3::SQLException @logger.warn "couldn't get schema version!" if @logger return nil end |