107 lines
3.0 KiB
Ruby
107 lines
3.0 KiB
Ruby
|
module Faraday
|
||
|
class Adapter
|
||
|
class HTTPClient < Faraday::Adapter
|
||
|
dependency 'httpclient'
|
||
|
|
||
|
def client
|
||
|
@client ||= ::HTTPClient.new
|
||
|
end
|
||
|
|
||
|
def call(env)
|
||
|
super
|
||
|
|
||
|
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
|
||
|
|
||
|
# 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]
|
||
|
|
||
|
save_response env, resp.status, resp.body, resp.headers
|
||
|
|
||
|
@app.call env
|
||
|
rescue ::HTTPClient::TimeoutError
|
||
|
raise Faraday::Error::TimeoutError, $!
|
||
|
rescue ::HTTPClient::BadResponseError => err
|
||
|
if err.message.include?('status 407')
|
||
|
raise Faraday::Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
|
||
|
else
|
||
|
raise Faraday::Error::ClientError, $!
|
||
|
end
|
||
|
rescue Errno::ECONNREFUSED, EOFError
|
||
|
raise Faraday::Error::ConnectionFailed, $!
|
||
|
rescue => err
|
||
|
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
|
||
|
raise Faraday::SSLError, err
|
||
|
else
|
||
|
raise
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def configure_socket(bind)
|
||
|
client.socket_local.host = bind[:host]
|
||
|
client.socket_local.port = bind[:port]
|
||
|
end
|
||
|
|
||
|
def configure_proxy(proxy)
|
||
|
client.proxy = proxy[:uri]
|
||
|
if proxy[:user] && proxy[:password]
|
||
|
client.set_proxy_auth proxy[:user], proxy[:password]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def configure_ssl(ssl)
|
||
|
ssl_config = client.ssl_config
|
||
|
|
||
|
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.cert_store = ssl[:cert_store] if ssl[:cert_store]
|
||
|
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]
|
||
|
ssl_config.verify_mode = ssl_verify_mode(ssl)
|
||
|
end
|
||
|
|
||
|
def configure_timeouts(req)
|
||
|
if req[:timeout]
|
||
|
client.connect_timeout = req[:timeout]
|
||
|
client.receive_timeout = req[:timeout]
|
||
|
client.send_timeout = req[:timeout]
|
||
|
end
|
||
|
|
||
|
if req[:open_timeout]
|
||
|
client.connect_timeout = req[:open_timeout]
|
||
|
client.send_timeout = req[:open_timeout]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
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
|
||
|
end
|
||
|
end
|
||
|
end
|