class Faraday::Adapter::HTTPClient

This class provides the main implementation for your adapter. There are some key responsibilities that your adapter should satisfy:

Public Instance Methods

build_connection(env) click to toggle source
# File lib/faraday/adapter/httpclient.rb, line 12
def build_connection(env)
  @client ||= ::HTTPClient.new.tap do |cli|
    # enable compression
    cli.transparent_gzip_decompression = true
  end

  if (req = env[:request])
    if (proxy = req[:proxy])
      configure_proxy @client, proxy
    end

    if (bind = req[:bind])
      configure_socket @client, bind
    end

    configure_timeouts @client, req
  end

  if env[:url].scheme == 'https' && (ssl = env[:ssl])
    configure_ssl @client, ssl
  end

  configure_client @client

  @client
end
call(env) click to toggle source
Calls superclass method
# File lib/faraday/adapter/httpclient.rb, line 39
def call(env)
  super

  # TODO: Don't stream yet.
  # https://github.com/nahi/httpclient/pull/90
  env[:body] = env[:body].read if env[:body].respond_to? :read

  connection(env) do |http|
    resp = http.request env[:method], env[:url],
                        body: env[:body],
                        header: env[:request_headers]

    if (req = env[:request]).stream_response?
      warn "Streaming downloads for #{self.class.name} " \
        'are not yet implemented.'
      req.on_data.call(resp.body, resp.body.bytesize)
    end
    save_response env, resp.status, resp.body, resp.headers, resp.reason

    @app.call env
  end
rescue ::HTTPClient::TimeoutError, Errno::ETIMEDOUT
  raise Faraday::TimeoutError, $ERROR_INFO
rescue ::HTTPClient::BadResponseError => e
  if e.message.include?('status 407')
    raise Faraday::ConnectionFailed,
          %(407 "Proxy Authentication Required ")
  end

  raise Faraday::ClientError, $ERROR_INFO
rescue Errno::EADDRNOTAVAIL, Errno::ECONNREFUSED, IOError, SocketError
  raise Faraday::ConnectionFailed, $ERROR_INFO
rescue StandardError => e
  if defined?(::OpenSSL::SSL::SSLError) && \
     e.is_a?(::OpenSSL::SSL::SSLError)
    raise Faraday::SSLError, e
  end

  raise
end
configure_client(client) click to toggle source
# File lib/faraday/adapter/httpclient.rb, line 124
def configure_client(client)
  @config_block&.call(client)
end
configure_proxy(client, proxy) click to toggle source

Configure proxy URI and any user credentials.

@param proxy [Hash]

# File lib/faraday/adapter/httpclient.rb, line 89
def configure_proxy(client, proxy)
  client.proxy = proxy[:uri]
  return unless proxy[:user] && proxy[:password]

  client.set_proxy_auth(proxy[:user], proxy[:password])
end
configure_socket(client, bind) click to toggle source

@param bind [Hash]

# File lib/faraday/adapter/httpclient.rb, line 81
def configure_socket(client, bind)
  client.socket_local.host = bind[:host]
  client.socket_local.port = bind[:port]
end
configure_ssl(client, ssl) click to toggle source

@param ssl [Hash]

# File lib/faraday/adapter/httpclient.rb, line 97
def configure_ssl(client, ssl)
  ssl_config = client.ssl_config
  ssl_config.verify_mode = ssl_verify_mode(ssl)
  ssl_config.cert_store = ssl_cert_store(ssl)

  ssl_config.add_trust_ca ssl[:ca_file] if ssl[:ca_file]
  ssl_config.add_trust_ca ssl[:ca_path] if ssl[:ca_path]
  ssl_config.client_cert = ssl[:client_cert] if ssl[:client_cert]
  ssl_config.client_key = ssl[:client_key] if ssl[:client_key]
  ssl_config.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
end
configure_timeouts(client, req) click to toggle source

@param req [Hash]

# File lib/faraday/adapter/httpclient.rb, line 110
def configure_timeouts(client, req)
  if (sec = request_timeout(:open, req))
    client.connect_timeout = sec
  end

  if (sec = request_timeout(:write, req))
    client.send_timeout = sec
  end

  return unless (sec = request_timeout(:read, req))

  client.receive_timeout = sec
end
ssl_cert_store(ssl) click to toggle source

@param ssl [Hash] @return [OpenSSL::X509::Store]

# File lib/faraday/adapter/httpclient.rb, line 130
def ssl_cert_store(ssl)
  return ssl[:cert_store] if ssl[:cert_store]

  # Memoize the cert store so that the same one is passed to
  # HTTPClient each time, to avoid resyncing SSL sessions when
  # it's changed

  # Use the default cert store by default, i.e. system ca certs
  @ssl_cert_store ||= OpenSSL::X509::Store.new.tap(&:set_default_paths)
end
ssl_verify_mode(ssl) click to toggle source

@param ssl [Hash]

# File lib/faraday/adapter/httpclient.rb, line 142
def ssl_verify_mode(ssl)
  ssl[:verify_mode] || begin
    if ssl.fetch(:verify, true)
      OpenSSL::SSL::VERIFY_PEER |
        OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
    else
      OpenSSL::SSL::VERIFY_NONE
    end
  end
end