Skip to content

Commit

Permalink
websocket: fix bug where interleaved control frame breaks compression
Browse files Browse the repository at this point in the history
  • Loading branch information
staticglobal committed Dec 4, 2023
1 parent b3f2a4b commit dd1de5e
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions tornado/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,9 @@ async def _receive_frame(self) -> None:
reserved_bits = header & self.RSV_MASK
opcode = header & self.OPCODE_MASK
opcode_is_control = opcode & 0x8
if self._decompressor is not None and opcode != 0:
# Control frames are never compressed, but can also be interleaved with a series
# of fragmented data frames. Don't let them affect _frame_compressed
if self._decompressor is not None and opcode != 0 and not opcode_is_control:
# Compression flag is present in the first frame's header,
# but we can't decompress until we have all the frames of
# the message.
Expand Down Expand Up @@ -1197,7 +1199,10 @@ def _handle_message(self, opcode: int, data: bytes) -> "Optional[Future[None]]":
if self.client_terminated:
return None

if self._frame_compressed:
opcode_is_control = opcode & 0x8
# _frame_compressed does not apply to control frames.
# Control frames are never compressed.
if self._frame_compressed and not opcode_is_control:
assert self._decompressor is not None
try:
data = self._decompressor.decompress(data)
Expand Down

0 comments on commit dd1de5e

Please sign in to comment.