diff --git a/qcloud_cos/cos_client.py b/qcloud_cos/cos_client.py index 93049026..36bde6a8 100644 --- a/qcloud_cos/cos_client.py +++ b/qcloud_cos/cos_client.py @@ -11,7 +11,7 @@ import json import xml.dom.minidom import xml.etree.ElementTree -from requests import Request, Session +from requests import Request, Session, ConnectionError, Timeout from datetime import datetime from six.moves.urllib.parse import quote, unquote, urlencode from six import text_type, binary_type @@ -265,23 +265,16 @@ def send_request(self, method, url, bucket, timeout=30, cos_request=True, **kwar return res elif res.status_code < 500: # 4xx 不重试 break + else: + if j < self._retry and client_can_retry(file_position, **kwargs): + continue + else: + break except Exception as e: # 捕获requests抛出的如timeout等客户端错误,转化为客户端错误 logger.exception('url:%s, retry_time:%d exception:%s' % (url, j, str(e))) - can_retry = False - if 'data' in kwargs: - body = kwargs['data'] - if hasattr(body, 'tell') and hasattr(body, 'seek') and hasattr(body, 'read'): - can_retry = True - elif isinstance(body, text_type) or isinstance(body, binary_type): - can_retry = True - - if j < self._retry and can_retry: - if file_position is not None: - try: - kwargs['data'].seek(file_position) - except IOError as ioe: - raise CosClientError(str(ioe)) - continue + if j < self._retry and (isinstance(e, ConnectionError) or isinstance(e, Timeout)): # 只重试网络错误 + if client_can_retry(file_position, **kwargs): + continue raise CosClientError(str(e)) if not cos_request: diff --git a/qcloud_cos/cos_comm.py b/qcloud_cos/cos_comm.py index ede48381..2b6e072a 100644 --- a/qcloud_cos/cos_comm.py +++ b/qcloud_cos/cos_comm.py @@ -437,6 +437,22 @@ def parse_bucket_canned_acl(result_acl): return "private" +def client_can_retry(file_position, **kwargs): + """如果客户端请求中不包含data则可以重试,以及判断包含data的请求是否可以重试""" + if 'data' not in kwargs: + return True + body = kwargs['data'] + if isinstance(body, text_type) or isinstance(body, binary_type): + return True + if file_position is not None and hasattr(body, 'tell') and hasattr(body, 'seek') and hasattr(body, 'read'): + try: + kwargs['data'].seek(file_position) + return True + except Exception as ioe: + return False + return False + + class CiDetectType(): """ci内容设备的类型设置,可与操作设多个""" PORN = 1 diff --git a/qcloud_cos/version.py b/qcloud_cos/version.py index 0ea27210..3e8d4d14 100644 --- a/qcloud_cos/version.py +++ b/qcloud_cos/version.py @@ -1,2 +1,2 @@ -__version__ = '5.1.9.2' +__version__ = '5.1.9.3' diff --git a/setup.py b/setup.py index 4ab605ac..51dc0b0b 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ def long_description(): setup( name='cos-python-sdk-v5', - version='1.9.2', + version='1.9.3', url='https://www.qcloud.com/', license='MIT', author='tiedu, lewzylu, channingliu',