Skip to content
Browse files

#1380 Official branch for 1.2.3 release

git-svn-id: https://wush.net/svn/rightscale/right_http_connection/release_1_2_3@4426 9f0cbaf6-ce18-0410-ad37-d14a22affa91
  • Loading branch information...
1 parent feeafd1 commit d65da1ff302a7d43b7b7b6038d43b95501862b16 @trbryan trbryan committed
Showing with 44 additions and 18 deletions.
  1. +5 −1 History.txt
  2. +1 −1 README.txt
  3. +38 −16 lib/right_http_connection.rb
View
6 History.txt
@@ -45,4 +45,8 @@ Initial public release
* r3524, konstantin, 2008-04-17 11:35:42 +0400
* Fixed a problem with incorrect error handling (connection retries always failed).
-== 1.2.3
+== 1.2.3
+
+- Added support for setting retry & timeout parameters in the constructor
+- Improve handling of data streams during upload: if there is a failure and a retry, reset
+ the seek pointer for the subsequent re-request
View
2 README.txt
@@ -28,7 +28,7 @@ algorithm for low-level network errors.
== INSTALL:
-sudo gem install
+sudo gem install right_http_connection
== LICENSE:
View
54 lib/right_http_connection.rb
@@ -244,6 +244,36 @@ def raise_on_eof_exception?
def eof_reset
@@eof.delete(@server)
end
+
+ # Detects if an object is 'streamable' - can we read from it, and can we know the size?
+ def setup_streaming(request)
+ if(request.body && request.body.respond_to?(:read))
+ body = request.body
+ request.content_length = body.respond_to?(:lstat) ? body.lstat.size : body.size
+ request.body_stream = request.body
+ true
+ end
+ end
+
+ def get_fileptr_offset(request_params)
+ request_params[:request].body.pos
+ rescue Exception => e
+ # Probably caught this because the body doesn't support the pos() method, like if it is a socket.
+ # Just return 0 and get on with life.
+ 0
+ end
+
+ def reset_fileptr_offset(request, offset = 0)
+ if(request.body_stream && request.body_stream.respond_to?(:pos))
+ begin
+ request.body_stream.pos = offset
+ rescue Exception => e
+ @logger.warn("Failed file pointer reset; aborting HTTP retries." +
+ " -- #{err_header} #{e.inspect}")
+ raise e
+ end
+ end
+ end
# Start a fresh connection. The object closes any existing connection and
# opens a new one.
@@ -295,6 +325,8 @@ def start(request_params)
=end
def request(request_params, &block)
+ # We save the offset here so that if we need to retry, we can return the file pointer to its initial position
+ mypos = get_fileptr_offset(request_params)
loop do
# if we are inside a delay between retries: no requests this time!
if error_count > @params[:http_connection_retry_count] &&
@@ -326,11 +358,7 @@ def request(request_params, &block)
# Detect if the body is a streamable object like a file or socket. If so, stream that
# bad boy.
- if(request.body && request.body.respond_to?(:read))
- body = request.body
- request.content_length = body.respond_to?(:lstat) ? body.lstat.size : body.size
- request.body_stream = request.body
- end
+ setup_streaming(request)
response = @http.request(request, &block)
error_reset
@@ -359,6 +387,8 @@ def request(request_params, &block)
else
# ... else just sleep a bit before new retry
sleep(add_eof)
+ # We will be retrying the request, so reset the file pointer
+ reset_fileptr_offset(request, mypos)
end
rescue Exception => e # See comment at bottom for the list of errors seen...
@http = nil
@@ -375,17 +405,9 @@ def request(request_params, &block)
error_add(e.message)
@logger.warn("#{err_header} request failure count: #{error_count}, exception: #{e.inspect}")
- # Always make sure that the fp is set to point to the beginning(?) of
- # the File/IO. TODO: it assumes that offset is 0, which is bad.
- if(request.body_stream && request.body_stream.respond_to?(:pos))
- begin
- request.body_stream.pos = 0
- rescue Exception => e
- @logger.warn("Retry may fail due to unable to reset the file pointer" +
- " -- #{err_header} #{e.inspect}")
- # may want to raise here? since it is not recoverable
- end
- end
+ # We will be retrying the request, so reset the file pointer
+ reset_fileptr_offset(request, mypos)
+
end
end
end

0 comments on commit d65da1f

Please sign in to comment.
Something went wrong with that request. Please try again.