Skip to content
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

RSV1 set to one but must be zero #23

Closed
gitneko opened this issue Oct 3, 2020 · 3 comments
Closed

RSV1 set to one but must be zero #23

gitneko opened this issue Oct 3, 2020 · 3 comments

Comments

@gitneko
Copy link

gitneko commented Oct 3, 2020

I'm currently in the works of making this library work with MKR1000 and WiFi101 and I'm testing this with a Node.js websocket client. However whenever I try to send a message from Node.js, the connection will fail with Invalid WebSocket frame: RSV1 must be clear, which indicates this library sets RSV1 to one, even though no extension was actually negated (websockets/ws#1140 (comment), https://tools.ietf.org/html/rfc6455#section-5.2).

In my config.h I've uncommented the "debug macros"

#define _DEBUG
#define _DUMP_HANDSHAKE
#define _DUMP_HEADER
#define _DUMP_FRAME_DATA

And on the serial I can see the following getting printed (and that's all of it):

17:43:13.645 -> [Line #0] GET / HTTP/1.1
17:43:13.645 -> [Line #1] Sec-WebSocket-Version: 13
17:43:13.645 -> [Line #2] Sec-WebSocket-Key: aaab5frEyNghA1Yrsz9Fxg==
17:43:13.645 -> [Line #3] Connection: Upgrade
17:43:13.645 -> [Line #4] Upgrade: websocket
17:43:13.645 -> [Line #5] Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
17:43:13.645 -> [Line #6] Host: 192.168.1.39:3000
17:43:13.645 -> [Line #7] 
17:43:13.679 -> New websocket connection

Node.js output:

connected
RangeError: Invalid WebSocket frame: RSV1 must be clear
    at Receiver.getInfo (C:\Users\GG\Downloads\node_modules\ws\lib\receiver.js:178:14)
    at Receiver.startLoop (C:\Users\GG\Downloads\node_modules\ws\lib\receiver.js:131:22)
    at Receiver._write (C:\Users\GG\Downloads\node_modules\ws\lib\receiver.js:78:10)
    at writeOrBuffer (_stream_writable.js:352:12)
    at Receiver.Writable.write (_stream_writable.js:303:10)
    at Socket.socketOnData (C:\Users\GG\Downloads\node_modules\ws\lib\websocket.js:872:35)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:307:12)
    at readableAddChunk (_stream_readable.js:282:9)
    at Socket.Readable.push (_stream_readable.js:221:10) {
  [Symbol(status-code)]: 1002
}

Node.js client code:

const WebSocket = require('ws');

const ws = new WebSocket('ws://192.168.1.39:3000');

const data = {
    "type": "standard",
    "id": 128,
    "dlc": null,
    "rtr": false,
    "data": "hello123"
};

ws.on('error', function (error) {
  console.log(error);
});

ws.on('open', function () {
  console.log('connected');
  setTimeout(() => ws.send(JSON.stringify(data)), 2000);
});

ws.on('message', function (data) {
  console.log(data);
});

I'm using a little more code for all my setup and peripheries, but this is a simplified version:

net::WebSocketServer wss(3000);

void ws_configure_websocket() {
  wss.onConnection([](net::WebSocket& ws) {
    ws.onClose([](net::WebSocket& wsc, const net::WebSocket::CloseCode& code, const char* reason, uint16_t length) {
      Serial.println("Websocket client closed");
    });
    
    ws.onMessage([](net::WebSocket& wsc, const net::WebSocket::DataType& dataType, const char* message, uint16_t length) {
      Serial.println("New websocket message");
    });
    
    Serial.println("New websocket connection");
  });

  wss.begin();
}

void ws_loop_websocket() {
  int status = WiFi.status();

  if (status == WL_CONNECTED) {
    wss.listen();
  }
}

void setup() {
 ws_configure_websocket();
}

void loop() {
  ws_loop_websocket();
}
@skaarj1989
Copy link
Owner

skaarj1989 commented Oct 3, 2020

  1. Test against RSV passed
  2. This implementation does not support any websocket extensions (due to lack of memory).

Can you force disable permessage-deflate in node.js?

@gitneko
Copy link
Author

gitneko commented Oct 3, 2020

The Node.js ws client documentation says that the extension is only enabled if the server supports it and it is enabled, which means that the extension must be negotiated before it is used (which is done by sending a HTTP header in the response to the initial HTTP request).

Which suggests to me, even though the server does not support it, it sends a RSV1 even though it's not enabled and negotiated. Looking at the code, the protocol implementation seems flawed to me. I'll report back after more investigation and testing.

@skaarj1989
Copy link
Owner

On your server listing I don't see any RX FRAME TX FRAME

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

2 participants