Skip to content

Commit

Permalink
fix: preserve existing blob hashes when 'X-Goog-Hash header' is not p…
Browse files Browse the repository at this point in the history
…resent (#267)

Co-authored-by: Tres Seaver <tseaver@palladion.com>
  • Loading branch information
MartinKilonzo and tseaver committed Sep 16, 2020
1 parent ec52b38 commit 277afb8
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
19 changes: 10 additions & 9 deletions google/cloud/storage/blob.py
Expand Up @@ -811,15 +811,16 @@ def _extract_headers_from_download(self, response):
# 'X-Goog-Hash': 'crc32c=4gcgLQ==,md5=CS9tHYTtyFntzj7B9nkkJQ==',
x_goog_hash = response.headers.get("X-Goog-Hash", "")

digests = {}
for encoded_digest in x_goog_hash.split(","):
match = re.match(r"(crc32c|md5)=([\w\d/\+/]+={0,3})", encoded_digest)
if match:
method, digest = match.groups()
digests[method] = digest

self.crc32c = digests.get("crc32c", None)
self.md5_hash = digests.get("md5", None)
if x_goog_hash:
digests = {}
for encoded_digest in x_goog_hash.split(","):
match = re.match(r"(crc32c|md5)=([\w\d/\+/]+={0,3})", encoded_digest)
if match:
method, digest = match.groups()
digests[method] = digest

self.crc32c = digests.get("crc32c", None)
self.md5_hash = digests.get("md5", None)

def _do_download(
self,
Expand Down
12 changes: 9 additions & 3 deletions tests/unit/test_blob.py
Expand Up @@ -1542,10 +1542,16 @@ def test_download_as_string_w_response_headers(self):

def test_download_as_string_w_hash_response_header_none(self):
blob_name = "blob-name"
md5_hash = "CS9tHYTtyFntzj7B9nkkJQ=="
crc32c = "4gcgLQ=="
client = mock.Mock(spec=["_http"])
bucket = _Bucket(client)
media_link = "http://example.com/media/"
properties = {"mediaLink": media_link}
properties = {
"mediaLink": media_link,
"md5Hash": md5_hash,
"crc32c": crc32c,
}
blob = self._make_one(blob_name, bucket=bucket, properties=properties)

response = self._mock_requests_response(
Expand All @@ -1556,8 +1562,8 @@ def test_download_as_string_w_hash_response_header_none(self):
)
blob._extract_headers_from_download(response)

self.assertIsNone(blob.md5_hash)
self.assertIsNone(blob.crc32c)
self.assertEqual(blob.md5_hash, md5_hash)
self.assertEqual(blob.crc32c, crc32c)

def test_download_as_bytes_w_generation_match(self):
GENERATION_NUMBER = 6
Expand Down

0 comments on commit 277afb8

Please sign in to comment.