From 94ecd706bae5e246ffbb7a3f67a419116f41391e Mon Sep 17 00:00:00 2001 From: Felix Holmgren Date: Wed, 20 Feb 2013 13:42:38 +0100 Subject: [PATCH 1/2] Wrap all http using Faraday. * Makes it easy to switch between http clients. * Currently set to use Patron. The speed is on par with HTTPClient. --- lib/tempodb.rb | 2 +- lib/tempodb/client.rb | 46 +++++++++++++++++++++++++------------------ spec/client_spec.rb | 2 +- tempodb.gemspec | 2 +- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/lib/tempodb.rb b/lib/tempodb.rb index b6fd853..1eaff25 100644 --- a/lib/tempodb.rb +++ b/lib/tempodb.rb @@ -1,5 +1,5 @@ require 'rubygems' -require 'httpclient' +require 'faraday' require 'net/https' require 'json' require 'time' diff --git a/lib/tempodb/client.rb b/lib/tempodb/client.rb index f5b7f75..e9e08d4 100644 --- a/lib/tempodb/client.rb +++ b/lib/tempodb/client.rb @@ -1,3 +1,5 @@ +require 'openssl' + module TempoDB class Client def initialize(key, secret, host=TempoDB::API_HOST, port=TempoDB::API_PORT, secure=true) @@ -183,33 +185,39 @@ def increment(series_type, series_val, data) do_post(url, nil, body) end - def do_http(uri, request) # :nodoc: - if @http_client.nil? - @http_client = HTTPClient.new - @http_client.transparent_gzip_decompression = true - if @secure - @http_client.ssl_config.clear_cert_store - @http_client.ssl_config.set_trust_ca(TempoDB::TRUSTED_CERT_FILE) - end + def build_client + headers = { :accept => 'application/json', + :user_agent => "tempodb-ruby/#{TempoDB::VERSION}", + # TempoDb doesn't seem to return gzipped content on our calls, so let's leave this out for the time being + # To get it to work later, we need a Faraday middle-ware to do the unzipping + # :accept_encoding => "gzip" + } + + # Calls still succeed without setting up the cert store. Need to investigate that. + cert_store = OpenSSL::X509::Store.new + cert_store.add_file(TempoDB::TRUSTED_CERT_FILE) + ssl_options = {:cert_store => cert_store} + + @http_client = Faraday::Connection.new(:headers => headers, :ssl => ssl_options) do |conn| + conn.adapter :patron + conn.basic_auth(@key, @secret) end + end - request.basic_auth @key, @secret - request['User-Agent'] = "tempodb-ruby/#{TempoDB::VERSION}" - request['Accept-Encoding'] = "gzip" + def do_http(uri, request) # :nodoc: + @http_client ||= build_client method = request.method.downcase.intern - http_client_attrs = { - :header => Hash[request.to_hash.map {|k,v| [k, v.first] if v.is_a?(Array) && v.size == 1}], - :body => request.body - } + headers = Hash[request.to_hash.map {|k,v| [k, v.first] if v.is_a?(Array) && v.size == 1}] + body = request.body begin - response = @http_client.request(method, uri, http_client_attrs) + # response = @http_client.request(method, uri, http_client_attrs) + response = @http_client.run_request(method, uri, body, headers) rescue OpenSSL::SSL::SSLError => e raise TempoDBClientError.new("SSL error connecting to TempoDB. " + "There may be a problem with the set of certificates in \"#{TempoDB::TRUSTED_CERT_FILE}\". " + e) end - parse_response(response) end @@ -275,7 +283,7 @@ def urlencode(params) end def parse_response(response) - if response.ok? + if response.success? body = response.body begin @@ -288,7 +296,7 @@ def parse_response(response) return body end else - raise TempoDBClientError.new("Error: #{response.status_code} #{response.reason}\n#{response.body}") + raise TempoDBClientError.new("Error: #{response.status}\n#{response.body}") end end end diff --git a/spec/client_spec.rb b/spec/client_spec.rb index fa88023..f3fda32 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -45,7 +45,7 @@ describe "get_series" do context "with no options provided" do it "lists all series in the database" do - stub_request(:get, "https://api.tempo-db.com/v1/series/?"). + stub_request(:get, "https://api.tempo-db.com/v1/series/"). to_return(:status => 200, :body => response_fixture('list_all_series.json'), :headers => {}) client = TempoDB::Client.new("key", "secret") client.get_series.size.should == 7 diff --git a/tempodb.gemspec b/tempodb.gemspec index 362198c..e936381 100644 --- a/tempodb.gemspec +++ b/tempodb.gemspec @@ -15,7 +15,7 @@ Gem::Specification.new do |s| s.require_paths = ["lib"] s.add_runtime_dependency "json" - s.add_runtime_dependency "httpclient" + s.add_runtime_dependency "faraday" s.add_development_dependency "rspec", "~> 2.12.0" s.add_development_dependency "webmock", "~> 1.8.10" end From 710fceae40b580ef112da1c1beeafd5082765c6b Mon Sep 17 00:00:00 2001 From: Felix Holmgren Date: Wed, 20 Feb 2013 13:54:52 +0100 Subject: [PATCH 2/2] Allow user to switch underlying http client. --- lib/tempodb/client.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/tempodb/client.rb b/lib/tempodb/client.rb index e9e08d4..d5e271f 100644 --- a/lib/tempodb/client.rb +++ b/lib/tempodb/client.rb @@ -2,12 +2,15 @@ module TempoDB class Client + attr_accessor :http_adapter + def initialize(key, secret, host=TempoDB::API_HOST, port=TempoDB::API_PORT, secure=true) @key = key @secret = secret @host = host @port = port @secure = secure + @http_adapter = :patron end def create_series(key=nil) @@ -199,7 +202,7 @@ def build_client ssl_options = {:cert_store => cert_store} @http_client = Faraday::Connection.new(:headers => headers, :ssl => ssl_options) do |conn| - conn.adapter :patron + conn.adapter @http_adapter conn.basic_auth(@key, @secret) end end