lib/flexirest/connection.rb
require 'faraday'
module Flexirest
class BaseException < StandardError ; end
class TimeoutException < BaseException ; end
class ConnectionFailedException < BaseException ; end
class Connection
attr_accessor :session, :base_url
def initialize(base_url)
@base_url = base_url
@session = new_session
end
def reconnect
@session = new_session
end
def headers
@session.headers
end
def make_safe_request(path, &block)
block.call
rescue Faraday::TimeoutError
raise Flexirest::TimeoutException.new("Timed out getting #{full_url(path)}")
rescue Faraday::ConnectionFailed => e1
if e1.respond_to?(:cause) && e1.cause.is_a?(Net::OpenTimeout)
raise Flexirest::TimeoutException.new("Timed out getting #{full_url(path)}")
end
begin
reconnect
block.call
rescue Faraday::ConnectionFailed => e2
if e2.respond_to?(:cause) && e2.cause.is_a?(Net::OpenTimeout)
raise Flexirest::TimeoutException.new("Timed out getting #{full_url(path)}")
end
raise Flexirest::ConnectionFailedException.new("Unable to connect to #{full_url(path)}")
end
end
def get(path, options={})
set_defaults(options)
make_safe_request(path) do
@session.get(path) do |req|
set_per_request_timeout(req, options) if options[:timeout]
req.headers = req.headers.merge(options[:headers])
sign_request(req, options[:api_auth])
end
end
end
def put(path, data, options={})
set_defaults(options)
make_safe_request(path) do
@session.put(path) do |req|
set_per_request_timeout(req, options) if options[:timeout]
req.headers = req.headers.merge(options[:headers])
req.body = data
sign_request(req, options[:api_auth])
end
end
end
def patch(path, data, options={})
set_defaults(options)
make_safe_request(path) do
@session.patch(path) do |req|
set_per_request_timeout(req, options) if options[:timeout]
req.headers = req.headers.merge(options[:headers])
req.body = data
sign_request(req, options[:api_auth])
end
end
end
def post(path, data, options={})
set_defaults(options)
make_safe_request(path) do
@session.post(path) do |req|
set_per_request_timeout(req, options) if options[:timeout]
req.headers = req.headers.merge(options[:headers])
req.body = data
sign_request(req, options[:api_auth])
end
end
end
def delete(path, data, options={})
set_defaults(options)
make_safe_request(path) do
@session.delete(path) do |req|
set_per_request_timeout(req, options) if options[:timeout]
req.headers = req.headers.merge(options[:headers])
req.body = data
sign_request(req, options[:api_auth])
end
end
end
private
def set_per_request_timeout(req, options)
req.options.timeout = options[:timeout].to_i
req.options.open_timeout = options[:timeout].to_i
end
def new_session
Faraday.new({url: @base_url}, &Flexirest::Base.faraday_config)
end
def full_url(path)
@session.build_url(path).to_s
end
def set_defaults(options)
options[:headers] ||= {}
options[:api_auth] ||= {}
return options
end
def sign_request(request, api_auth)
return if api_auth[:api_auth_access_id].nil? || api_auth[:api_auth_secret_key].nil?
ApiAuth.sign!(
request,
api_auth[:api_auth_access_id],
api_auth[:api_auth_secret_key],
api_auth[:api_auth_options])
rescue ArgumentError
if api_auth[:api_auth_options] && api_auth[:api_auth_options].keys.size > 0
Flexirest::Logger.warn("Specifying Api-Auth options isn't supported with your version of ApiAuth")
end
ApiAuth.sign!(
request,
api_auth[:api_auth_access_id],
api_auth[:api_auth_secret_key])
end
end
end