diff --git a/lib/httpx/options.rb b/lib/httpx/options.rb index b53e6b78..fae71577 100644 --- a/lib/httpx/options.rb +++ b/lib/httpx/options.rb @@ -30,6 +30,7 @@ module HTTPX :request_body_class => Class.new(Request::Body), :response_body_class => Class.new(Response::Body), :connection_class => Class.new(Connection), + :options_class => Class.new(self), :transport => nil, :transport_options => nil, :addresses => nil, @@ -56,24 +57,20 @@ module HTTPX attr_reader(optname) - alias_method(:"__set_#{optname}", meth) - class_eval(<<-OUT, __FILE__, __LINE__ + 1) def #{optname}=(value) return if value.nil? - value = __set_#{optname}(value) + value = #{meth}(value) - @#{optname} = value.freeze + @#{optname} = value end protected :#{optname}= OUT - - remove_method(meth) end def def_option(optname, *args, &block) - if args.size.zero? + if args.size.zero? && !block_given? class_eval(<<-OUT, __FILE__, __LINE__ + 1) def option_#{optname}(v); v; end OUT @@ -84,8 +81,8 @@ module HTTPX end def deprecated_def_option(optname, layout = nil, &interpreter) - warn "DEPRECATION WARNING: using `#{__method__}` for setting options is deprecated. " \ - "Use `def option_\#{optname}` instead." + warn "DEPRECATION WARNING: using `def_option(#{optname})` for setting options is deprecated. " \ + "Define module OptionsMethods and `def option_#{optname}(val)` instead." if layout class_eval(<<-OUT, __FILE__, __LINE__ + 1) @@ -94,7 +91,7 @@ module HTTPX end OUT elsif block_given? - define_method(:"option:#{name}") do |value| + define_method(:"option_#{optname}") do |value| instance_exec(value, &interpreter) end end @@ -171,7 +168,8 @@ module HTTPX %i[ params form json body ssl http2_settings - request_class response_class headers_class request_body_class response_body_class connection_class + request_class response_class headers_class request_body_class + response_body_class connection_class options_class io fallback_protocol debug debug_level transport_options resolver_class resolver_options persistent ].each do |method_name| diff --git a/lib/httpx/session.rb b/lib/httpx/session.rb index 374a5560..924740ea 100644 --- a/lib/httpx/session.rb +++ b/lib/httpx/session.rb @@ -247,9 +247,8 @@ module HTTPX if !@plugins.include?(pl) @plugins << pl pl.load_dependencies(self, &block) if pl.respond_to?(:load_dependencies) + @default_options = @default_options.dup - @default_options = pl.extra_options(@default_options, &block) if pl.respond_to?(:extra_options) - @default_options = @default_options.merge(options) if options include(pl::InstanceMethods) if defined?(pl::InstanceMethods) extend(pl::ClassMethods) if defined?(pl::ClassMethods) @@ -266,14 +265,26 @@ module HTTPX opts.response_body_class.__send__(:include, pl::ResponseBodyMethods) if defined?(pl::ResponseBodyMethods) opts.response_body_class.extend(pl::ResponseBodyClassMethods) if defined?(pl::ResponseBodyClassMethods) opts.connection_class.__send__(:include, pl::ConnectionMethods) if defined?(pl::ConnectionMethods) + if defined?(pl::OptionsMethods) + opts.options_class.__send__(:include, pl::OptionsMethods) + + (pl::OptionsMethods.instance_methods - Object.instance_methods).each do |meth| + opts.options_class.method_added(meth) + end + @default_options = opts.options_class.new(@default_options) + end + + @default_options = pl.extra_options(@default_options) if pl.respond_to?(:extra_options) + @default_options = @default_options.merge(options) if options + pl.configure(self, &block) if pl.respond_to?(:configure) @default_options.freeze elsif options # this can happen when two plugins are loaded, an one of them calls the other under the hood, # albeit changing some default. - @default_options = @default_options.dup - @default_options = @default_options.merge(options) + @default_options = pl.extra_options(@default_options) if pl.respond_to?(:extra_options) + @default_options = @default_options.merge(options) if options @default_options.freeze end diff --git a/test/options_test.rb b/test/options_test.rb index e05f569e..be116fdb 100644 --- a/test/options_test.rb +++ b/test/options_test.rb @@ -107,6 +107,7 @@ class OptionsTest < Minitest::Test :request_body_class => bar.request_body_class, :response_body_class => bar.response_body_class, :connection_class => bar.connection_class, + :options_class => bar.options_class, :transport => nil, :transport_options => nil, :addresses => nil, diff --git a/test/session_test.rb b/test/session_test.rb index 7ead3a79..ba053b66 100644 --- a/test/session_test.rb +++ b/test/session_test.rb @@ -169,6 +169,11 @@ class SessionTest < Minitest::Test self.class.foo end end + self::OptionsMethods = Module.new do + def option_foo(v) + v + end + end def self.load_dependencies(mod) mod.__send__(:include, Module.new do @@ -179,9 +184,7 @@ class SessionTest < Minitest::Test end def self.extra_options(options) - Class.new(options.class) do - def_option(:foo) - end.new(options).merge(foo: "options-foo") + options.merge(foo: "options-foo") end def self.configure(mod)