Browse code

s3cmd: Fix s3 path style signature v4 handling.

Harshavardhana authored on 2015/12/10 09:15:25
Showing 1 changed files
... ...
@@ -161,33 +161,38 @@ class S3Request(object):
161 161
         return False
162 162
 
163 163
     def sign(self):
164
-        h  = self.method_string + "\n"
165
-        h += self.headers.get("content-md5", "")+"\n"
166
-        h += self.headers.get("content-type", "")+"\n"
167
-        h += self.headers.get("date", "")+"\n"
168
-        for header in sorted(self.headers.keys()):
169
-            if header.startswith("x-amz-"):
170
-                h += header+":"+str(self.headers[header])+"\n"
171
-            if header.startswith("x-emc-"):
172
-                h += header+":"+str(self.headers[header])+"\n"
173
-        if self.resource['bucket']:
174
-            h += "/" + self.resource['bucket']
175
-        h += self.resource['uri']
176
-
177 164
         if self.use_signature_v2():
165
+            h  = self.method_string + "\n"
166
+            h += self.headers.get("content-md5", "")+"\n"
167
+            h += self.headers.get("content-type", "")+"\n"
168
+            h += self.headers.get("date", "")+"\n"
169
+            for header in sorted(self.headers.keys()):
170
+                if header.startswith("x-amz-"):
171
+                    h += header+":"+str(self.headers[header])+"\n"
172
+                if header.startswith("x-emc-"):
173
+                    h += header+":"+str(self.headers[header])+"\n"
174
+            if self.resource['bucket']:
175
+                h += "/" + self.resource['bucket']
176
+            h += self.resource['uri']
178 177
             debug("Using signature v2")
179 178
             debug("SignHeaders: " + repr(h))
180 179
             signature = sign_string_v2(h)
181 180
             self.headers["Authorization"] = "AWS "+self.s3.config.access_key+":"+signature
182 181
         else:
183 182
             debug("Using signature v4")
184
-            self.headers = sign_string_v4(self.method_string,
185
-                                          self.s3.get_hostname(self.resource['bucket']),
186
-                                          self.resource['uri'],
187
-                                          self.params,
188
-                                          S3Request.region_map.get(self.resource['bucket'], Config().bucket_location),
189
-                                          self.headers,
190
-                                          self.body)
183
+            hostname = self.s3.get_hostname(self.resource['bucket'])
184
+
185
+            ## Default to bucket part of DNS.
186
+            resource_uri = self.resource['uri']
187
+            ## If bucket is not part of DNS assume path style to complete the request.
188
+            if not check_bucket_name_dns_support(self.s3.config.host_bucket, self.resource['bucket']):
189
+                if self.resource['bucket']:
190
+                    resource_uri = "/" + self.resource['bucket'] + self.resource['uri']
191
+
192
+            bucket_region = S3Request.region_map.get(self.resource['bucket'], Config().bucket_location)
193
+            ## Sign the data.
194
+            self.headers = sign_string_v4(self.method_string, hostname, resource_uri, self.params,
195
+                                          bucket_region, self.headers, self.body)
191 196
 
192 197
     def get_triplet(self):
193 198
         self.update_timestamp()