Class: Faraday::Adapter::HTTPClient

Inherits:
Faraday::Adapter show all
Defined in:
lib/faraday/adapter/httpclient.rb

Overview

HTTPClient adapter.

Constant Summary

Constants inherited from Faraday::Adapter

CONTENT_LENGTH

Instance Attribute Summary

Attributes included from DependencyLoader

#load_error

Attributes included from Parallelism

#supports_parallel

Instance Method Summary collapse

Methods inherited from Faraday::Adapter

#initialize

Methods included from MiddlewareRegistry

#fetch_middleware, #load_middleware, #lookup_middleware, #middleware_mutex, #register_middleware, #unregister_middleware

Methods included from DependencyLoader

#dependency, #inherited, #loaded?, #new

Methods included from Parallelism

#inherited, #supports_parallel?

Methods included from Faraday::AutoloadHelper

#all_loaded_constants, #autoload_all, #load_autoloaded_constants

Constructor Details

This class inherits a constructor from Faraday::Adapter

Instance Method Details

#call(env) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/faraday/adapter/httpclient.rb', line 14

def call(env)
  super

  # enable compression
  client.transparent_gzip_decompression = true

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

    if (bind = req[:bind])
      configure_socket bind
    end

    configure_timeouts req
  end

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

  configure_client

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

  resp = client.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
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) && e.is_a?(OpenSSL::SSL::SSLError)
    raise Faraday::SSLError, e
  end

  raise
end

#clientHTTPClient

Returns:



10
11
12
# File 'lib/faraday/adapter/httpclient.rb', line 10

def client
  @client ||= ::HTTPClient.new
end

#configure_clientObject



119
120
121
# File 'lib/faraday/adapter/httpclient.rb', line 119

def configure_client
  @config_block&.call(client)
end

#configure_open_timeout(req) ⇒ Object



114
115
116
117
# File 'lib/faraday/adapter/httpclient.rb', line 114

def configure_open_timeout(req)
  client.connect_timeout   = req[:open_timeout]
  client.send_timeout      = req[:open_timeout]
end

#configure_proxy(proxy) ⇒ Object

Configure proxy URI and any user credentials.

Parameters:

  • proxy (Hash)


82
83
84
85
86
87
# File 'lib/faraday/adapter/httpclient.rb', line 82

def configure_proxy(proxy)
  client.proxy = proxy[:uri]
  return unless proxy[:user] && proxy[:password]

  client.set_proxy_auth(proxy[:user], proxy[:password])
end

#configure_socket(bind) ⇒ Object

Parameters:

  • bind (Hash)


74
75
76
77
# File 'lib/faraday/adapter/httpclient.rb', line 74

def configure_socket(bind)
  client.socket_local.host = bind[:host]
  client.socket_local.port = bind[:port]
end

#configure_ssl(ssl) ⇒ Object

Parameters:

  • ssl (Hash)


90
91
92
93
94
95
96
97
98
99
100
# File 'lib/faraday/adapter/httpclient.rb', line 90

def configure_ssl(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_timeout(req) ⇒ Object



108
109
110
111
112
# File 'lib/faraday/adapter/httpclient.rb', line 108

def configure_timeout(req)
  client.connect_timeout   = req[:timeout]
  client.receive_timeout   = req[:timeout]
  client.send_timeout      = req[:timeout]
end

#configure_timeouts(req) ⇒ Object

Parameters:

  • req (Hash)


103
104
105
106
# File 'lib/faraday/adapter/httpclient.rb', line 103

def configure_timeouts(req)
  configure_timeout(req) if req[:timeout]
  configure_open_timeout(req) if req[:open_timeout]
end

#ssl_cert_store(ssl) ⇒ OpenSSL::X509::Store

Parameters:

  • ssl (Hash)

Returns:

  • (OpenSSL::X509::Store)


125
126
127
128
129
130
131
132
133
134
135
# File 'lib/faraday/adapter/httpclient.rb', line 125

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
  @ssl_cert_store ||= begin
    # Use the default cert store by default, i.e. system ca certs
    OpenSSL::X509::Store.new.tap(&:set_default_paths)
  end
end

#ssl_verify_mode(ssl) ⇒ Object

Parameters:

  • ssl (Hash)


138
139
140
141
142
143
144
145
146
147
# File 'lib/faraday/adapter/httpclient.rb', line 138

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