Index: boto/s3/resumable_download_handler.py |
diff --git a/boto/s3/resumable_download_handler.py b/boto/s3/resumable_download_handler.py |
index 0d014774fb48a1027e35aa0f97e470c642c1b82e..5492e14bc726a4195283244834c64e23544df385 100644 |
--- a/boto/s3/resumable_download_handler.py |
+++ b/boto/s3/resumable_download_handler.py |
@@ -65,7 +65,7 @@ class ByteTranslatingCallbackHandler(object): |
def call(self, total_bytes_uploaded, total_size): |
self.proxied_cb(self.download_start_point + total_bytes_uploaded, |
- self.download_start_point + total_size) |
+ total_size) |
def get_cur_file_size(fp, position_to_eof=False): |
@@ -294,12 +294,28 @@ class ResumableDownloadHandler(object): |
except self.RETRYABLE_EXCEPTIONS, e: |
if debug >= 1: |
print('Caught exception (%s)' % e.__repr__()) |
+ if isinstance(e, IOError) and e.errno == errno.EPIPE: |
+ # Broken pipe error causes httplib to immediately |
+ # close the socket (http://bugs.python.org/issue5542), |
+ # so we need to close and reopen the key before resuming |
+ # the download. |
+ key.get_file(fp, headers, cb, num_cb, torrent, version_id, |
+ override_num_retries=0) |
except ResumableDownloadException, e: |
- if e.disposition == ResumableTransferDisposition.ABORT: |
+ if (e.disposition == |
+ ResumableTransferDisposition.ABORT_CUR_PROCESS): |
if debug >= 1: |
print('Caught non-retryable ResumableDownloadException ' |
'(%s)' % e.message) |
raise |
+ elif (e.disposition == |
+ ResumableTransferDisposition.ABORT): |
+ if debug >= 1: |
+ print('Caught non-retryable ResumableDownloadException ' |
+ '(%s); aborting and removing tracker file' % |
+ e.message) |
+ self._remove_tracker_file() |
+ raise |
else: |
if debug >= 1: |
print('Caught ResumableDownloadException (%s) - will ' |
@@ -316,11 +332,18 @@ class ResumableDownloadHandler(object): |
raise ResumableDownloadException( |
'Too many resumable download attempts failed without ' |
'progress. You might try this download again later', |
- ResumableTransferDisposition.ABORT) |
+ ResumableTransferDisposition.ABORT_CUR_PROCESS) |
# Close the key, in case a previous download died partway |
# through and left data in the underlying key HTTP buffer. |
- key.close() |
+ # Do this within a try/except block in case the connection is |
+ # closed (since key.close() attempts to do a final read, in which |
+ # case this read attempt would get an IncompleteRead exception, |
+ # which we can safely ignore. |
+ try: |
+ key.close() |
+ except httplib.IncompleteRead: |
+ pass |
sleep_time_secs = 2**progress_less_iterations |
if debug >= 1: |