lib/faraday/adapter/net_http.rb in faraday-0.8.0.rc2 vs lib/faraday/adapter/net_http.rb in faraday-0.8.0

- old
+ new

@@ -6,63 +6,36 @@ end module Faraday class Adapter class NetHttp < Faraday::Adapter + NET_HTTP_EXCEPTIONS = [ + EOFError, + Errno::ECONNABORTED, + Errno::ECONNREFUSED, + Errno::ECONNRESET, + Errno::EINVAL, + Net::HTTPBadResponse, + Net::HTTPHeaderSyntaxError, + Net::ProtocolError, + SocketError + ] + + NET_HTTP_EXCEPTIONS << OpenSSL::SSL::SSLError if defined?(OpenSSL) + def call(env) super - url = env[:url] - req = env[:request] + http = net_http_connection(env) + configure_ssl(http, env[:ssl]) if env[:url].scheme == 'https' and env[:ssl] - http = net_http_class(env).new(url.host, url.port) - - if http.use_ssl = (url.scheme == 'https' && (ssl = env[:ssl]) && true) - http.verify_mode = ssl[:verify_mode] || begin - if ssl.fetch(:verify, true) - # Use the default cert store by default, i.e. system ca certs - store = OpenSSL::X509::Store.new - store.set_default_paths - http.cert_store = store - OpenSSL::SSL::VERIFY_PEER - else - OpenSSL::SSL::VERIFY_NONE - end - end - - http.cert = ssl[:client_cert] if ssl[:client_cert] - http.key = ssl[:client_key] if ssl[:client_key] - http.ca_file = ssl[:ca_file] if ssl[:ca_file] - http.ca_path = ssl[:ca_path] if ssl[:ca_path] - http.cert_store = ssl[:cert_store] if ssl[:cert_store] - http.verify_depth = ssl[:verify_depth] if ssl[:verify_depth] - end - + req = env[:request] http.read_timeout = http.open_timeout = req[:timeout] if req[:timeout] http.open_timeout = req[:open_timeout] if req[:open_timeout] - if :get != env[:method] or env[:body] - http_request = Net::HTTPGenericRequest.new \ - env[:method].to_s.upcase, # request method - !!env[:body], # is there request body - :head != env[:method], # is there response body - url.request_uri, # request uri path - env[:request_headers] # request headers - - if env[:body].respond_to?(:read) - http_request.body_stream = env[:body] - env[:body] = nil - end - end - begin - http_response = if :get == env[:method] and env[:body].nil? - # prefer `get` to `request` because the former handles gzip (ruby 1.9) - http.get url.request_uri, env[:request_headers] - else - http.request http_request, env[:body] - end - rescue Errno::ECONNREFUSED + http_response = perform_request(http, env) + rescue *NET_HTTP_EXCEPTIONS raise Error::ConnectionFailed, $! end save_response(env, http_response.code.to_i, http_response.body) do |response_headers| http_response.each_header do |key, value| @@ -73,14 +46,70 @@ @app.call env rescue Timeout::Error => err raise Faraday::Error::TimeoutError, err end - def net_http_class(env) + def create_request(env) + request = Net::HTTPGenericRequest.new \ + env[:method].to_s.upcase, # request method + !!env[:body], # is there request body + :head != env[:method], # is there response body + env[:url].request_uri, # request uri path + env[:request_headers] # request headers + + if env[:body].respond_to?(:read) + request.body_stream = env[:body] + else + request.body = env[:body] + end + request + end + + def perform_request(http, env) + if :get == env[:method] and !env[:body] + # prefer `get` to `request` because the former handles gzip (ruby 1.9) + http.get env[:url].request_uri, env[:request_headers] + else + http.request create_request(env) + end + end + + def net_http_connection(env) if proxy = env[:request][:proxy] Net::HTTP::Proxy(proxy[:uri].host, proxy[:uri].port, proxy[:user], proxy[:password]) else Net::HTTP + end.new(env[:url].host, env[:url].port) + end + + def configure_ssl(http, ssl) + http.use_ssl = true + http.verify_mode = ssl_verify_mode(ssl) + http.cert_store = ssl_cert_store(ssl) + + http.cert = ssl[:client_cert] if ssl[:client_cert] + http.key = ssl[:client_key] if ssl[:client_key] + http.ca_file = ssl[:ca_file] if ssl[:ca_file] + http.ca_path = ssl[:ca_path] if ssl[:ca_path] + http.verify_depth = ssl[:verify_depth] if ssl[:verify_depth] + http.ssl_version = ssl[:version] if ssl[:version] + end + + def ssl_cert_store(ssl) + return ssl[:cert_store] if ssl[:cert_store] + # Use the default cert store by default, i.e. system ca certs + cert_store = OpenSSL::X509::Store.new + cert_store.set_default_paths + cert_store + end + + def ssl_verify_mode(ssl) + ssl[:verify_mode] || begin + if ssl.fetch(:verify, true) + OpenSSL::SSL::VERIFY_PEER + else + OpenSSL::SSL::VERIFY_NONE + end end end end end end