service: Check content-length before etag

If the received content-length does not match expectations, of course
the etag won't match!

Co-Authored-By: Alistair Coles <alistairncoles@gmail.com>
Change-Id: I1a0c066c11b94718fffbb11e13b82d0b16e01626
This commit is contained in:
Tim Burke 2023-03-10 09:22:34 -08:00
parent 0f2b567953
commit 6adb8bb17f
2 changed files with 25 additions and 9 deletions

View File

@ -457,13 +457,6 @@ class _SwiftReader:
self._check_contents()
def _check_contents(self):
if self._actual_md5 and self._expected_md5:
etag = self._actual_md5.hexdigest()
if etag != self._expected_md5:
raise SwiftError('Error downloading {0}: md5sum != etag, '
'{1} != {2}'.format(
self._path, etag, self._expected_md5))
if (self._content_length is not None and
self._actual_read != self._content_length):
raise SwiftError('Error downloading {0}: read_length != '
@ -471,6 +464,13 @@ class _SwiftReader:
self._path, self._actual_read,
self._content_length))
if self._actual_md5 and self._expected_md5:
etag = self._actual_md5.hexdigest()
if etag != self._expected_md5:
raise SwiftError('Error downloading {0}: md5sum != etag, '
'{1} != {2}'.format(
self._path, etag, self._expected_md5))
def bytes_read(self):
return self._actual_read

View File

@ -196,8 +196,24 @@ class TestSwiftReader(unittest.TestCase):
# Check error is raised if SwiftReader doesn't read the same length
# as the content length it is created with
sr = self.sr('path', BytesIO(b'body'), {'content-length': 5})
self.assertRaises(SwiftError, _consume, sr)
sr = self.sr('path', BytesIO(b'body'), {'content-length': 5,
'etag': 'bad etag'})
with self.assertRaises(SwiftError) as cm:
_consume(sr)
self.assertEqual(
"'Error downloading path: read_length != content_length, 4 != 5'",
str(cm.exception))
# Check error is raised if SwiftReader doesn't calculate the expected
# hash
sr = self.sr('path', BytesIO(b'body'), {'content-length': 4,
'etag': 'bad etag'})
with self.assertRaises(SwiftError) as cm:
_consume(sr)
self.assertEqual(
"'Error downloading path: md5sum != etag, "
"841a2d689ad86bd1611447453c22c6fc != bad etag'",
str(cm.exception))
sr = self.sr('path', BytesIO(b'body'), {'content-length': 4})
_consume(sr)