lib/httpx/options.rb in httpx-1.1.5 vs lib/httpx/options.rb in httpx-1.2.0
- old
+ new
@@ -9,10 +9,11 @@
BUFFER_SIZE = 1 << 14
WINDOW_SIZE = 1 << 14 # 16K
MAX_BODY_THRESHOLD_SIZE = (1 << 10) * 112 # 112K
KEEP_ALIVE_TIMEOUT = 20
SETTINGS_TIMEOUT = 10
+ CLOSE_HANDSHAKE_TIMEOUT = 10
CONNECT_TIMEOUT = READ_TIMEOUT = WRITE_TIMEOUT = 60
REQUEST_TIMEOUT = OPERATION_TIMEOUT = nil
# https://github.com/ruby/resolv/blob/095f1c003f6073730500f02acbdbc55f83d70987/lib/resolv.rb#L408
ip_address_families = begin
@@ -37,10 +38,11 @@
:decompress_response_body => true,
:compress_request_body => true,
:timeout => {
connect_timeout: CONNECT_TIMEOUT,
settings_timeout: SETTINGS_TIMEOUT,
+ close_handshake_timeout: CLOSE_HANDSHAKE_TIMEOUT,
operation_timeout: OPERATION_TIMEOUT,
keep_alive_timeout: KEEP_ALIVE_TIMEOUT,
read_timeout: READ_TIMEOUT,
write_timeout: WRITE_TIMEOUT,
request_timeout: REQUEST_TIMEOUT,
@@ -224,59 +226,114 @@
class_eval(<<-OUT, __FILE__, __LINE__ + 1)
def option_#{method_name}(v); v; end # def option_smth(v); v; end
OUT
end
- REQUEST_IVARS = %i[@params @form @xml @json @body].freeze
- private_constant :REQUEST_IVARS
+ REQUEST_BODY_IVARS = %i[@headers @params @form @xml @json @body].freeze
def ==(other)
- ivars = instance_variables | other.instance_variables
+ super || options_equals?(other)
+ end
+
+ def options_equals?(other, ignore_ivars = REQUEST_BODY_IVARS)
+ # headers and other request options do not play a role, as they are
+ # relevant only for the request.
+ ivars = instance_variables - ignore_ivars
+ other_ivars = other.instance_variables - ignore_ivars
+
+ return false if ivars.size != other_ivars.size
+
+ return false if ivars.sort != other_ivars.sort
+
ivars.all? do |ivar|
- case ivar
- when :@headers
- # currently, this is used to pick up an available matching connection.
- # the headers do not play a role, as they are relevant only for the request.
- true
- when *REQUEST_IVARS
- true
- else
- instance_variable_get(ivar) == other.instance_variable_get(ivar)
- end
+ instance_variable_get(ivar) == other.instance_variable_get(ivar)
end
end
+ OTHER_LOOKUP = ->(obj, k, ivar_map) {
+ case obj
+ when Hash
+ obj[ivar_map[k]]
+ else
+ obj.instance_variable_get(k)
+ end
+ }
def merge(other)
- raise ArgumentError, "#{other} is not a valid set of options" unless other.respond_to?(:to_hash)
+ ivar_map = nil
+ other_ivars = case other
+ when Hash
+ ivar_map = other.keys.to_h { |k| [:"@#{k}", k] }
+ ivar_map.keys
+ else
+ other.instance_variables
+ end
- h2 = other.to_hash
- return self if h2.empty?
+ return self if other_ivars.empty?
- h1 = to_hash
+ return self if other_ivars.all? { |ivar| instance_variable_get(ivar) == OTHER_LOOKUP[other, ivar, ivar_map] }
- return self if h1 >= h2
+ opts = dup
- merged = h1.merge(h2) do |_k, v1, v2|
- if v1.respond_to?(:merge) && v2.respond_to?(:merge)
- v1.merge(v2)
- else
- v2
+ other_ivars.each do |ivar|
+ v = OTHER_LOOKUP[other, ivar, ivar_map]
+
+ unless v
+ opts.instance_variable_set(ivar, v)
+ next
end
+
+ v = opts.__send__(:"option_#{ivar[1..-1]}", v)
+
+ orig_v = instance_variable_get(ivar)
+
+ v = orig_v.merge(v) if orig_v.respond_to?(:merge) && v.respond_to?(:merge)
+
+ opts.instance_variable_set(ivar, v)
end
- self.class.new(merged)
+ opts
end
def to_hash
instance_variables.each_with_object({}) do |ivar, hs|
hs[ivar[1..-1].to_sym] = instance_variable_get(ivar)
end
end
- def initialize_dup(other)
- instance_variables.each do |ivar|
- instance_variable_set(ivar, other.instance_variable_get(ivar).dup)
+ def extend_with_plugin_classes(pl)
+ if defined?(pl::RequestMethods) || defined?(pl::RequestClassMethods)
+ @request_class = @request_class.dup
+ @request_class.__send__(:include, pl::RequestMethods) if defined?(pl::RequestMethods)
+ @request_class.extend(pl::RequestClassMethods) if defined?(pl::RequestClassMethods)
end
+ if defined?(pl::ResponseMethods) || defined?(pl::ResponseClassMethods)
+ @response_class = @response_class.dup
+ @response_class.__send__(:include, pl::ResponseMethods) if defined?(pl::ResponseMethods)
+ @response_class.extend(pl::ResponseClassMethods) if defined?(pl::ResponseClassMethods)
+ end
+ if defined?(pl::HeadersMethods) || defined?(pl::HeadersClassMethods)
+ @headers_class = @headers_class.dup
+ @headers_class.__send__(:include, pl::HeadersMethods) if defined?(pl::HeadersMethods)
+ @headers_class.extend(pl::HeadersClassMethods) if defined?(pl::HeadersClassMethods)
+ end
+ if defined?(pl::RequestBodyMethods) || defined?(pl::RequestBodyClassMethods)
+ @request_body_class = @request_body_class.dup
+ @request_body_class.__send__(:include, pl::RequestBodyMethods) if defined?(pl::RequestBodyMethods)
+ @request_body_class.extend(pl::RequestBodyClassMethods) if defined?(pl::RequestBodyClassMethods)
+ end
+ if defined?(pl::ResponseBodyMethods) || defined?(pl::ResponseBodyClassMethods)
+ @response_body_class = @response_body_class.dup
+ @response_body_class.__send__(:include, pl::ResponseBodyMethods) if defined?(pl::ResponseBodyMethods)
+ @response_body_class.extend(pl::ResponseBodyClassMethods) if defined?(pl::ResponseBodyClassMethods)
+ end
+ if defined?(pl::ConnectionMethods)
+ @connection_class = @connection_class.dup
+ @connection_class.__send__(:include, pl::ConnectionMethods)
+ end
+ return unless defined?(pl::OptionsMethods)
+
+ @options_class = @options_class.dup
+ @options_class.__send__(:include, pl::OptionsMethods)
end
private
def do_initialize(options = {})