Skip to content

fix(http): compress empty encoded responses#152

Merged
yordis merged 2 commits intomasterfrom
yordis/fix-gzip-empty-responses
May 2, 2026
Merged

fix(http): compress empty encoded responses#152
yordis merged 2 commits intomasterfrom
yordis/fix-gzip-empty-responses

Conversation

@yordis
Copy link
Copy Markdown
Member

@yordis yordis commented May 2, 2026

  • Prevents clients from receiving a declared gzip or deflate response that has no compressed payload to decode.
  • Keeps HTTP compression behavior consistent for empty and non-empty responses.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@cursor
Copy link
Copy Markdown

cursor Bot commented May 2, 2026

PR Summary

Medium Risk
Changes HTTP response encoding behavior for empty bodies by emitting non-empty gzip/deflate payloads; could affect clients/proxies that rely on prior zero-length behavior or content-length handling. Scope is limited and covered by new unit tests for both direct compression and end-to-end Reply writes.

Overview
Ensures HTTP replies that advertise gzip/deflate always include a decodable compressed body, even when the uncompressed response is empty.

HttpEntityManager.CompressResponse now returns precomputed "empty" gzip/deflate members for zero-length inputs, and Reply is reordered so compression occurs before deciding whether to write/close. Adds tests that validate empty compressed bodies can be decompressed and that end-to-end Reply writes a non-empty payload while still decompressing to 0 bytes.

Reviewed by Cursor Bugbot for commit b78b901. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 2, 2026

Warning

Rate limit exceeded

@yordis has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 54 minutes and 10 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 819ed943-a092-4501-8dfa-1c49e9aab27c

📥 Commits

Reviewing files that changed from the base of the PR and between 7aea47d and b78b901.

📒 Files selected for processing (1)
  • src/EventStore.Core.Tests/Services/Transport/Http/compress_response_should.cs

Walkthrough

Empty HTTP responses are now compressed when clients advertise Content-Encoding support. HttpEntityManager applies compression via precomputed gzip/deflate payloads for empty inputs, producing valid compressed bodies. Tests verify compression produces non-empty, valid, and decompress-to-empty results.

Changes

Empty Payload Compression

Layer / File(s) Summary
Core Implementation
src/EventStore.Transport.Http/EntityManagement/HttpEntityManager.cs
Added precomputed static byte arrays EmptyGzipResponse and EmptyDeflateResponse representing valid compressed payloads for zero-length input. Modified CompressResponse to return these arrays when input is empty and gzip/deflate is requested. Updated Reply to always pass response ?? Array.Empty<byte>() through compression before checking payload length, enabling compressed empty bodies to be written.
Tests
src/EventStore.Core.Tests/Services/Transport/Http/compress_response_should.cs
Added three tests: unit tests verify gzip/deflate compression of empty data yields non-empty compressed bytes that decompress to empty strings. Integration test constructs DefaultHttpContext with gzip encoding, sends empty reply via HttpEntityManager, asserts Content-Encoding: gzip header presence and valid gzip body. Updated using directives for ASP.NET Core HTTP types.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Empty payloads once would flee,
But now they're compressed in gzip glee!
Precomputed bytes, so wise and small,
Make valid streams from none at all. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main change: applying compression to empty encoded HTTP responses in the EventStore transport layer.
Description check ✅ Passed The description is directly related to the changeset, explaining the problem (clients receiving declared but uncompressed responses) and the solution (consistent compression behavior).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch yordis/fix-gzip-empty-responses

Tip

💬 Introducing [Slack Agent](https://www.coderabbit.ai/agent): Turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get your free trial and get 200 agent minutes per Slack user (a $50 value).


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 54 minutes and 10 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/EventStore.Core.Tests/Services/Transport/Http/compress_response_should.cs (1)

84-112: 💤 Low value

Consider adding a symmetric integration test for deflate.

There's empty_gzip_reply_has_a_valid_gzip_body but no equivalent empty_deflate_reply_has_a_valid_deflate_body. Since the Reply code path treats both algorithms identically and unit-level coverage exists for deflate, this is low risk—but adding the test would ensure complete parity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/EventStore.Core.Tests/Services/Transport/Http/compress_response_should.cs`
around lines 84 - 112, Add a parallel test to
empty_gzip_reply_has_a_valid_gzip_body that verifies deflate behavior: create a
new test method (e.g., empty_deflate_reply_has_a_valid_deflate_body) that sets
context.Request.Headers["Accept-Encoding"] = CompressionAlgorithms.Deflate,
calls manager.Reply(Array.Empty<byte>(), 200, "OK", "text/plain", Encoding.UTF8,
null, ex => error = ex) on the same HttpEntity/manager setup, assert the
response header context.Response.Headers["Content-Encoding"] equals
CompressionAlgorithms.Deflate, confirm responseBody.Length > 0 and then
decompress using System.IO.Compression.DeflateStream to verify the uncompressed
output length is 0 and error is null and the completed event was signaled.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@src/EventStore.Core.Tests/Services/Transport/Http/compress_response_should.cs`:
- Around line 84-112: Add a parallel test to
empty_gzip_reply_has_a_valid_gzip_body that verifies deflate behavior: create a
new test method (e.g., empty_deflate_reply_has_a_valid_deflate_body) that sets
context.Request.Headers["Accept-Encoding"] = CompressionAlgorithms.Deflate,
calls manager.Reply(Array.Empty<byte>(), 200, "OK", "text/plain", Encoding.UTF8,
null, ex => error = ex) on the same HttpEntity/manager setup, assert the
response header context.Response.Headers["Content-Encoding"] equals
CompressionAlgorithms.Deflate, confirm responseBody.Length > 0 and then
decompress using System.IO.Compression.DeflateStream to verify the uncompressed
output length is 0 and error is null and the completed event was signaled.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 504582cd-0f22-4e52-9ad8-c8c88746aeef

📥 Commits

Reviewing files that changed from the base of the PR and between 13a7bb2 and 7aea47d.

📒 Files selected for processing (2)
  • src/EventStore.Core.Tests/Services/Transport/Http/compress_response_should.cs
  • src/EventStore.Transport.Http/EntityManagement/HttpEntityManager.cs

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis yordis merged commit 08ec77b into master May 2, 2026
18 checks passed
@yordis yordis deleted the yordis/fix-gzip-empty-responses branch May 2, 2026 20:48
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.

1 participant