module Postmaster
Constants
- VERSION
Public Class Methods
api_base()
click to toggle source
# File lib/postmaster.rb, line 62 def self.api_base @@api_base end
api_base=(api_base)
click to toggle source
# File lib/postmaster.rb, line 58 def self.api_base=(api_base) @@api_base = api_base end
api_key()
click to toggle source
# File lib/postmaster.rb, line 54 def self.api_key @@api_key end
api_key=(api_key)
click to toggle source
# File lib/postmaster.rb, line 50 def self.api_key=(api_key) @@api_key = api_key end
api_url(url='')
click to toggle source
# File lib/postmaster.rb, line 46 def self.api_url(url='') self.api_base + url end
request(method, url, params={}, headers={})
click to toggle source
# File lib/postmaster.rb, line 66 def self.request(method, url, params={}, headers={}) api_key = self.api_key raise AuthenticationError.new('No API key provided. (HINT: set your API key using "Postmaster.api_key = <API-KEY>".)') unless api_key uname = (@@uname ||= RUBY_PLATFORM =~ /linux|darwin/i ? `uname -a 2>/dev/null`.strip : nil) lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})" ua = { :bindings_version => Postmaster::VERSION, :lang => 'ruby', :lang_version => lang_version, :platform => RUBY_PLATFORM, :publisher => 'postmaster', :uname => uname } params = Util.objects_to_ids(params) url = self.api_url(url) case method.to_s.downcase.to_sym when :get, :head, :delete # Make params into GET parameters if params && params.count > 0 query_string = Util.flatten_params(params).collect{|key, value| "#{key}=#{Util.url_encode(value)}"}.join('&') url += "?#{query_string}" end payload = nil else if params.kind_of? String payload = params else payload = Util.flatten_params(params).collect{|(key, value)| "#{key}=#{Util.url_encode(value)}"}.join('&') end end begin headers = { :x_postmaster_client_user_agent => Postmaster::JSON.dump(ua) }.merge(headers) rescue => e headers = { :x_postmaster_client_raw_user_agent => ua.inspect, :error => "#{e} (#{e.class})" }.merge(headers) end headers = { :user_agent => "Postmaster/v1 RubyBindings/#{Postmaster::VERSION}", :content_type => 'application/x-www-form-urlencoded' }.merge(headers) opts = { :method => method, :url => url, :headers => headers, :open_timeout => 60, :payload => payload, :timeout => 80, :user => api_key, :password => "", } begin response = execute_request(opts) rescue SocketError => e self.handle_restclient_error(e) rescue NoMethodError => e # Work around RestClient bug if e.message =~ /\WRequestFailed\W/ e = APIConnectionError.new('Unexpected HTTP response code') self.handle_restclient_error(e) else raise end rescue RestClient::ExceptionWithResponse => e if rcode = e.http_code and rbody = e.http_body self.handle_api_error(rcode, rbody) else self.handle_restclient_error(e) end rescue RestClient::Exception, Errno::ECONNREFUSED => e self.handle_restclient_error(e) end rbody = response.body rcode = response.code begin # Would use :symbolize_names => true, but apparently there is # some library out there that makes symbolize_names not work. resp = Postmaster::JSON.load(rbody) rescue MultiJson::DecodeError raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody) end resp = Util.symbolize_names(resp) resp end
Private Class Methods
api_error(error, rcode, rbody, error_obj)
click to toggle source
# File lib/postmaster.rb, line 205 def self.api_error(error, rcode, rbody, error_obj) APIError.new(error[:message], rcode, rbody, error_obj) end
authentication_error(error, rcode, rbody, error_obj)
click to toggle source
# File lib/postmaster.rb, line 197 def self.authentication_error(error, rcode, rbody, error_obj) AuthenticationError.new(error[:message], rcode, rbody, error_obj) end
execute_request(opts)
click to toggle source
# File lib/postmaster.rb, line 162 def self.execute_request(opts) RestClient::Request.execute(opts) end
handle_api_error(rcode, rbody)
click to toggle source
# File lib/postmaster.rb, line 166 def self.handle_api_error(rcode, rbody) begin error_obj = Postmaster::JSON.load(rbody) error_obj = Util.symbolize_names(error_obj) if error_obj.has_key?(:message) error = error_obj elsif error_obj.has_key?(:error) error = error_obj[:error] else raise PostmasterError.new # escape from parsing end rescue MultiJson::DecodeError, PostmasterError raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody) end case rcode when 400, 404 then raise invalid_request_error(error, rcode, rbody, error_obj) when 401 raise authentication_error(error, rcode, rbody, error_obj) when 403 raise permission_error(error, rcode, rbody, error_obj) else raise api_error(error, rcode, rbody, error_obj) end end
handle_restclient_error(e)
click to toggle source
# File lib/postmaster.rb, line 209 def self.handle_restclient_error(e) case e when RestClient::ServerBrokeConnection, RestClient::RequestTimeout message = "Could not connect to Postmaster ($apiBase). Please check your internet connection and try again. If this problem persists, let us know at support@postmaster.io." when RestClient::SSLCertificateNotVerified message = "Could not verify Postmaster's SSL certificate. If this problem persists, let us know at support@postmaster.io." else message = "Unexpected error communicating with Postmaster. If this problem persists, let us know at support@postmaster.io." end message += "\n\n(Network error: #{e.message})" raise APIConnectionError.new(message) end
invalid_request_error(error, rcode, rbody, error_obj)
click to toggle source
# File lib/postmaster.rb, line 193 def self.invalid_request_error(error, rcode, rbody, error_obj) InvalidRequestError.new(error[:message], error[:param], rcode, rbody, error_obj) end
permission_error(error, rcode, rbody, error_obj)
click to toggle source
# File lib/postmaster.rb, line 201 def self.permission_error(error, rcode, rbody, error_obj) PermissionError.new(error[:message], error[:param], error[:code], rcode, rbody, error_obj) end