* Runs whenever a new chunk is received. * Callback is called whenever there are no more chunks buffering, * or not enough bytes are buffered to parse.
(callback)
| 15460 | * or not enough bytes are buffered to parse. |
| 15461 | */ |
| 15462 | run(callback) { |
| 15463 | while (this.#loop) { |
| 15464 | if (this.#state === parserStates.INFO) { |
| 15465 | if (this.#byteOffset < 2) { |
| 15466 | return callback(); |
| 15467 | } |
| 15468 | const buffer = this.consume(2); |
| 15469 | const fin = (buffer[0] & 128) !== 0; |
| 15470 | const opcode = buffer[0] & 15; |
| 15471 | const masked = (buffer[1] & 128) === 128; |
| 15472 | const fragmented = !fin && opcode !== opcodes.CONTINUATION; |
| 15473 | const payloadLength = buffer[1] & 127; |
| 15474 | const rsv1 = buffer[0] & 64; |
| 15475 | const rsv2 = buffer[0] & 32; |
| 15476 | const rsv3 = buffer[0] & 16; |
| 15477 | if (!isValidOpcode(opcode)) { |
| 15478 | failWebsocketConnection(this.#handler, 1002, "Invalid opcode received"); |
| 15479 | return callback(); |
| 15480 | } |
| 15481 | if (masked) { |
| 15482 | failWebsocketConnection(this.#handler, 1002, "Frame cannot be masked"); |
| 15483 | return callback(); |
| 15484 | } |
| 15485 | if (rsv1 !== 0 && !this.#extensions.has("permessage-deflate")) { |
| 15486 | failWebsocketConnection(this.#handler, 1002, "Expected RSV1 to be clear."); |
| 15487 | return; |
| 15488 | } |
| 15489 | if (rsv2 !== 0 || rsv3 !== 0) { |
| 15490 | failWebsocketConnection(this.#handler, 1002, "RSV1, RSV2, RSV3 must be clear"); |
| 15491 | return; |
| 15492 | } |
| 15493 | if (fragmented && !isTextBinaryFrame(opcode)) { |
| 15494 | failWebsocketConnection(this.#handler, 1002, "Invalid frame type was fragmented."); |
| 15495 | return; |
| 15496 | } |
| 15497 | if (isTextBinaryFrame(opcode) && this.#fragments.length > 0) { |
| 15498 | failWebsocketConnection(this.#handler, 1002, "Expected continuation frame"); |
| 15499 | return; |
| 15500 | } |
| 15501 | if (this.#info.fragmented && fragmented) { |
| 15502 | failWebsocketConnection(this.#handler, 1002, "Fragmented frame exceeded 125 bytes."); |
| 15503 | return; |
| 15504 | } |
| 15505 | if ((payloadLength > 125 || fragmented) && isControlFrame(opcode)) { |
| 15506 | failWebsocketConnection(this.#handler, 1002, "Control frame either too large or fragmented"); |
| 15507 | return; |
| 15508 | } |
| 15509 | if (isContinuationFrame(opcode) && this.#fragments.length === 0 && !this.#info.compressed) { |
| 15510 | failWebsocketConnection(this.#handler, 1002, "Unexpected continuation frame"); |
| 15511 | return; |
| 15512 | } |
| 15513 | if (payloadLength <= 125) { |
| 15514 | this.#info.payloadLength = payloadLength; |
| 15515 | this.#state = parserStates.READ_DATA; |
| 15516 | if (!this.#validatePayloadLength()) { |
| 15517 | return; |
| 15518 | } |
| 15519 | } else if (payloadLength === 126) { |
no test coverage detected