You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
import{WebSocketServer}from"ws";import{once}from"node:events";constserver=newWebSocketServer({host: "127.0.0.1",port: 6680,});awaitonce(server,"listening");console.log("Server is listening")server.on("connection",(sock,request)=>{console.log("Server has received client connection, port",request.socket.remotePort);setTimeout(()=>{console.log("Server is closing client connection");sock.close();},3000);});constclient=newWebSocket(`ws://127.0.0.1:6680`);console.log("Client is created");awaitonce(client,"open");console.log("Client is open");awaitonce(client,"close");console.log("Client is closed");server.close();console.log("Server is closing");awaitonce(server,"close");console.log("Server is closed");
How often does it reproduce? Is there a required condition?
This bug always happens when the above snippet is invoked with --experimental-websocket flag.
node --experimental-websocket main.mjs
What is the expected behavior? Why is that the expected behavior?
The expected behavior may be obtained by importing WebSocket from ws package.
The console log is:
Server is listening
Client is created
Server has received client connection, port 49956
Client is open
Server is closing client connection
Client is closed
Server is closing
Server is closed
ws-websocket.pcapng.zip is the packet capture of this execution.
When the WebSocketServer closes the client connection in Frame 8, the WebSocket client responds with a Close frame in Frame 10.
Close frame from ws WebSocket client is encoded as:
Notably, there isn't a payload field in this packet.
What do you see instead?
The console log is:
Server is listening
Client is created
(node:289454) [UNDICI-WS] Warning: WebSockets are experimental, expect them to change at any time.
(Use `node --trace-warnings ...` to show where the warning was created)
Server has received client connection, port 34810
Client is open
Server is closing client connection
node:events:496
throw er; // Unhandled 'error' event
^
RangeError: Invalid WebSocket frame: invalid status code 0
at Receiver.controlMessage (/home/ubuntu/x/node_modules/.pnpm/ws@8.16.0/node_modules/ws/lib/receiver.js:633:30)
at Receiver.getData (/home/ubuntu/x/node_modules/.pnpm/ws@8.16.0/node_modules/ws/lib/receiver.js:481:12)
at Receiver.startLoop (/home/ubuntu/x/node_modules/.pnpm/ws@8.16.0/node_modules/ws/lib/receiver.js:171:16)
at Receiver._write (/home/ubuntu/x/node_modules/.pnpm/ws@8.16.0/node_modules/ws/lib/receiver.js:98:10)
at writeOrBuffer (node:internal/streams/writable:564:12)
at _write (node:internal/streams/writable:493:10)
at Writable.write (node:internal/streams/writable:502:10)
at Socket.socketOnData (/home/ubuntu/x/node_modules/.pnpm/ws@8.16.0/node_modules/ws/lib/websocket.js:1303:35)
at Socket.emit (node:events:518:28)
at addChunk (node:internal/streams/readable:559:12)
Emitted 'error' event on WebSocket instance at:
at Receiver.receiverOnError (/home/ubuntu/x/node_modules/.pnpm/ws@8.16.0/node_modules/ws/lib/websocket.js:1189:13)
at Receiver.emit (node:events:518:28)
at emitErrorNT (node:internal/streams/destroy:169:8)
at emitErrorCloseNT (node:internal/streams/destroy:128:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
code: 'WS_ERR_INVALID_CLOSE_CODE',
[Symbol(status-code)]: 1002
}
Node.js v20.11.0
While the error appears to come from ws, it is caused by incorrect packet encoding by Node.js native WebSocket implementation. node-websocket.pcapng.zip is the packet capture of this execution.
When the WebSocketServer closes the client connection in Frame 8, the WebSocket client responds with a Close frame in Frame 10.
Close frame from Node.js native WebSocket is encoded as:
The Close frame MAY contain a body that indicates a reason for closing.
If there is a body, the first two bytes of the body MUST be a 2-byte unsigned integer (in network byte order) representing a status code with value /code/ defined in Section 7.4.
Version
v20.11.0
Platform
Linux ndndev 6.1.0-17-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.69-1 (2023-12-30) x86_64 x86_64 x86_64 GNU/Linux
Subsystem
WebSocket
What steps will reproduce the bug?
main.mjs
package.json
How often does it reproduce? Is there a required condition?
This bug always happens when the above snippet is invoked with
--experimental-websocket
flag.What is the expected behavior? Why is that the expected behavior?
The expected behavior may be obtained by importing
WebSocket
from ws package.The console log is:
ws-websocket.pcapng.zip is the packet capture of this execution.
When the WebSocketServer closes the client connection in Frame 8, the WebSocket client responds with a Close frame in Frame 10.
Close frame from ws WebSocket client is encoded as:
Notably, there isn't a payload field in this packet.
What do you see instead?
The console log is:
While the error appears to come from ws, it is caused by incorrect packet encoding by Node.js native WebSocket implementation.
node-websocket.pcapng.zip is the packet capture of this execution.
When the WebSocketServer closes the client connection in Frame 8, the WebSocket client responds with a Close frame in Frame 10.
Close frame from Node.js native WebSocket is encoded as:
Notably, there's a payload containing a Status code that is zero.
Additional information
According to RFC 6455 section 5.5.1:
According to RFC 6455 section 7.4.2:
Node.js native WebSocket client has violated the protocol by sending an unassigned value as the status code.
The text was updated successfully, but these errors were encountered: