Skip to content

RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear #2098

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
ORESoftware opened this issue Nov 18, 2022 · 11 comments
Closed
1 task done

RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear #2098

ORESoftware opened this issue Nov 18, 2022 · 11 comments

Comments

@ORESoftware
Copy link

ORESoftware commented Nov 18, 2022

Is there an existing issue for this?

  • I've searched for any related issues and avoided creating a duplicate issue.

Description

Not sure what causes this error, but looking for find away around it.

In a child process, I have:

process.on('message', (m,socket) => {
    console.log('child received message:', m);
    socket.write('foo'); // <---- error happens here!
});

in the parent, I create the child using:

const cp = require('child_process');
const ws = require('ws');
const server = new ws.WebSocketServer({port: 5151});


server.on('connection', c => {

    console.log('new connection');

    const fd = c._socket._handle.fd; // ignore for now

    const k = cp.fork('k.js', ['--file-descriptor', fd],{
        stdio: 'pipe',
        detached: false
    });

    k.send('foobar', c._socket);

    k.on('message', (a, b, c) => {
        console.log('parent received message:', a, b, c);
    });

    k.stdout.pipe(process.stdout);
    k.stderr.pipe(process.stderr);


});

here is the full stack trace;

RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear
    at Receiver.getInfo (/Users/alex.mills/codes/uta-phd/node_modules/ws/lib/receiver.js:176:14)
    at Receiver.startLoop (/Users/alex.mills/codes/uta-phd/node_modules/ws/lib/receiver.js:136:22)
    at Receiver._write (/Users/alex.mills/codes/uta-phd/node_modules/ws/lib/receiver.js:83:10)
    at writeOrBuffer (node:internal/streams/writable:392:12)
    at _write (node:internal/streams/writable:333:10)
    at Writable.write (node:internal/streams/writable:337:10)
    at Socket.socketOnData (/Users/alex.mills/codes/uta-phd/node_modules/ws/lib/websocket.js:1272:35)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:324:12)

ws version

"version": "8.11.0",

Node.js Version

v18.12.1

System

System:
OS: macOS 12.6
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 24.73 MB / 32.00 GB
Shell: 5.8.1 - /bin/zsh

Expected result

No response

Actual result

No response

Attachments

No response

@lpinca
Copy link
Member

lpinca commented Nov 18, 2022

It means the WebSocket received an invalid frame.

@lpinca
Copy link
Member

lpinca commented Nov 18, 2022

You can reproduce like this:

const WebSocket = require('ws');

const server = new WebSocket.WebSocketServer({ port: 0 }, function () {
  const websocket = new WebSocket(`ws://localhost:${server.address().port}`);

  websocket.on('open', function () {
    const chunk = Buffer.from('a180', 'hex');

    websocket._socket.write(chunk);
  });
});

server.on('connection', function (websocket) {
  websocket.on('error', console.error);
});

See https://www.rfc-editor.org/rfc/rfc6455#section-5.2.

@lpinca lpinca closed this as completed Nov 18, 2022
@lpinca
Copy link
Member

lpinca commented Nov 18, 2022

See also #154.

@ORESoftware
Copy link
Author

thanks I added a comment to that thread - looking for info on the 'upgrade' event and handleUpgrade, never heard of those, I will look at the docs

@sysrage
Copy link

sysrage commented Apr 12, 2023

@lpinca I'm encountering this invalid frame error fairly-consistently with iOS Safari. Unfortunately, when it happens it disconnects all active websocket connections and they're unable to reconnect.

I've reviewed the following:

Based on feedback in those issues, I've added the following to my server:

ws._socket.prependListener('data', (data) => console.log('ws data', data.toString()));
ws.on('error', (error) => {
  console.error(error);
});

All normal/working frames are shown as binary data, but the frame that breaks the websocket connection is clear text:

ws data ��☻�S�y�'�r�q� �&�j�=�k�2�g��c�#�m�6� �q�g�'�l�q�
���♠��� ������J������J������☺���
ws data {"type":"authenticate","appToken":"testing"}
RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear
    at Receiver.getInfo (C:\project\server\node_modules\ws\lib\receiver.js:186:14)
    at Receiver.startLoop (C:\project\server\node_modules\ws\lib\receiver.js:146:22)
    at Receiver._write (C:\project\help-button\server\node_modules\ws\lib\receiver.js:84:10)
    at writeOrBuffer (node:internal/streams/writable:392:12)
    at _write (node:internal/streams/writable:333:10)
    at Writable.write (node:internal/streams/writable:337:10)
    at Socket.socketOnData (C:\project\server\node_modules\ws\lib\websocket.js:1278:35)
    at Socket.emit (node:events:525:35)
    at addChunk (node:internal/streams/readable:324:12)
    at readableAddChunk (node:internal/streams/readable:297:9) {
  code: 'WS_ERR_UNEXPECTED_RSV_2_3',
  [Symbol(status-code)]: 1002
}
ws data ���‼�L�1�5�v�v�r�8�v�8�p�8�1�n�c�↑�x�"�)�8�`�%�t�1
ws data ���>���∟��[�ݬ_��[��]��∟���N���U���♦���M��Y��

In my test, I have Windows Chrome connected and working perfectly for days. When I make a connection with an iOS Safari device, I often see the above problematic frame. Once the frame is seen, the Chrome connection is dropped and cannot reconnect until the server is restarted.

I realize this is likely an issue with the iOS WebSocket implementation, but it shouldn't be crashing the ws server when I have an error handler present?

@lpinca
Copy link
Member

lpinca commented Apr 12, 2023

@sysrage make sure that the 'error' listener is not removed until the 'close' event is emitted.

@sysrage
Copy link

sysrage commented Apr 12, 2023

@lpinca the listener is never removed. I can keep refreshing the page in iOS and keep getting invalid frame errors (and crashing other clients).

@lpinca
Copy link
Member

lpinca commented Apr 12, 2023

@sysrage see #2098 (comment). The server does not crash.

@sysrage
Copy link

sysrage commented Apr 12, 2023

Sorry, terrible wording all-around on my part. You're correct that nothing is crashing. However, in my configuration, other clients are getting disconnected. The server stays up and reloading the page does re-connect them.

So, my auto-reconnect code is apparently busted since reloading the page works. But, I don't believe a bad frame from one client should disconnect other clients. I'll expand your minimum repro and test with multiple clients to verify. Thank you for the input.

@lpinca
Copy link
Member

lpinca commented Apr 12, 2023

However, in my configuration, other clients are getting disconnected.

It shouldn't be possible because the TCP connection is not shared. There is one socket for each WebSocket.

@sysrage
Copy link

sysrage commented Apr 12, 2023

You're right. It was a bug in my code removing other connections. Sorry for wasting your time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants