Browse code

Fix MD5 comparison with s3 compatible servers that are not Amazon S3.

Some servers (like fakes3), doesn't add quotes in ETags aroung md5 value.
Ex.:
AWS: <LastModified>2014-06-05T09:45:25.000Z</LastModified><ETag>&quot;fc0f71ccc63dda0efc30239b48bdeccd&quot;</ETag><Size>132947133</Size>
FAKES3: <LastModified>2014-06-05T09:58:35.982060ZZ</LastModified><ETag>fc0f71ccc63dda0efc30239b48bdeccd</ETag><Size>132947133</Size>
(Nota: &quot; <=> " )

Bug in the previous code was always striping and first and last characters whatever they were. Such, in a fakes3 case, dest md5 was truncated and so would never match.
In the same time, this patch normalize the behavior to always strip " and ' chars in all the code dealing with etags.

Florent Viard authored on 2014/06/05 21:31:54
Showing 4 changed files
... ...
@@ -381,7 +381,7 @@ def fetch_remote_list(args, require_attribs = False, recursive = None, uri_param
381 381
             rem_list[key] = {
382 382
                 'size' : int(object['Size']),
383 383
                 'timestamp' : dateS3toUnix(object['LastModified']), ## Sadly it's upload time, not our lastmod time :-(
384
-                'md5' : object['ETag'][1:-1],
384
+                'md5' : object['ETag'].strip('"\''),
385 385
                 'object_key' : object['Key'],
386 386
                 'object_uri_str' : object_uri_str,
387 387
                 'base_uri' : remote_uri,
... ...
@@ -147,7 +147,7 @@ class MultiPartUpload(object):
147 147
         if remote_status is not None:
148 148
             if int(remote_status['size']) == chunk_size:
149 149
                 checksum = calculateChecksum(buffer, self.file, offset, chunk_size, self.s3.config.send_chunk)
150
-                remote_checksum = remote_status['checksum'].strip('"')
150
+                remote_checksum = remote_status['checksum'].strip('"\'')
151 151
                 if remote_checksum == checksum:
152 152
                     warning("MultiPart: size and md5sum match for %s part %d, skipping." % (self.uri, seq))
153 153
                     self.parts[seq] = remote_status['checksum']
... ...
@@ -528,7 +528,7 @@ class S3(object):
528 528
 
529 529
             if info is not None:
530 530
                 remote_size = int(info['headers']['content-length'])
531
-                remote_checksum = info['headers']['etag'].strip('"')
531
+                remote_checksum = info['headers']['etag'].strip('"\'')
532 532
                 if size == remote_size:
533 533
                     checksum = calculateChecksum('', file, 0, size, self.config.send_chunk)
534 534
                     if remote_checksum == checksum:
... ...
@@ -173,7 +173,7 @@ def subcmd_bucket_list(s3, uri):
173 173
             "uri": uri.compose_uri(bucket, prefix["Prefix"])})
174 174
 
175 175
     for object in response["list"]:
176
-        md5 = object['ETag'].strip('"')
176
+        md5 = object['ETag'].strip('"\'')
177 177
         if cfg.list_md5:
178 178
             if md5.find('-') >= 0: # need to get md5 from the object
179 179
                 object_uri = uri.compose_uri(bucket, object["Key"])
... ...
@@ -775,7 +775,7 @@ def cmd_info(args):
775 775
                 output(u"   File size: %s" % info['headers']['content-length'])
776 776
                 output(u"   Last mod:  %s" % info['headers']['last-modified'])
777 777
                 output(u"   MIME type: %s" % info['headers']['content-type'])
778
-                md5 = info['headers']['etag'].strip('"')
778
+                md5 = info['headers']['etag'].strip('"\'')
779 779
                 try:
780 780
                     md5 = info['s3cmd-attrs']['md5']
781 781
                 except KeyError: