* Parses control frames. * @param {Buffer} body
(body)
| 15699 | * @param {Buffer} body |
| 15700 | */ |
| 15701 | parseControlFrame(body) { |
| 15702 | const { opcode, payloadLength } = this.#info; |
| 15703 | if (opcode === opcodes.CLOSE) { |
| 15704 | if (payloadLength === 1) { |
| 15705 | failWebsocketConnection(this.#handler, 1002, "Received close frame with a 1-byte body."); |
| 15706 | return false; |
| 15707 | } |
| 15708 | this.#info.closeInfo = this.parseCloseBody(body); |
| 15709 | if (this.#info.closeInfo.error) { |
| 15710 | const { code, reason } = this.#info.closeInfo; |
| 15711 | failWebsocketConnection(this.#handler, code, reason); |
| 15712 | return false; |
| 15713 | } |
| 15714 | if (!this.#handler.closeState.has(sentCloseFrameState.SENT) && !this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) { |
| 15715 | let body2 = emptyBuffer; |
| 15716 | if (this.#info.closeInfo.code) { |
| 15717 | body2 = Buffer.allocUnsafe(2); |
| 15718 | body2.writeUInt16BE(this.#info.closeInfo.code, 0); |
| 15719 | } |
| 15720 | const closeFrame = new WebsocketFrameSend(body2); |
| 15721 | this.#handler.socket.write(closeFrame.createFrame(opcodes.CLOSE)); |
| 15722 | this.#handler.closeState.add(sentCloseFrameState.SENT); |
| 15723 | } |
| 15724 | this.#handler.readyState = states.CLOSING; |
| 15725 | this.#handler.closeState.add(sentCloseFrameState.RECEIVED); |
| 15726 | return false; |
| 15727 | } else if (opcode === opcodes.PING) { |
| 15728 | if (!this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) { |
| 15729 | const frame = new WebsocketFrameSend(body); |
| 15730 | this.#handler.socket.write(frame.createFrame(opcodes.PONG)); |
| 15731 | this.#handler.onPing(body); |
| 15732 | } |
| 15733 | } else if (opcode === opcodes.PONG) { |
| 15734 | this.#handler.onPong(body); |
| 15735 | } |
| 15736 | return true; |
| 15737 | } |
| 15738 | get closingInfo() { |
| 15739 | return this.#info.closeInfo; |
| 15740 | } |
no test coverage detected