fix(transport): remove manual Content-Length headers causing compression errors#5461
Open
bogdanmariusc10 wants to merge 1 commit into
Open
fix(transport): remove manual Content-Length headers causing compression errors#5461bogdanmariusc10 wants to merge 1 commit into
bogdanmariusc10 wants to merge 1 commit into
Conversation
…ng compression errors Fixes #5457 When compression is enabled (COMPRESSION_ENABLED=true), manually setting Content-Length headers before the compression middleware runs causes "Too much data for declared Content-Length" errors because the declared size is uncompressed but the actual body is compressed. Changes: - Remove manual Content-Length from streamablehttp transport (4 locations) - Skip sanitization of compressed responses in ValidationMiddleware - Add 16 regression tests to prevent future occurrences The compression middleware now correctly sets Content-Length after compressing the response body, ensuring the header matches the actual transmitted byte count. Signed-off-by: Bogdan-Marius-Catanus <bogdan-marius.catanus@ibm.com>
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
🔗 Related Issue
Closes #5457
📝 Summary
Fixes "Too much data for declared Content-Length" errors occurring when compression is enabled by removing manual Content-Length headers that are set before the compression middleware runs.
Root Cause: When
COMPRESSION_ENABLED=true(default), the streamable HTTP transport and ValidationMiddleware were manually setting Content-Length headers based on uncompressed body sizes. The compression middleware then compressed the response body but could not update the already-sent headers, causing a mismatch between the declared size and actual transmitted bytes.Solution:
Impact: Eliminates client-side connection errors for responses larger than 500 bytes when compression is active, which was blocking production usage of MCP tool calling in Stage environment.
📏 Reviewability
triage🏷️ Type of Change
🧪 Verification
Automated Testing
make lintmake testuv run pytest tests/unit/mcpgateway/transports/test_streamablehttp_compression_contentlength.py -vuv run pytest tests/unit/mcpgateway/middleware/test_validation_middleware_contentlength.py -vmake coverageTest Coverage
New Regression Tests Added (16 total):
Transport Layer Tests (
test_streamablehttp_compression_contentlength.py):test_send_json_response_no_content_length- Verifies helper function doesn't set Content-Lengthtest_compression_middleware_sets_content_length_correctly- E2E flow with compressiontest_loopback_rpc_routing_no_content_length- Static analysis of source codetest_redis_forwarded_response_no_content_length- Multi-worker forwarding pathtest_content_length_with_compression_disabled- Behavior without compressiontest_large_response_with_compression- Large payloads (10KB+)ValidationMiddleware Tests (
test_validation_middleware_contentlength.py):test_validation_middleware_skips_gzip_compressed_responsestest_validation_middleware_skips_brotli_compressed_responsestest_validation_middleware_skips_zstd_compressed_responsestest_validation_middleware_skips_deflate_compressed_responsestest_validation_middleware_sanitizes_uncompressed_responsestest_validation_middleware_updates_content_length_only_if_modifiedtest_validation_middleware_handles_missing_content_encodingtest_validation_middleware_preserves_large_compressed_responsestest_validation_middleware_handles_empty_content_encodingtest_validation_middleware_case_insensitive_content_encodingFiles Modified
Core Fixes:
mcpgateway/transports/streamablehttp_transport.py- Removed 4 manual Content-Length locations_send_streamable_http_json_response()helper/rpcroutingmcpgateway/middleware/validation_middleware.py- Skip compressed response sanitization (lines 273-276)Test Files Added:
tests/unit/mcpgateway/transports/test_streamablehttp_compression_contentlength.py(395 lines)tests/unit/mcpgateway/middleware/test_validation_middleware_contentlength.py(224 lines)✅ Checklist
make black isort pre-commit)📓 Notes
Known Limitation
One low-priority location still has manual Content-Length:
mcpgateway/transports/mcp_ingress_mount.py:195- 503 error responsesThis is unlikely to trigger compression (error messages typically < 500 bytes) but should be addressed for consistency in a future PR.
Related Issues
This fix addresses the primary bug (Content-Length mismatch). A secondary bug exists where MCP sessions are not cleaned up on connection errors, causing cascading failures after the initial error. This is tracked separately and documented in Issue #5460.
Architecture Context
ASGI Middleware Execution Order (response path is reverse of registration):
On the response path:
Testing Strategy
Unit tests verify:
Integration testing (recommended post-deployment):