Fix/http encoder stream flush - #4227
Open
matthid wants to merge 3 commits into
Open
Conversation
Stream compressors buffer small writes internally: after writing a body chunk, Encoder::poll_next's take() returns nothing and the compressed bytes stay inside the encoder until finish() runs at stream end. A streaming response body (SSE, for example) wrapped in the Compress middleware is therefore delivered as a single burst when the stream completes, not incrementally as chunks are produced — the first chunk only ever carries the bare gzip header. Flush the encoder whenever an in-place or blocking write produces no output so each body chunk reaches the client as it is produced. Large writes that produce output immediately are unaffected; full-body compression is unchanged apart from the added sync markers. Regression test gates the body on a channel and asserts compressed bytes for the first events arrive before the gate is released; without the flush it times out because nothing but the gzip header is sent before the stream ends.
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.
The background of this change is that I deploy my services behind cloud flare. Cloud flare has a timeout on stale connections. Usually this is solved with streaming. However once compression is enabled this no longer works hence this patch.
It was created by AI.
AI Generated:
Stream compressors buffer small writes internally: after writing a body chunk, Encoder::poll_next's take() returns nothing and the compressed bytes stay inside the encoder until finish() runs at stream end. A streaming response body (SSE, for example) wrapped in the Compress middleware is therefore delivered as a single burst when the stream completes, not incrementally as chunks are produced — the first chunk only ever carries the bare gzip header.
Flush the encoder whenever an in-place or blocking write produces no output so each body chunk reaches the client as it is produced. Large writes that produce output immediately are unaffected; full-body compression is unchanged apart from the added sync markers.
Regression test gates the body on a channel and asserts compressed bytes for the first events arrive before the gate is released; without the flush it times out because nothing but the gzip header is sent before the stream ends.
PR Type
Bug Fix
PR_TYPE
PR Checklist
Overview