diff --git a/lib/http/cookie.rb b/lib/http/cookie.rb index 01e8254..278036a 100644 --- a/lib/http/cookie.rb +++ b/lib/http/cookie.rb @@ -4,10 +4,7 @@ require 'uri' require 'domain_name' require 'http/cookie/ruby_compat' - -module HTTP - autoload :CookieJar, 'http/cookie_jar' -end +require 'http/cookie_jar' # This class is used to represent an HTTP Cookie. class HTTP::Cookie diff --git a/lib/http/cookie_jar.rb b/lib/http/cookie_jar.rb index ef5429b..dd2faf7 100644 --- a/lib/http/cookie_jar.rb +++ b/lib/http/cookie_jar.rb @@ -1,31 +1,10 @@ # :markup: markdown -require 'http/cookie' ## # This class is used to manage the Cookies that have been returned from # any particular website. class HTTP::CookieJar - class << self - def const_missing(name) - case name.to_s - when /\A([A-Za-z]+)Store\z/ - file = 'http/cookie_jar/%s_store' % $1.downcase - when /\A([A-Za-z]+)Saver\z/ - file = 'http/cookie_jar/%s_saver' % $1.downcase - end - begin - require file - rescue LoadError - raise NameError, 'can\'t resolve constant %s; failed to load %s' % [name, file] - end - if const_defined?(name) - const_get(name) - else - raise NameError, 'can\'t resolve constant %s after loading %s' % [name, file] - end - end - end attr_reader :store @@ -342,3 +321,6 @@ def cleanup(session = false) self end end + +require 'http/cookie_jar/abstract_store' +require 'http/cookie_jar/abstract_saver' diff --git a/lib/http/cookie_jar/abstract_saver.rb b/lib/http/cookie_jar/abstract_saver.rb index 9d82873..758f5e5 100644 --- a/lib/http/cookie_jar/abstract_saver.rb +++ b/lib/http/cookie_jar/abstract_saver.rb @@ -2,29 +2,15 @@ # An abstract superclass for all saver classes. class HTTP::CookieJar::AbstractSaver - class << self - @@class_map = {} - # Gets an implementation class by the name, optionally trying to - # load "http/cookie_jar/*_saver" if not found. If loading fails, - # IndexError is raised. - def implementation(symbol) - @@class_map.fetch(symbol) - rescue IndexError - begin - require 'http/cookie_jar/%s_saver' % symbol - @@class_map.fetch(symbol) - rescue LoadError, IndexError - raise IndexError, 'cookie saver unavailable: %s' % symbol.inspect - end - end - - def inherited(subclass) # :nodoc: - @@class_map[class_to_symbol(subclass)] = subclass - end - - def class_to_symbol(klass) # :nodoc: - klass.name[/[^:]+?(?=Saver$|$)/].downcase.to_sym + def self.implementation(symbol) + case symbol + when :yaml + HTTP::CookieJar::YAMLSaver + when :cookiestxt + HTTP::CookieJar::CookiestxtSaver + else + raise IndexError, 'cookie saver unavailable: %s' % symbol.inspect end end @@ -63,3 +49,6 @@ def load(io, jar) # self end end + +require "http/cookie_jar/yaml_saver" +require "http/cookie_jar/cookiestxt_saver" diff --git a/lib/http/cookie_jar/abstract_store.rb b/lib/http/cookie_jar/abstract_store.rb index 9c062ed..773b081 100644 --- a/lib/http/cookie_jar/abstract_store.rb +++ b/lib/http/cookie_jar/abstract_store.rb @@ -6,29 +6,18 @@ class HTTP::CookieJar::AbstractStore include MonitorMixin class << self - @@class_map = {} - # Gets an implementation class by the name, optionally trying to - # load "http/cookie_jar/*_store" if not found. If loading fails, - # IndexError is raised. + # Gets an implementation class by the name. def implementation(symbol) - @@class_map.fetch(symbol) - rescue IndexError - begin - require 'http/cookie_jar/%s_store' % symbol - @@class_map.fetch(symbol) - rescue LoadError, IndexError => e - raise IndexError, 'cookie store unavailable: %s, error: %s' % symbol.inspect, e.message + case symbol + when :hash + HTTP::CookieJar::HashStore + when :mozilla + HTTP::CookieJar::MozillaStore + else + raise IndexError, 'cookie store unavailable: %s' % symbol.inspect end end - - def inherited(subclass) # :nodoc: - @@class_map[class_to_symbol(subclass)] = subclass - end - - def class_to_symbol(klass) # :nodoc: - klass.name[/[^:]+?(?=Store$|$)/].downcase.to_sym - end end # Defines options and their default values. @@ -122,3 +111,16 @@ def cleanup(session = false) # self end end + +require 'http/cookie_jar/hash_store' + +# Skip loading MozillaStore on JRuby. +if defined?(JRUBY_VERSION) + class HTTP::CookieJar::MozillaStore + def initialize(*) + raise ArgumentError, "MozillaStore is not supported on JRuby" + end + end +else + require 'http/cookie_jar/mozilla_store' +end diff --git a/lib/http/cookie_jar/cookiestxt_saver.rb b/lib/http/cookie_jar/cookiestxt_saver.rb index df0ca01..7b0d57c 100644 --- a/lib/http/cookie_jar/cookiestxt_saver.rb +++ b/lib/http/cookie_jar/cookiestxt_saver.rb @@ -1,5 +1,4 @@ # :markup: markdown -require 'http/cookie_jar' # CookiestxtSaver saves and loads cookies in the cookies.txt format. class HTTP::CookieJar::CookiestxtSaver < HTTP::CookieJar::AbstractSaver diff --git a/lib/http/cookie_jar/hash_store.rb b/lib/http/cookie_jar/hash_store.rb index 258be46..cff4caa 100644 --- a/lib/http/cookie_jar/hash_store.rb +++ b/lib/http/cookie_jar/hash_store.rb @@ -1,5 +1,4 @@ # :markup: markdown -require 'http/cookie_jar' class HTTP::CookieJar # A store class that uses a hash-based cookie store. diff --git a/lib/http/cookie_jar/mozilla_store.rb b/lib/http/cookie_jar/mozilla_store.rb index 03433a7..ec52205 100644 --- a/lib/http/cookie_jar/mozilla_store.rb +++ b/lib/http/cookie_jar/mozilla_store.rb @@ -1,6 +1,5 @@ # :markup: markdown -require 'http/cookie_jar' -require 'sqlite3' +autoload :SQLite3, 'sqlite3' class HTTP::CookieJar # A store class that uses Mozilla compatible SQLite3 database as diff --git a/lib/http/cookie_jar/yaml_saver.rb b/lib/http/cookie_jar/yaml_saver.rb index bc83f04..1b362b6 100644 --- a/lib/http/cookie_jar/yaml_saver.rb +++ b/lib/http/cookie_jar/yaml_saver.rb @@ -1,7 +1,5 @@ # :markup: markdown -require 'http/cookie_jar' -require 'psych' if !defined?(YAML) && RUBY_VERSION == "1.9.2" -require 'yaml' +autoload :YAML, 'yaml' # YAMLSaver saves and loads cookies in the YAML format. It can load a # YAML file saved by Mechanize, but the saving format is not @@ -74,13 +72,9 @@ def default_options {} end - if YAML.name == 'Psych' && Psych::VERSION >= '3.1' - def load_yaml(yaml) - YAML.safe_load(yaml, :permitted_classes => %w[Time HTTP::Cookie Mechanize::Cookie DomainName], :aliases => true) - end - else - def load_yaml(yaml) - YAML.load(yaml) - end + def load_yaml(yaml) + YAML.safe_load(yaml, :permitted_classes => %w[Time HTTP::Cookie Mechanize::Cookie DomainName], :aliases => true) + rescue NoMethodError # ruby < 2.0, no safe_load + YAML.load(yaml) end end diff --git a/test/test_http_cookie_jar.rb b/test/test_http_cookie_jar.rb index 8f57abf..24a4e09 100644 --- a/test/test_http_cookie_jar.rb +++ b/test/test_http_cookie_jar.rb @@ -10,17 +10,8 @@ def test_nonexistent_store end def test_erroneous_store - Dir.mktmpdir { |dir| - Dir.mkdir(File.join(dir, 'http')) - Dir.mkdir(File.join(dir, 'http', 'cookie_jar')) - rb = File.join(dir, 'http', 'cookie_jar', 'erroneous_store.rb') - File.open(rb, 'w').close - $LOAD_PATH.unshift(dir) - - assert_raises(NameError) { - HTTP::CookieJar::ErroneousStore - } - assert($LOADED_FEATURES.any? { |file| FileTest.identical?(file, rb) }) + assert_raises(NameError) { + HTTP::CookieJar::ErroneousStore } end @@ -31,17 +22,8 @@ def test_nonexistent_saver end def test_erroneous_saver - Dir.mktmpdir { |dir| - Dir.mkdir(File.join(dir, 'http')) - Dir.mkdir(File.join(dir, 'http', 'cookie_jar')) - rb = File.join(dir, 'http', 'cookie_jar', 'erroneous_saver.rb') - File.open(rb, 'w').close - $LOAD_PATH.unshift(dir) - - assert_raises(NameError) { - HTTP::CookieJar::ErroneousSaver - } - assert($LOADED_FEATURES.any? { |file| FileTest.identical?(file, rb) }) + assert_raises(NameError) { + HTTP::CookieJar::ErroneousSaver } end end