Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add faraday adapter for typhoeus 0.5.0 support.

  • Loading branch information...
commit a9dcbfd1131882f83bd0fb4bfcf4d739e9f318d6 1 parent b9327bd
@i0rek i0rek authored
View
2  Gemfile
@@ -8,6 +8,7 @@ group :development, :test do
gem "sinatra", "~> 1.3"
gem "json"
+ gem "faraday", "~> 0.8.4"
if RUBY_PLATFORM == "java"
gem "spoon"
@@ -15,5 +16,6 @@ group :development, :test do
unless ENV["CI"]
gem "guard-rspec", "~> 0.7"
+ gem 'rb-fsevent', '~> 0.9.1'
end
end
View
109 lib/typhoeus/adapters/faraday.rb
@@ -0,0 +1,109 @@
+require 'faraday'
+
+module Faraday
+ class Adapter
+ class Typhoeus < Faraday::Adapter
+ self.supports_parallel = true
+
+ def self.setup_parallel_manager(options = {})
+ ::Typhoeus::Hydra.new(options)
+ end
+
+ dependency 'typhoeus'
+
+ def call(env)
+ super
+ perform_request env
+ @app.call env
+ end
+
+ private
+
+ def perform_request(env)
+ if parallel?(env)
+ hydra = env[:parallel_manager] || self.class.setup_parallel_manager
+ hydra.queue request(env)
+ else
+ request(env).run
+ end
+ end
+
+ def request(env)
+ read_body env
+
+ req = ::Typhoeus::Request.new(
+ env[:url].to_s,
+ :method => env[:method],
+ :body => env[:body],
+ :headers => env[:request_headers]
+ )
+
+ 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
+
+ save_response(env, resp.code, resp.body) do |response_headers|
+ response_headers.parse resp.response_headers
+ end
+ # in async mode, :response is initialized at this point
+ env[:response].finish(env) if parallel?(env)
+ end
+
+ req
+ end
+
+ def read_body(env)
+ env[:body] = env[:body].read if env[:body].respond_to? :read
+ end
+
+ def configure_ssl(req, env)
+ ssl = env[:ssl]
+
+ ssl_verifyhost = (ssl && ssl.fetch(:verify, true)) ? 2 : 0
+ req.options[:ssl_verifyhost] = ssl_verifyhost
+ req.options[:sslversion] = ssl[:version] if ssl[:version]
+ req.options[:sslcert] = ssl[:client_cert_file] if ssl[:client_cert_file]
+ req.options[:sslkey] = ssl[:client_key_file] if ssl[:client_key_file]
+ req.options[:cainfo] = ssl[:ca_file] if ssl[:ca_file]
+ req.options[:capath] = ssl[:ca_path] if ssl[:ca_path]
+ end
+
+ def configure_proxy(req, env)
+ proxy = env[:request][:proxy]
+ return unless proxy
+
+ req.options[:proxy] = "#{proxy[:uri].host}:#{proxy[:uri].port}"
+
+ if proxy[:username] && proxy[:password]
+ req.options[:proxyuserpwd] = "#{proxy[:username]}:#{proxy[:password]}"
+ end
+ end
+
+ def configure_timeout(req, env)
+ env_req = env[:request]
+ req.options[:timeout_ms] = (env_req[:timeout] * 1000) if env_req[:timeout]
+ req.options[:connecttimeout_ms] = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
+ end
+
+ def configure_socket(req, env)
+ if bind = env[:request][:bind]
+ req.options[:interface] = bind[:host]
+ end
+ end
+
+ def parallel?(env)
+ !!env[:parallel_manager]
+ end
+ end
+ end
+end
View
216 spec/typhoeus/adapters/faraday_spec.rb
@@ -0,0 +1,216 @@
+require 'spec_helper'
+require 'typhoeus/adapters/faraday'
+
+describe Faraday::Adapter::Typhoeus do
+ let(:url) { "http://localhost:3001" }
+ let(:adapter) { described_class.new }
+ let(:request) { Typhoeus::Request.new(url) }
+ let(:conn) do
+ Faraday.new(:url => url) do |faraday|
+ faraday.adapter :typhoeus
+ end
+ end
+ let(:response) { conn.get("/") }
+
+ context "when parallel" do
+ it "returns a faraday response" do
+ response = nil
+ conn.in_parallel { response = conn.get("/") }
+ expect(response).to be_a(Faraday::Response)
+ end
+
+ it "succeeds" do
+ response = nil
+ conn.in_parallel { response = conn.get("/") }
+ expect(response.status).to be(200)
+ end
+ end
+
+ context "when not parallel" do
+ it "returns a faraday response" do
+ expect(response).to be_a(Faraday::Response)
+ end
+
+ it "succeeds" do
+ expect(response.status).to be(200)
+ end
+ end
+
+ describe "#perform_request" do
+ let(:env) { {} }
+
+ context "when body" do
+ let(:env) { { :body => stub(:read => "body") } }
+
+ it "reads body" do
+ expect(adapter.method(:read_body).call(env)).to eq("body")
+ end
+ end
+
+ context "parallel_manager" do
+ context "when given" do
+ let(:env) { { :parallel_manager => stub(:queue => true) } }
+
+ it "uses" do
+ pending
+ end
+ end
+
+ context "when not given" do
+ it { pending }
+ end
+ end
+ end
+
+ describe "#request" do
+ let(:env) do
+ { :url => "url", :method => :get, :body => "body", :request_headers => {}, :ssl => {}, :request => {} }
+ end
+
+ let(:request) { adapter.method(:request).call(env) }
+
+ it "returns request" do
+ expect(request).to be_a(Typhoeus::Request)
+ end
+
+ it "sets url" do
+ expect(request.url).to eq("url")
+ end
+
+ it "sets http method" do
+ expect(request.original_options[:method]).to eq(:get)
+ end
+
+ it "sets body" do
+ expect(request.original_options[:body]).to eq("body")
+ end
+
+ it "sets headers" do
+ expect(request.original_options[:headers]).to eq({})
+ end
+
+ it "sets on_complete callback" do
+ expect(request.on_complete).to have(1).items
+ end
+ end
+
+ describe "#configure_socket" do
+ let(:env) { { :request => { :bind => { :host => "interface" } } } }
+
+ before { adapter.method(:configure_socket).call(request, env) }
+
+ context "when host" do
+ it "sets interface" do
+ expect(request.options[:interface]).to eq("interface")
+ end
+ end
+ end
+
+ describe "#configure_timeout" do
+ before { adapter.method(:configure_timeout).call(request, env) }
+
+ context "when timeout" do
+ let(:env) { { :request => { :timeout => 1 } } }
+
+ it "sets timeout_ms" do
+ expect(request.options[:timeout_ms]).to eq(1000)
+ end
+ end
+
+ context "when open_timeout" do
+ let(:env) { { :request => { :open_timeout => 1 } } }
+
+ it "sets connecttimeout_ms" do
+ expect(request.options[:connecttimeout_ms]).to eq(1000)
+ end
+ end
+ end
+
+ describe "#configure_proxy" do
+ before { adapter.method(:configure_proxy).call(request, env) }
+
+ context "when proxy" do
+ let(:env) { { :request => { :proxy => { :uri => stub(:host => "localhost", :port => "3001") } } } }
+
+ it "sets proxy" do
+ expect(request.options[:proxy]).to eq("localhost:3001")
+ end
+
+ context "when username and password" do
+ let(:env) do
+ { :request => { :proxy => {
+ :uri => stub(:host => :a, :port => :b),
+ :username => "a",
+ :password => "b"
+ } } }
+ end
+
+ it "sets proxyuserpwd" do
+ expect(request.options[:proxyuserpwd]).to eq("a:b")
+ end
+ end
+ end
+ end
+
+ describe "#configure_ssl" do
+ before { adapter.method(:configure_ssl).call(request, env) }
+
+ context "when version" do
+ let(:env) { { :ssl => { :version => "a" } } }
+
+ it "sets sslversion" do
+ expect(request.options[:sslversion]).to eq("a")
+ end
+ end
+
+ context "when client_cert_file" do
+ let(:env) { { :ssl => { :client_cert_file => "a" } } }
+
+ it "sets sslcert" do
+ expect(request.options[:sslcert]).to eq("a")
+ end
+ end
+
+ context "when client_key_file" do
+ let(:env) { { :ssl => { :client_key_file => "a" } } }
+
+ it "sets sslkey" do
+ expect(request.options[:sslkey]).to eq("a")
+ end
+ end
+
+ context "when ca_file" do
+ let(:env) { { :ssl => { :ca_file => "a" } } }
+
+ it "sets cainfo" do
+ expect(request.options[:cainfo]).to eq("a")
+ end
+ end
+
+ context "when ca_path" do
+ let(:env) { { :ssl => { :ca_path => "a" } } }
+
+ it "sets capath" do
+ expect(request.options[:capath]).to eq("a")
+ end
+ end
+ end
+
+ describe "#parallel?" do
+ context "when parallel_manager" do
+ let(:env) { { :parallel_manager => true } }
+
+ it "returns true" do
+ expect(adapter.method(:parallel?).call(env)).to be_true
+ end
+ end
+
+ context "when no parallel_manager" do
+ let(:env) { { :parallel_manager => nil } }
+
+ it "returns false" do
+ expect(adapter.method(:parallel?).call(env)).to be_false
+ end
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.