Browse code

move fallback_to_signature_v2 and force_signature_v4 up

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.

Matt Domsch authored on 2014/12/20 11:41:31
Showing 1 changed files
... ...
@@ -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)