lib/amee/connection.rb in amee-2.5.1 vs lib/amee/connection.rb in amee-2.6.0
- old
+ new
@@ -16,10 +16,11 @@
@ssl = (options[:ssl] == false) ? false : true
@port = @ssl ? 443 : 80
@auth_token = nil
@format = options[:format] || (defined?(JSON) ? :json : :xml)
@amee_source = options[:amee_source]
+ @retries = options[:retries] || 0
if !valid?
raise "You must supply connection details - server, username and password are all required!"
end
# Handle old option
if options[:enable_caching]
@@ -50,26 +51,27 @@
@http.ca_file = RootCA
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
@http.verify_depth = 5
end
end
- @http.read_timeout = 60
+ self.timeout = options[:timeout] || 60
@http.set_debug_output($stdout) if options[:enable_debug]
@debug = options[:enable_debug]
end
attr_reader :format
attr_reader :server
attr_reader :username
attr_reader :password
+ attr_reader :retries
def timeout
@http.read_timeout
end
def timeout=(t)
- @http.read_timeout = t
+ @http.open_timeout = @http.read_timeout = t
end
def version
authenticate if @version.nil?
@version
@@ -215,24 +217,26 @@
return false
when '400'
if response.body.include? "would have resulted in a duplicate resource being created"
raise AMEE::DuplicateResource.new("The specified resource already exists. This is most often caused by creating an item that overlaps another in time.\nRequest: #{request.method} #{request.path}\n#{request.body}\Response: #{response.body}")
else
- raise AMEE::UnknownError.new("An error occurred while talking to AMEE: HTTP response code #{response.code}.\nRequest: #{request.method} #{request.path}\n#{request.body}\Response: #{response.body}")
+ raise AMEE::BadRequest.new("Bad request. This is probably due to malformed input data.\nRequest: #{request.method} #{request.path}\n#{request.body}\Response: #{response.body}")
end
- else
- raise AMEE::UnknownError.new("An error occurred while talking to AMEE: HTTP response code #{response.code}.\nRequest: #{request.method} #{request.path}\n#{request.body}\Response: #{response.body}")
end
+ raise AMEE::UnknownError.new("An error occurred while talking to AMEE: HTTP response code #{response.code}.\nRequest: #{request.method} #{request.path}\n#{request.body}\Response: #{response.body}")
end
def do_request(request, format = @format)
# Open HTTP connection
@http.start
- # Do request
begin
+ # Set auth token in cookie (and header just in case someone's stripping cookies)
+ request['Cookie'] = "authToken=#{@auth_token}"
+ request['authToken'] = @auth_token
+ # Do request
timethen=Time.now
- response = send_request(request, format)
+ response = send_request(@http, request, format)
Logger.log.debug("Requesting #{request.class} at #{request.path} with #{request.body} in format #{format}, taking #{(Time.now-timethen)*1000} miliseconds")
end while !response_ok?(response, request)
# Return response
return response
rescue SocketError
@@ -240,19 +244,31 @@
ensure
# Close HTTP connection
@http.finish if @http.started?
end
- def send_request(request, format = @format)
- # Set auth token in cookie (and header just in case someone's stripping cookies)
- request['Cookie'] = "authToken=#{@auth_token}"
- request['authToken'] = @auth_token
+ def send_request(connection, request, format = @format)
# Set accept header
request['Accept'] = content_type(format)
# Set AMEE source header if set
request['X-AMEE-Source'] = @amee_source if @amee_source
# Do the business
- response = @http.request(request)
+ retries = [1] * @retries
+ begin
+ response = connection.request(request)
+ # 500-series errors fail early
+ if ['502', '503', '504'].include? response.code
+ raise AMEE::ConnectionFailed.new("A connection error occurred while talking to AMEE: HTTP response code #{response.code}.\nRequest: #{request.method} #{request.path}")
+ end
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, AMEE::ConnectionFailed => e
+ if delay = retries.shift
+ sleep delay
+ retry
+ else
+ raise
+ end
+ end
# Done
response
end
def cache(path, &block)