These flags were defined in S3Request, which works, but has the
unfortuante side-effect that each request of a multi-request operation
(think [sync] or any recursive operation) would repeat the "try v4,
fallback to v2" or "asked for v2, but endpoint requires upgrading to
v4"), essentially causing two operations (one failing, one succeeding)
for every desired operation.
By moving these flags up from S3Request into class S3, they are
retained across all actions, so if you've got it wrong, it is only
wrong for one request, then is correct for all future requests.
... | ... |
@@ -118,8 +118,6 @@ class S3Request(object): |
118 | 118 |
self.method_string = method_string |
119 | 119 |
self.params = params |
120 | 120 |
self.body = body |
121 |
- self.fallback_to_signature_v2 = False |
|
122 |
- self.force_signature_v4 = False |
|
123 | 121 |
|
124 | 122 |
def update_timestamp(self): |
125 | 123 |
if self.headers.has_key("date"): |
... | ... |
@@ -142,12 +140,12 @@ class S3Request(object): |
142 | 142 |
return param_str and "?" + param_str[1:] |
143 | 143 |
|
144 | 144 |
def use_signature_v2(self): |
145 |
- if self.force_signature_v4: |
|
145 |
+ if self.s3.endpoint_requires_signature_v4: |
|
146 | 146 |
return False |
147 | 147 |
# in case of bad DNS name due to bucket name v2 will be used |
148 | 148 |
# this way we can still use capital letters in bucket names for the older regions |
149 | 149 |
|
150 |
- if self.resource['bucket'] is None or not check_bucket_name_dns_conformity(self.resource['bucket']) or self.s3.config.signature_v2 or self.fallback_to_signature_v2: |
|
150 |
+ if self.resource['bucket'] is None or not check_bucket_name_dns_conformity(self.resource['bucket']) or self.s3.config.signature_v2 or self.s3.fallback_to_signature_v2: |
|
151 | 151 |
return True |
152 | 152 |
return False |
153 | 153 |
|
... | ... |
@@ -231,6 +229,8 @@ class S3(object): |
231 | 231 |
|
232 | 232 |
def __init__(self, config): |
233 | 233 |
self.config = config |
234 |
+ self.fallback_to_signature_v2 = False |
|
235 |
+ self.endpoint_requires_signature_v4 = False |
|
234 | 236 |
|
235 | 237 |
def get_hostname(self, bucket): |
236 | 238 |
if bucket and check_bucket_name_dns_support(self.config.host_bucket, bucket): |
... | ... |
@@ -947,21 +947,21 @@ class S3(object): |
947 | 947 |
|
948 | 948 |
elif failureCode == 'InvalidRequest': |
949 | 949 |
if message == 'The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.': |
950 |
- debug(u'Region requires signature v4') |
|
951 |
- request.force_signature_v4 = True |
|
950 |
+ debug(u'Endpoint requires signature v4') |
|
951 |
+ self.endpoint_requires_signature_v4 = True |
|
952 | 952 |
return fn(*args, **kwargs) |
953 | 953 |
|
954 | 954 |
elif failureCode == 'InvalidArgument': # returned by DreamObjects on send_request and send_file, |
955 | 955 |
# which doesn't support signature v4. Retry with signature v2 |
956 |
- if not request.use_signature_v2() and not request.fallback_to_signature_v2: # have not tried with v2 yet |
|
956 |
+ if not request.use_signature_v2() and not self.fallback_to_signature_v2: # have not tried with v2 yet |
|
957 | 957 |
debug(u'Falling back to signature v2') |
958 |
- request.fallback_to_signature_v2 = True |
|
958 |
+ self.fallback_to_signature_v2 = True |
|
959 | 959 |
return fn(*args, **kwargs) |
960 | 960 |
|
961 | 961 |
else: # returned by DreamObjects on recv_file, which doesn't support signature v4. Retry with signature v2 |
962 |
- if not request.use_signature_v2() and not request.fallback_to_signature_v2: # have not tried with v2 yet |
|
962 |
+ if not request.use_signature_v2() and not self.fallback_to_signature_v2: # have not tried with v2 yet |
|
963 | 963 |
debug(u'Falling back to signature v2') |
964 |
- request.fallback_to_signature_v2 = True |
|
964 |
+ self.fallback_to_signature_v2 = True |
|
965 | 965 |
return fn(*args, **kwargs) |
966 | 966 |
|
967 | 967 |
error(u"S3 error: %s" % message) |
... | ... |
@@ -974,9 +974,9 @@ class S3(object): |
974 | 974 |
message = getTextFromXml(response['data'], 'Message') |
975 | 975 |
if failureCode == 'AccessDenied': # traditional HTTP 403 |
976 | 976 |
if message == 'AWS authentication requires a valid Date or x-amz-date header': # message from an Eucalyptus walrus server |
977 |
- if not request.use_signature_v2() and not request.fallback_to_signature_v2: # have not tried with v2 yet |
|
977 |
+ if not request.use_signature_v2() and not self.fallback_to_signature_v2: # have not tried with v2 yet |
|
978 | 978 |
debug(u'Falling back to signature v2') |
979 |
- request.fallback_to_signature_v2 = True |
|
979 |
+ self.fallback_to_signature_v2 = True |
|
980 | 980 |
return fn(*args, **kwargs) |
981 | 981 |
|
982 | 982 |
error(u"S3 error: %s" % message) |