From 676d61bf5b99e8c5da13046249995cf46d3c4661 Mon Sep 17 00:00:00 2001 From: Jonathan Bergknoff Date: Fri, 12 Feb 2021 08:26:06 -0600 Subject: [PATCH] Add CRC32 to DynamoDB responses (#3677) * Add CRC32 to DynamoDB responses * Change test assertion * CRC32 - Align Py2/Py3 behaviour Co-authored-by: Bert Blommers --- moto/core/utils.py | 8 ++++++-- moto/dynamodb2/responses.py | 3 ++- tests/test_dynamodb2/test_server.py | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/moto/core/utils.py b/moto/core/utils.py index 97303a508..03258f085 100644 --- a/moto/core/utils.py +++ b/moto/core/utils.py @@ -227,10 +227,14 @@ def gen_amz_crc32(response, headerdict=None): if not isinstance(response, bytes): response = response.encode() - crc = str(binascii.crc32(response)) + crc = binascii.crc32(response) + if six.PY2: + # https://python.readthedocs.io/en/v2.7.2/library/binascii.html + # TLDR: Use bitshift to match Py3 behaviour + crc = crc & 0xFFFFFFFF if headerdict is not None and isinstance(headerdict, dict): - headerdict.update({"x-amz-crc32": crc}) + headerdict.update({"x-amz-crc32": str(crc)}) return crc diff --git a/moto/dynamodb2/responses.py b/moto/dynamodb2/responses.py index 85d265f6d..fe1a463d6 100644 --- a/moto/dynamodb2/responses.py +++ b/moto/dynamodb2/responses.py @@ -8,7 +8,7 @@ import itertools import six from moto.core.responses import BaseResponse -from moto.core.utils import camelcase_to_underscores, amzn_request_id +from moto.core.utils import camelcase_to_underscores, amz_crc32, amzn_request_id from .exceptions import ( InvalidIndexNameError, ItemSizeTooLarge, @@ -80,6 +80,7 @@ class DynamoHandler(BaseResponse): """ return dynamodb_backends[self.region] + @amz_crc32 @amzn_request_id def call_action(self): self.body = json.loads(self.body or "{}") diff --git a/tests/test_dynamodb2/test_server.py b/tests/test_dynamodb2/test_server.py index 880909fac..b2d348ab5 100644 --- a/tests/test_dynamodb2/test_server.py +++ b/tests/test_dynamodb2/test_server.py @@ -17,3 +17,4 @@ def test_table_list(): headers = {"X-Amz-Target": "TestTable.ListTables"} res = test_client.get("/", headers=headers) res.data.should.contain(b"TableNames") + res.headers.should.have.key("X-Amz-Crc32")