class HTTParty::ConnectionAdapter
def self.call(uri, options)
def self.call(uri, options) new(uri, options).connection end
def self.default_cert_store
def self.default_cert_store @default_cert_store ||= OpenSSL::X509::Store.new.tap do |cert_store| cert_store.set_default_paths end end
def add_max_retries?(max_retries)
def add_max_retries?(max_retries) max_retries && max_retries.is_a?(Integer) && max_retries >= 0 end
def add_timeout?(timeout)
def add_timeout?(timeout) timeout && (timeout.is_a?(Integer) || timeout.is_a?(Float)) end
def attach_ssl_certificates(http, options)
def attach_ssl_certificates(http, options) if http.use_ssl? if options.fetch(:verify, true) http.verify_mode = OpenSSL::SSL::VERIFY_PEER if options[:cert_store] http.cert_store = options[:cert_store] else # Use the default cert store by default, i.e. system ca certs http.cert_store = self.class.default_cert_store end else http.verify_mode = OpenSSL::SSL::VERIFY_NONE end # Client certificate authentication # Note: options[:pem] must contain the content of a PEM file having the private key appended if options[:pem] http.cert = OpenSSL::X509::Certificate.new(options[:pem]) http.key = OpenSSL::PKey.read(options[:pem], options[:pem_password]) http.verify_mode = verify_ssl_certificate? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE end # PKCS12 client certificate authentication if options[:p12] p12 = OpenSSL::PKCS12.new(options[:p12], options[:p12_password]) http.cert = p12.certificate http.key = p12.key http.verify_mode = verify_ssl_certificate? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE end # SSL certificate authority file and/or directory if options[:ssl_ca_file] http.ca_file = options[:ssl_ca_file] http.verify_mode = OpenSSL::SSL::VERIFY_PEER end if options[:ssl_ca_path] http.ca_path = options[:ssl_ca_path] http.verify_mode = OpenSSL::SSL::VERIFY_PEER end # This is only Ruby 1.9+ if options[:ssl_version] && http.respond_to?(:ssl_version=) http.ssl_version = options[:ssl_version] end end end
def clean_host(host)
def clean_host(host) strip_ipv6_brackets(host) end
def connection
def connection host = clean_host(uri.host) port = uri.port || (uri.scheme == 'https' ? 443 : 80) if options.key?(:http_proxyaddr) http = Net::HTTP.new( host, port, options[:http_proxyaddr], options[:http_proxyport], options[:http_proxyuser], options[:http_proxypass] ) else http = Net::HTTP.new(host, port) end http.use_ssl = ssl_implied?(uri) attach_ssl_certificates(http, options) if add_timeout?(options[:timeout]) http.open_timeout = options[:timeout] http.read_timeout = options[:timeout] from_ruby_version('2.6.0', option: :write_timeout, warn: false) do http.write_timeout = options[:timeout] end end if add_timeout?(options[:read_timeout]) http.read_timeout = options[:read_timeout] end if add_timeout?(options[:open_timeout]) http.open_timeout = options[:open_timeout] end if add_timeout?(options[:write_timeout]) from_ruby_version('2.6.0', option: :write_timeout) do http.write_timeout = options[:write_timeout] end end if add_max_retries?(options[:max_retries]) from_ruby_version('2.5.0', option: :max_retries) do http.max_retries = options[:max_retries] end end if options[:debug_output] http.set_debug_output(options[:debug_output]) end if options[:ciphers] http.ciphers = options[:ciphers] end # Bind to a specific local address or port # # @see https://bugs.ruby-lang.org/issues/6617 if options[:local_host] from_ruby_version('2.0.0', option: :local_host) do http.local_host = options[:local_host] end end if options[:local_port] from_ruby_version('2.0.0', option: :local_port) do http.local_port = options[:local_port] end end http end
def from_ruby_version(ruby_version, option: nil, warn: true)
def from_ruby_version(ruby_version, option: nil, warn: true) if RUBY_VERSION >= ruby_version yield elsif warn Kernel.warn("Warning: option #{ option } requires Ruby version #{ ruby_version } or later") end end
def initialize(uri, options = {})
def initialize(uri, options = {}) uri_adapter = options[:uri_adapter] || URI raise ArgumentError, "uri must be a #{uri_adapter}, not a #{uri.class}" unless uri.is_a? uri_adapter @uri = uri @options = OPTION_DEFAULTS.merge(options) end
def ssl_implied?(uri)
def ssl_implied?(uri) uri.port == 443 || uri.scheme == 'https' end
def strip_ipv6_brackets(host)
def strip_ipv6_brackets(host) StripIpv6BracketsRegex =~ host ? $1 : host end
def verify_ssl_certificate?
def verify_ssl_certificate? !(options[:verify] == false || options[:verify_peer] == false) end