Contains a set of options which are passed and shared across from session to its requests or responses.
Methods
Public Class
Public Instance
Constants
BUFFER_SIZE | = | 1 << 14 | ||
CLOSE_HANDSHAKE_TIMEOUT | = | 10 | ||
CONNECT_TIMEOUT | = | READ_TIMEOUT = WRITE_TIMEOUT = 60 | ||
DEFAULT_OPTIONS | = | { :max_requests => Float::INFINITY, :debug => nil, :debug_level => (ENV["HTTPX_DEBUG"] || 1).to_i, :debug_redact => ENV.key?("HTTPX_DEBUG_REDACT"), :ssl => EMPTY_HASH, :http2_settings => { settings_enable_push: 0 }.freeze, :fallback_protocol => "http/1.1", :supported_compression_formats => %w[gzip deflate], :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, }.freeze, :headers_class => Class.new(Headers, &SET_TEMPORARY_NAME), :headers => EMPTY_HASH, :window_size => WINDOW_SIZE, :buffer_size => BUFFER_SIZE, :body_threshold_size => MAX_BODY_THRESHOLD_SIZE, :request_class => Class.new(Request, &SET_TEMPORARY_NAME), :response_class => Class.new(Response, &SET_TEMPORARY_NAME), :request_body_class => Class.new(Request::Body, &SET_TEMPORARY_NAME), :response_body_class => Class.new(Response::Body, &SET_TEMPORARY_NAME), :pool_class => Class.new(Pool, &SET_TEMPORARY_NAME), :connection_class => Class.new(Connection, &SET_TEMPORARY_NAME), :http1_class => Class.new(Connection::HTTP1, &SET_TEMPORARY_NAME), :http2_class => Class.new(Connection::HTTP2, &SET_TEMPORARY_NAME), :resolver_native_class => Class.new(Resolver::Native, &SET_TEMPORARY_NAME), :resolver_system_class => Class.new(Resolver::System, &SET_TEMPORARY_NAME), :resolver_https_class => Class.new(Resolver::HTTPS, &SET_TEMPORARY_NAME), :options_class => Class.new(self, &SET_TEMPORARY_NAME), :transport => nil, :addresses => nil, :persistent => false, :resolver_class => (ENV["HTTPX_RESOLVER"] || :native).to_sym, :resolver_options => { cache: true }.freeze, :pool_options => EMPTY_HASH, :ip_families => nil, :close_on_fork => false, }.freeze | ||
KEEP_ALIVE_TIMEOUT | = | 20 | ||
MAX_BODY_THRESHOLD_SIZE | = | (1 << 10) * 112 | ||
REQUEST_BODY_IVARS | = | %i[@headers].freeze | ||
REQUEST_TIMEOUT | = | OPERATION_TIMEOUT = nil | ||
SETTINGS_TIMEOUT | = | 10 | ||
SET_TEMPORARY_NAME | = | ->(klass, pl = nil) do if klass.respond_to?(:set_temporary_name) # ruby 3.4 only name = klass.name || "#{klass.superclass.name}(plugin)" name = "#{name}/#{pl}" if pl klass.set_temporary_name(name) end end | ||
USER_AGENT | = | "httpx.rb/#{VERSION}".freeze |
default value used for “user-agent” header, when not overridden. |
|
WINDOW_SIZE | = | 1 << 14 |
Attributes
options_names | [R] |
Public Class methods
# File lib/httpx/options.rb 37 def freeze 38 @options_names.freeze 39 super 40 end
# File lib/httpx/options.rb 24 def inherited(klass) 25 super 26 klass.instance_variable_set(:@options_names, @options_names.dup) 27 end
# File lib/httpx/options.rb 42 def method_added(meth) 43 super 44 45 return unless meth =~ /^option_(.+)$/ 46 47 optname = Regexp.last_match(1) 48 49 if optname =~ /^(.+[^_])_+with/ 50 # ignore alias method chain generated methods. 51 # this is the case with RBS runtime tests. 52 # it relies on the "_with/_without" separator, which is the most used convention, 53 # however it shouldn't be used in practice in httpx given the plugin architecture 54 # as the main extension API. 55 orig_name = Regexp.last_match(1) 56 57 return if @options_names.include?(orig_name.to_sym) 58 end 59 60 optname = optname.to_sym 61 62 attr_reader(optname) 63 64 @options_names << optname unless @options_names.include?(optname) 65 end
# File lib/httpx/options.rb 29 def new(options = {}) 30 # let enhanced options go through 31 return options if self == Options && options.class < self 32 return options if options.is_a?(self) 33 34 super 35 end
creates a new options instance from a given hash, which optionally define the following:
:debug |
an object which log messages are written to (must respond to |
:debug_level |
the log level of messages (can be 1, 2, or 3). |
:debug_redact |
whether header/body payload should be redacted (defaults to |
:ssl |
a hash of options which can be set as params of OpenSSL::SSL::SSLContext (see |
:http2_settings |
a hash of options to be passed to a HTTP2::Connection (ex: |
:fallback_protocol |
version of HTTP protocol to use by default in the absence of protocol negotiation like ALPN (defaults to |
:supported_compression_formats |
list of compressions supported by the transcoder layer (defaults to |
:decompress_response_body |
whether to auto-decompress response body (defaults to |
:compress_request_body |
whether to auto-decompress response body (defaults to |
:timeout |
hash of timeout configurations (supports |
:headers |
hash of HTTP headers (ex: |
:window_size |
number of bytes to read from a socket |
:buffer_size |
internal read and write buffer size in bytes |
:body_threshold_size |
maximum size in bytes of response payload that is buffered in memory. |
:request_class |
class used to instantiate a request |
:response_class |
class used to instantiate a response |
:headers_class |
class used to instantiate headers |
:request_body_class |
class used to instantiate a request body |
:response_body_class |
class used to instantiate a response body |
:connection_class |
class used to instantiate connections |
:http1_class |
class used to manage HTTP1 sessions |
:http2_class |
class used to imanage HTTP2 sessions |
:resolver_native_class |
class used to resolve names using pure ruby DNS implementation |
:resolver_system_class |
class used to resolve names using system-based (getaddrinfo) name resolution |
:resolver_https_class |
class used to resolve names using DoH |
:pool_class |
class used to instantiate the session connection pool |
:options_class |
class used to instantiate options |
:transport |
type of transport to use (set to “unix” for |
:addresses |
bucket of peer addresses (can be a list of IP addresses, a hash of domain to list of adddresses; paths should be used for |
:io |
open socket, or domain/ip-to-socket hash, which requests should be sent to |
:persistent |
whether to persist connections in between requests (defaults to |
:resolver_class |
which resolver to use (defaults to |
:resolver_options |
hash of options passed to the resolver. Accepted keys depend on the resolver type. |
:pool_options |
hash of options passed to the connection pool (See Pool#initialize). |
:ip_families |
which socket families are supported (system-dependent) |
:origin |
HTTP origin to set on requests with relative path (ex: “api.serv.com”) |
:base_path |
path to prefix given relative paths with (ex: “/v2”) |
:max_concurrent_requests |
max number of requests which can be set concurrently |
:max_requests |
max number of requests which can be made on socket before it reconnects. |
:close_on_fork |
whether the session automatically closes when the process is fork (defaults to |
This list of options are enhanced with each loaded plugin, see the plugin docs for details.
# File lib/httpx/options.rb 118 def initialize(options = EMPTY_HASH) 119 options_names = self.class.options_names 120 121 defaults = 122 case options 123 when Options 124 unknown_options = options.class.options_names - options_names 125 126 raise Error, "unknown option: #{unknown_options.first}" unless unknown_options.empty? 127 128 DEFAULT_OPTIONS.merge(options) 129 else 130 options.each_key do |k| 131 raise Error, "unknown option: #{k}" unless options_names.include?(k) 132 end 133 134 options.empty? ? DEFAULT_OPTIONS : DEFAULT_OPTIONS.merge(options) 135 end 136 137 options_names.each do |k| 138 v = defaults[k] 139 140 if v.nil? 141 instance_variable_set(:"@#{k}", v) 142 143 next 144 end 145 146 value = __send__(:"option_#{k}", v) 147 instance_variable_set(:"@#{k}", value) 148 end 149 150 do_initialize 151 freeze 152 end
Public Instance methods
# File lib/httpx/options.rb 171 def ==(other) 172 super || options_equals?(other) 173 end
# File lib/httpx/options.rb 237 def extend_with_plugin_classes(pl) 238 # extend request class 239 if defined?(pl::RequestMethods) || defined?(pl::RequestClassMethods) 240 @request_class = @request_class.dup 241 SET_TEMPORARY_NAME[@request_class, pl] 242 @request_class.__send__(:include, pl::RequestMethods) if defined?(pl::RequestMethods) 243 @request_class.extend(pl::RequestClassMethods) if defined?(pl::RequestClassMethods) 244 end 245 # extend response class 246 if defined?(pl::ResponseMethods) || defined?(pl::ResponseClassMethods) 247 @response_class = @response_class.dup 248 SET_TEMPORARY_NAME[@response_class, pl] 249 @response_class.__send__(:include, pl::ResponseMethods) if defined?(pl::ResponseMethods) 250 @response_class.extend(pl::ResponseClassMethods) if defined?(pl::ResponseClassMethods) 251 end 252 # extend headers class 253 if defined?(pl::HeadersMethods) || defined?(pl::HeadersClassMethods) 254 @headers_class = @headers_class.dup 255 SET_TEMPORARY_NAME[@headers_class, pl] 256 @headers_class.__send__(:include, pl::HeadersMethods) if defined?(pl::HeadersMethods) 257 @headers_class.extend(pl::HeadersClassMethods) if defined?(pl::HeadersClassMethods) 258 end 259 # extend request body class 260 if defined?(pl::RequestBodyMethods) || defined?(pl::RequestBodyClassMethods) 261 @request_body_class = @request_body_class.dup 262 SET_TEMPORARY_NAME[@request_body_class, pl] 263 @request_body_class.__send__(:include, pl::RequestBodyMethods) if defined?(pl::RequestBodyMethods) 264 @request_body_class.extend(pl::RequestBodyClassMethods) if defined?(pl::RequestBodyClassMethods) 265 end 266 # extend response body class 267 if defined?(pl::ResponseBodyMethods) || defined?(pl::ResponseBodyClassMethods) 268 @response_body_class = @response_body_class.dup 269 SET_TEMPORARY_NAME[@response_body_class, pl] 270 @response_body_class.__send__(:include, pl::ResponseBodyMethods) if defined?(pl::ResponseBodyMethods) 271 @response_body_class.extend(pl::ResponseBodyClassMethods) if defined?(pl::ResponseBodyClassMethods) 272 end 273 # extend connection pool class 274 if defined?(pl::PoolMethods) 275 @pool_class = @pool_class.dup 276 SET_TEMPORARY_NAME[@pool_class, pl] 277 @pool_class.__send__(:include, pl::PoolMethods) 278 end 279 # extend connection class 280 if defined?(pl::ConnectionMethods) 281 @connection_class = @connection_class.dup 282 SET_TEMPORARY_NAME[@connection_class, pl] 283 @connection_class.__send__(:include, pl::ConnectionMethods) 284 end 285 # extend http1 class 286 if defined?(pl::HTTP1Methods) 287 @http1_class = @http1_class.dup 288 SET_TEMPORARY_NAME[@http1_class, pl] 289 @http1_class.__send__(:include, pl::HTTP1Methods) 290 end 291 # extend http2 class 292 if defined?(pl::HTTP2Methods) 293 @http2_class = @http2_class.dup 294 SET_TEMPORARY_NAME[@http2_class, pl] 295 @http2_class.__send__(:include, pl::HTTP2Methods) 296 end 297 # extend native resolver class 298 if defined?(pl::ResolverNativeMethods) 299 @resolver_native_class = @resolver_native_class.dup 300 SET_TEMPORARY_NAME[@resolver_native_class, pl] 301 @resolver_native_class.__send__(:include, pl::ResolverNativeMethods) 302 end 303 # extend system resolver class 304 if defined?(pl::ResolverSystemMethods) 305 @resolver_system_class = @resolver_system_class.dup 306 SET_TEMPORARY_NAME[@resolver_system_class, pl] 307 @resolver_system_class.__send__(:include, pl::ResolverSystemMethods) 308 end 309 # extend https resolver class 310 if defined?(pl::ResolverHTTPSMethods) 311 @resolver_https_class = @resolver_https_class.dup 312 SET_TEMPORARY_NAME[@resolver_https_class, pl] 313 @resolver_https_class.__send__(:include, pl::ResolverHTTPSMethods) 314 end 315 316 return unless defined?(pl::OptionsMethods) 317 318 # extend option class 319 # works around lack of initialize_dup callback 320 @options_class = @options_class.dup 321 # (self.class.options_names) 322 @options_class.__send__(:include, pl::OptionsMethods) 323 end
# File lib/httpx/options.rb 154 def freeze 155 self.class.options_names.each do |ivar| 156 # avoid freezing debug option, as when it's set, it's usually an 157 # object which cannot be frozen, like stderr or stdout. It's a 158 # documented exception then, and still does not defeat the purpose 159 # here, which is to make option objects shareable across ractors, 160 # and in most cases debug should be nil, or one of the objects 161 # which will eventually be shareable, like STDOUT or STDERR. 162 next if ivar == :debug 163 164 instance_variable_get(:"@#{ivar}").freeze 165 end 166 super 167 end
# File lib/httpx/options.rb 190 def merge(other) 191 ivar_map = nil 192 other_ivars = case other 193 when Options 194 other.instance_variables 195 else 196 other = Hash[other] unless other.is_a?(Hash) 197 ivar_map = other.keys.to_h { |k| [:"@#{k}", k] } 198 ivar_map.keys 199 end 200 201 return self if other_ivars.empty? 202 203 return self if other_ivars.all? { |ivar| instance_variable_get(ivar) == access_option(other, ivar, ivar_map) } 204 205 opts = dup 206 207 other_ivars.each do |ivar| 208 v = access_option(other, ivar, ivar_map) 209 210 unless v 211 opts.instance_variable_set(ivar, v) 212 next 213 end 214 215 v = opts.__send__(:"option_#{ivar[1..-1]}", v) 216 217 orig_v = instance_variable_get(ivar) 218 219 v = orig_v.merge(v) if orig_v.respond_to?(:merge) && v.respond_to?(:merge) 220 221 opts.instance_variable_set(ivar, v) 222 end 223 224 opts 225 end
# File lib/httpx/options.rb 175 def options_equals?(other, ignore_ivars = REQUEST_BODY_IVARS) 176 # headers and other request options do not play a role, as they are 177 # relevant only for the request. 178 ivars = instance_variables - ignore_ivars 179 other_ivars = other.instance_variables - ignore_ivars 180 181 return false if ivars.size != other_ivars.size 182 183 return false if ivars.sort != other_ivars.sort 184 185 ivars.all? do |ivar| 186 instance_variable_get(ivar) == other.instance_variable_get(ivar) 187 end 188 end
# File lib/httpx/options.rb 227 def to_hash 228 instance_variables.each_with_object({}) do |ivar, hs| 229 val = instance_variable_get(ivar) 230 231 next if val.nil? 232 233 hs[ivar[1..-1].to_sym] = val 234 end 235 end