keep websocket compression state across interleaved control frames#12988
keep websocket compression state across interleaved control frames#12988arshsmith1 wants to merge 5 commits into
Conversation
|
Is this ready? PR is still in draft. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #12988 +/- ##
==========================================
+ Coverage 98.96% 98.97% +0.01%
==========================================
Files 131 131
Lines 48087 48747 +660
Branches 2496 2541 +45
==========================================
+ Hits 47587 48247 +660
Misses 376 376
Partials 124 124
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
Merging this PR will not alter performance
Comparing Footnotes
|
|
Yeah, it's ready, just marked it out of draft. The fix, regression test, changelog and CONTRIBUTORS entry are all in and CI is green. Sorry for leaving it in draft. |
Co-authored-by: Sam Bull <aa6bs0@sambull.org>
| parser._feed_data(PACK_LEN1(0x40 | WSMsgType.BINARY, half) + compressed[:half]) | ||
| # interleaved ping | ||
| parser._feed_data(PACK_LEN1(0x80 | WSMsgType.PING, 0)) | ||
| # final continuation fragment | ||
| parser._feed_data( |
There was a problem hiding this comment.
Why are we not using the public .feed_data() here?
There was a problem hiding this comment.
Good point, no reason not to. Switched all three feeds to the public feed_data() and dropped a duplicate comment line that slipped in when I applied the suggestions. Suite still green (67 passed).
What do these changes do?
When a permessage-deflate message is split across several frames, a peer may interleave a control frame (ping/pong/close) between the fragments (RFC 6455 §5.4). The reader uses
_frame_finto spot the start of a new message and (re)latch the per-message compression flag, but control frames always carry FIN, so an interleaved one makes the following continuation look like a fresh message and clears that flag. The continuation is then handled as uncompressed: raw deflate bytes are delivered for a binary message, or a UTF-8 error closes the connection for a text one.The fix lets only data frames advance that tracker, so control frames stay transparent to the message framing and the compression state carries across them. The added test feeds a compressed first fragment, a ping, then the continuation and checks the binary message still decompresses.
Are there changes in behavior for the user?
No public API change. A compressed message that previously came back corrupted (or dropped the connection) when a control frame landed mid-message now decodes correctly.
Is it a substantial burden for the maintainers to support this?
No, it is a few lines in the reader plus one regression test.
Related issue number
N/A
Checklist
CONTRIBUTORS.txtCHANGES/folder