lib/xeroizer/http.rb in xeroizer-2.20.0 vs lib/xeroizer/http.rb in xeroizer-3.0.0
- old
+ new
@@ -13,11 +13,11 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
module Xeroizer
module Http
class BadResponse < XeroizerError; end
- RequestInfo = Struct.new(:url, :headers, :params, :body)
+ RequestInfo = Struct.new(:url, :headers, :params, :body, :method)
ACCEPT_MIME_MAP = {
:pdf => 'application/pdf',
:json => 'application/json'
}
@@ -51,11 +51,11 @@
http_request(client, :put, url, body, extra_params)
end
private
- def http_request(client, method, url, body, params = {})
+ def http_request(client, method, url, request_body, params = {})
# headers = {'Accept-Encoding' => 'gzip, deflate'}
headers = self.default_headers.merge({ 'charset' => 'utf-8' })
# include the unitdp query string parameter
@@ -87,18 +87,18 @@
uri = URI.parse(url)
attempts = 0
- request_info = RequestInfo.new(url, headers, params, body)
+ request_info = RequestInfo.new(url, headers, params, request_body, method)
before_request.call(request_info) if before_request
begin
attempts += 1
logger.info("XeroGateway Request: #{method.to_s.upcase} #{uri.request_uri}") if self.logger
- raw_body = params.delete(:raw_body) ? body : {:xml => body}
+ raw_body = params.delete(:raw_body) ? request_body : {:xml => request_body}
response = with_around_request(request_info) do
case method
when :get then client.get(uri.request_uri, headers)
when :post then client.post(uri.request_uri, raw_body, headers)
@@ -107,26 +107,11 @@
end
log_response(response, uri)
after_request.call(request_info, response) if after_request
- case response.code.to_i
- when 200
- response.plain_body
- when 204
- nil
- when 400
- handle_error!(response, body)
- when 401
- handle_oauth_error!(response)
- when 404
- handle_object_not_found!(response, url)
- when 503
- handle_oauth_error!(response)
- else
- handle_unknown_response_error!(response)
- end
+ HttpResponse.from_response(response, request_body, url).body
rescue Xeroizer::OAuth::NonceUsed => exception
raise if attempts > nonce_used_max_attempts
logger.info("Nonce used: " + exception.to_s) if self.logger
sleep_for(1)
retry
@@ -155,69 +140,9 @@
logger.info("XeroGateway Response (#{response.code})")
logger.add(response.code.to_i == 200 ? Logger::DEBUG : Logger::INFO) {
"#{uri.request_uri}\n== Response Body\n\n#{response.plain_body}\n== End Response Body"
}
end
- end
-
- def handle_oauth_error!(response)
- error_details = CGI.parse(response.plain_body)
- description = error_details["oauth_problem_advice"].first
- problem = error_details["oauth_problem"].first
-
- # see http://oauth.pbworks.com/ProblemReporting
- # In addition to token_expired and token_rejected, Xero also returns
- # 'rate limit exceeded' when more than 60 requests have been made in
- # a second.
- if problem
- case problem
- when "token_expired" then raise OAuth::TokenExpired.new(description)
- when "token_rejected" then raise OAuth::TokenInvalid.new(description)
- when "rate limit exceeded" then raise OAuth::RateLimitExceeded.new(description)
- when "consumer_key_unknown" then raise OAuth::ConsumerKeyUnknown.new(description)
- when "nonce_used" then raise OAuth::NonceUsed.new(description)
- when "organisation offline" then raise OAuth::OrganisationOffline.new(description)
- else raise OAuth::UnknownError.new(problem + ':' + description)
- end
- else
- raise OAuth::UnknownError.new("Xero API may be down or the way OAuth errors are provided by Xero may have changed.")
- end
- end
-
- def handle_error!(response, request_body)
-
- raw_response = response.plain_body
-
- # XeroGenericApplication API Exceptions *claim* to be UTF-16 encoded, but fail REXML/Iconv parsing...
- # So let's ignore that :)
- raw_response.gsub! '<?xml version="1.0" encoding="utf-16"?>', ''
-
- # doc = REXML::Document.new(raw_response, :ignore_whitespace_nodes => :all)
- doc = Nokogiri::XML(raw_response)
-
- if doc && doc.root && doc.root.name == "ApiException"
-
- raise ApiException.new(doc.root.xpath("Type").text,
- doc.root.xpath("Message").text,
- raw_response,
- doc,
- request_body)
-
- else
- raise BadResponse.new("Unparseable 400 Response: #{raw_response}")
- end
- end
-
- def handle_object_not_found!(response, request_url)
- case request_url
- when /Invoices/ then raise InvoiceNotFoundError.new("Invoice not found in Xero.")
- when /CreditNotes/ then raise CreditNoteNotFoundError.new("Credit Note not found in Xero.")
- else raise ObjectNotFound.new(request_url)
- end
- end
-
- def handle_unknown_response_error!(response)
- raise BadResponse.new("Unknown response code: #{response.code.to_i}")
end
def sleep_for(seconds = 1)
sleep seconds
end