twitter-status-bot/.gems/gems/faraday-0.9.0/lib/faraday/adapter/typhoeus.rb

124 lines
3.6 KiB
Ruby

module Faraday
class Adapter
class Typhoeus < Faraday::Adapter
self.supports_parallel = true
def self.setup_parallel_manager(options = {})
options.empty? ? ::Typhoeus::Hydra.hydra : ::Typhoeus::Hydra.new(options)
end
dependency 'typhoeus'
def call(env)
super
perform_request env
@app.call env
end
def perform_request(env)
read_body env
hydra = env[:parallel_manager] || self.class.setup_parallel_manager
hydra.queue request(env)
hydra.run unless parallel?(env)
rescue Errno::ECONNREFUSED
raise Error::ConnectionFailed, $!
end
# TODO: support streaming requests
def read_body(env)
env[:body] = env[:body].read if env[:body].respond_to? :read
end
def request(env)
method = env[:method]
# For some reason, prevents Typhoeus from using "100-continue".
# We want this because Webrick 1.3.1 can't seem to handle it w/ PUT.
method = method.to_s.upcase if method == :put
req = ::Typhoeus::Request.new env[:url].to_s,
:method => method,
:body => env[:body],
:headers => env[:request_headers],
:disable_ssl_peer_verification => (env[:ssl] && env[:ssl].disable?)
configure_ssl req, env
configure_proxy req, env
configure_timeout req, env
configure_socket req, env
req.on_complete do |resp|
if resp.timed_out?
if parallel?(env)
# TODO: error callback in async mode
else
raise Faraday::Error::TimeoutError, "request timed out"
end
end
case resp.curl_return_code
when 0
# everything OK
when 7
raise Error::ConnectionFailed, resp.curl_error_message
when 60
raise Faraday::SSLError, resp.curl_error_message
else
raise Error::ClientError, resp.curl_error_message
end
save_response(env, resp.code, resp.body) do |response_headers|
response_headers.parse resp.headers
end
# in async mode, :response is initialized at this point
env[:response].finish(env) if parallel?(env)
end
req
end
def configure_ssl(req, env)
ssl = env[:ssl]
req.ssl_version = ssl[:version] if ssl[:version]
req.ssl_cert = ssl[:client_cert] if ssl[:client_cert]
req.ssl_key = ssl[:client_key] if ssl[:client_key]
req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
end
def configure_proxy(req, env)
proxy = request_options(env)[:proxy]
return unless proxy
req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
if proxy[:user] && proxy[:password]
req.proxy_username = proxy[:user]
req.proxy_password = proxy[:password]
end
end
def configure_timeout(req, env)
env_req = request_options(env)
req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
end
def configure_socket(req, env)
if bind = request_options(env)[:bind]
req.interface = bind[:host]
end
end
def request_options(env)
env[:request]
end
def parallel?(env)
!!env[:parallel_manager]
end
end
end
end