Skip to content

Commit 277afb8

Browse files
fix: preserve existing blob hashes when 'X-Goog-Hash header' is not present (#267)
Co-authored-by: Tres Seaver <[email protected]>
1 parent ec52b38 commit 277afb8

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

google/cloud/storage/blob.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -811,15 +811,16 @@ def _extract_headers_from_download(self, response):
811811
# 'X-Goog-Hash': 'crc32c=4gcgLQ==,md5=CS9tHYTtyFntzj7B9nkkJQ==',
812812
x_goog_hash = response.headers.get("X-Goog-Hash", "")
813813

814-
digests = {}
815-
for encoded_digest in x_goog_hash.split(","):
816-
match = re.match(r"(crc32c|md5)=([\w\d/\+/]+={0,3})", encoded_digest)
817-
if match:
818-
method, digest = match.groups()
819-
digests[method] = digest
820-
821-
self.crc32c = digests.get("crc32c", None)
822-
self.md5_hash = digests.get("md5", None)
814+
if x_goog_hash:
815+
digests = {}
816+
for encoded_digest in x_goog_hash.split(","):
817+
match = re.match(r"(crc32c|md5)=([\w\d/\+/]+={0,3})", encoded_digest)
818+
if match:
819+
method, digest = match.groups()
820+
digests[method] = digest
821+
822+
self.crc32c = digests.get("crc32c", None)
823+
self.md5_hash = digests.get("md5", None)
823824

824825
def _do_download(
825826
self,

tests/unit/test_blob.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,10 +1542,16 @@ def test_download_as_string_w_response_headers(self):
15421542

15431543
def test_download_as_string_w_hash_response_header_none(self):
15441544
blob_name = "blob-name"
1545+
md5_hash = "CS9tHYTtyFntzj7B9nkkJQ=="
1546+
crc32c = "4gcgLQ=="
15451547
client = mock.Mock(spec=["_http"])
15461548
bucket = _Bucket(client)
15471549
media_link = "http://example.com/media/"
1548-
properties = {"mediaLink": media_link}
1550+
properties = {
1551+
"mediaLink": media_link,
1552+
"md5Hash": md5_hash,
1553+
"crc32c": crc32c,
1554+
}
15491555
blob = self._make_one(blob_name, bucket=bucket, properties=properties)
15501556

15511557
response = self._mock_requests_response(
@@ -1556,8 +1562,8 @@ def test_download_as_string_w_hash_response_header_none(self):
15561562
)
15571563
blob._extract_headers_from_download(response)
15581564

1559-
self.assertIsNone(blob.md5_hash)
1560-
self.assertIsNone(blob.crc32c)
1565+
self.assertEqual(blob.md5_hash, md5_hash)
1566+
self.assertEqual(blob.crc32c, crc32c)
15611567

15621568
def test_download_as_bytes_w_generation_match(self):
15631569
GENERATION_NUMBER = 6

0 commit comments

Comments
 (0)