Skip to content

fix(dynamodb): attach X-Amz-Crc32 header to JSON protocol responses#347

Merged
hectorvent merged 2 commits intofloci-io:mainfrom
okinaka:fix/dynamodb-crc32-header
Apr 11, 2026
Merged

fix(dynamodb): attach X-Amz-Crc32 header to JSON protocol responses#347
hectorvent merged 2 commits intofloci-io:mainfrom
okinaka:fix/dynamodb-crc32-header

Conversation

@okinaka
Copy link
Copy Markdown
Contributor

@okinaka okinaka commented Apr 11, 2026

Summary

The AWS SDK for Go v2 DynamoDB client wraps every response body in a CRC32-verifying reader (service/dynamodb/internal/customizations/checksum.go). When the X-Amz-Crc32 header is missing, the expected value defaults to 0, the verifier's Close() returns a checksum mismatch error, and smithy-go's closeResponseBody middleware logs "failed to close HTTP response body, this may affect connection reuse" on every DynamoDB call.

Real AWS DynamoDB includes this header on every response (success and error). This PR adds it for floci's JSON protocol responses so the warning goes away and clients get a real integrity check.

Where the wrapping lives

  • DynamoDbResponses.withCrc32() — new helper in services/dynamodb/ that pre-serializes the entity to bytes, computes the CRC32, and rebuilds the Response with Content-Type: application/x-amz-json-1.0 and the header.
  • AwsJsonController — calls the helper for the DynamoDB and DynamoDBStreams cases.

The wrapping is applied at the JSON protocol boundary (not inside DynamoDbJsonHandler) because DynamoDbJsonHandler.handle() is also invoked from AwsJsonCborController, AwsServiceRouter (API Gateway proxy), and AslExecutor (Step Functions tasks). Those callers need to keep the original ObjectNode entity and use a different content type.

CBOR protocol CRC32 is a follow-up — it's not involved in the Go SDK warning surfaced here.

Type of change

  • Bug fix (fix:)
  • New feature (feat:)
  • Breaking change (feat!: or fix!:)
  • Docs / chore

AWS Compatibility

Verified against AWS SDK for Go v2 (github.com/aws/aws-sdk-go-v2/service/dynamodb@v1.57.0) using compatibility-tests/sdk-test-go/tests/dynamodb_test.go. Before: every DynamoDB test emitted 1+ failed to close HTTP response body warnings (10 per full TestDynamoDB run). After: 0 warnings, all sub-tests pass.

Checklist

  • ./mvnw test passes locally (1715/1715 — including DynamoDbCborIntegrationTest, StepFunctionsDynamoDbIntegrationTest, and the new DynamoDbResponsesTest)
  • New or updated integration test added
    • DynamoDbResponsesTest — 6 unit tests for the helper (ObjectNode/byte[]/null entity, status code, header preservation, null input)
    • DynamoDbIntegrationTest.responseIncludesCorrectXAmzCrc32Header — E2E verification that success (200) and error (400) responses carry a correct CRC32 header
  • Commit messages follow Conventional Commits

The AWS SDK for Go v2 DynamoDB client wraps every response body in a
CRC32-verifying reader and emits "failed to close HTTP response body,
this may affect connection reuse" on every call when the header is
missing. Real AWS DynamoDB includes this header on all responses.

Add it at the JSON protocol boundary (AwsJsonController) for both
DynamoDB and DynamoDBStreams, using a new DynamoDbResponses helper
that serializes the entity to bytes, computes the CRC32, and rebuilds
the Response with the bytes + header. Error responses are wrapped as
well to match real AWS behavior.

The wrapping lives in AwsJsonController rather than DynamoDbJsonHandler
because the handler is also invoked from CBOR, API Gateway proxy, and
Step Functions task flows — those callers must keep the original
ObjectNode entity.

Add unit tests for DynamoDbResponses and an integration test that
verifies the header is present and matches the CRC32 of the response
body bytes on both success and error responses.
Copilot AI review requested due to automatic review settings April 11, 2026 10:55
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves DynamoDB (and DynamoDBStreams) AWS JSON protocol compatibility by ensuring responses include the X-Amz-Crc32 header, matching real AWS DynamoDB behavior and preventing AWS SDK for Go v2 checksum-close warnings.

Changes:

  • Add DynamoDbResponses.withCrc32(...) to pre-serialize JSON responses, compute CRC32, and attach X-Amz-Crc32.
  • Apply the CRC32 wrapping at the JSON protocol boundary in AwsJsonController for DynamoDB and DynamoDBStreams only.
  • Add unit and integration test coverage to validate header presence and correctness on both success and error responses.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/main/java/io/github/hectorvent/floci/services/dynamodb/DynamoDbResponses.java New helper to serialize response bodies, compute CRC32, and attach X-Amz-Crc32 while preserving headers/status.
src/main/java/io/github/hectorvent/floci/core/common/AwsJsonController.java Wrap DynamoDB/DynamoDBStreams JSON responses with CRC32 header at the protocol boundary.
src/test/java/io/github/hectorvent/floci/services/dynamodb/DynamoDbResponsesTest.java New unit tests for withCrc32 behavior (entity types, headers, status preservation).
src/test/java/io/github/hectorvent/floci/services/dynamodb/DynamoDbIntegrationTest.java New E2E verification that real HTTP responses include correct X-Amz-Crc32 on success and error.

Address Copilot review comment on floci-io#347: ".getBytes()"
uses the platform default charset, which can make the test (and the
computed CRC32) vary across environments. The string is ASCII so the
bytes are the same on any sensible platform, but being explicit about
UTF-8 makes the determinism obvious and matches the rest of the
codebase.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Collaborator

@hectorvent hectorvent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @okinaka

@hectorvent hectorvent merged commit 3d3f12d into floci-io:main Apr 11, 2026
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants