(
self,
fin: bool,
opcode: int | cython_int, # Union intended: Cython pxd uses C int
payload: bytes | bytearray,
compressed: int | cython_int, # Union intended: Cython pxd uses C int
)
| 187 | return EMPTY_FRAME |
| 188 | |
| 189 | def _handle_frame( |
| 190 | self, |
| 191 | fin: bool, |
| 192 | opcode: int | cython_int, # Union intended: Cython pxd uses C int |
| 193 | payload: bytes | bytearray, |
| 194 | compressed: int | cython_int, # Union intended: Cython pxd uses C int |
| 195 | ) -> None: |
| 196 | msg: WSMessage |
| 197 | if opcode in {OP_CODE_TEXT, OP_CODE_BINARY, OP_CODE_CONTINUATION}: |
| 198 | # Validate continuation frames before processing |
| 199 | if opcode == OP_CODE_CONTINUATION and self._opcode == OP_CODE_NOT_SET: |
| 200 | raise WebSocketError( |
| 201 | WSCloseCode.PROTOCOL_ERROR, |
| 202 | "Continuation frame for non started message", |
| 203 | ) |
| 204 | |
| 205 | # load text/binary |
| 206 | if not fin: |
| 207 | # got partial frame payload |
| 208 | if opcode != OP_CODE_CONTINUATION: |
| 209 | self._opcode = opcode |
| 210 | self._partial += payload |
| 211 | return |
| 212 | |
| 213 | has_partial = bool(self._partial) |
| 214 | if opcode == OP_CODE_CONTINUATION: |
| 215 | opcode = self._opcode |
| 216 | self._opcode = OP_CODE_NOT_SET |
| 217 | # previous frame was non finished |
| 218 | # we should get continuation opcode |
| 219 | elif has_partial: |
| 220 | raise WebSocketError( |
| 221 | WSCloseCode.PROTOCOL_ERROR, |
| 222 | "The opcode in non-fin frame is expected " |
| 223 | f"to be zero, got {opcode!r}", |
| 224 | ) |
| 225 | |
| 226 | assembled_payload: bytes | bytearray |
| 227 | if has_partial: |
| 228 | assembled_payload = self._partial + payload |
| 229 | self._partial.clear() |
| 230 | else: |
| 231 | assembled_payload = payload |
| 232 | |
| 233 | # Decompress process must to be done after all packets |
| 234 | # received. |
| 235 | if compressed: |
| 236 | if not self._decompressobj: |
| 237 | self._decompressobj = ZLibDecompressor(suppress_deflate_header=True) |
| 238 | # XXX: It's possible that the zlib backend (isal is known to |
| 239 | # do this, maybe others too?) will return max_length bytes, |
| 240 | # but internally buffer more data such that the payload is |
| 241 | # >max_length, so we return one extra byte and if we're able |
| 242 | # to do that, then the message is too big. |
| 243 | payload_merged = self._decompressobj.decompress_sync( |
| 244 | assembled_payload + WS_DEFLATE_TRAILING, |
| 245 | ( |
| 246 | self._max_msg_size + 1 |
no test coverage detected