websockets / ws

Simple to use, blazing fast and thoroughly tested WebSocket client and server for Node.js
MIT License
21.33k stars 2.3k forks source link

Sec-WebSocket-Accept not found #2196

Closed zekageri closed 5 months ago

zekageri commented 5 months ago

Is there an existing issue for this?

Description

I want to write a websocket client application for ESP32. For this I'm using the native ESP32 IDF websocket client library.

When the clients wants to connect to my node,js server which hosts websocket with express app i got Sec-WebSocket-Accept not found.

Here is my node.js implementation

import express from "express";
import http from "http";
import { WebSocketServer } from 'ws';

const app = express();
const server = http.createServer(app);
const wss = new WebSocketServer({ server });

wss.on('connection', function(ws) {
    console.log("Client connected!");

    ws.on('error', console.error);

    ws.on('message', function(data) {
      console.log('received: %s', data);
    });

    ws.on("close", function() {
        console.log("Client disconnected!");
    });

    setInterval(() => {
        ws.send('Test message');
    }, 5000);
});

server.listen(80, () => {
    console.log(`Server listening on port 80`);
});

It should be very simple. My server is reachable at ws://bridgetest-9q8c.onrender.com/ It can be http or https.

Can it happan that Sec-WebSocket-Accept header is not specified on handshake?

ws version

latest

Node.js Version

latest

System

render.com

Expected result

My client should connect to my node.js server.

Actual result

My client throws an error that it can not find the Sec-WebSocket-Accept header on handshake.

Attachments

Websocket client is based on the standard: https://www.rfc-editor.org/rfc/rfc6455.txt

Some debug messages from ESP32

E (7712413) TRANSPORT_WS: Sec-WebSocket-Accept not found
E (7712414) WEBSOCKET_CLIENT: Error transport connect
[HsH_SocketClient] - Disconnected
lpinca commented 5 months ago

Can it happan that Sec-WebSocket-Accept header is not specified on handshake?

No, the header is always set here https://github.com/websockets/ws/blob/8.16.0/lib/websocket-server.js#L382.

zekageri commented 5 months ago

Strange, my client can't see it...

lpinca commented 5 months ago
$ cat index.js 
const WebSocket = require('ws');

const ws = new WebSocket('ws://bridgetest-9q8c.onrender.com/', {
  followRedirects: true
});

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

ws.on('upgrade', function (response) {
  console.log(response.headers);
});

ws.on('open', ws.close);
$ node index.js 
wss://bridgetest-9q8c.onrender.com/
{
  date: 'Wed, 17 Jan 2024 17:58:49 GMT',
  connection: 'upgrade',
  upgrade: 'websocket',
  'sec-websocket-accept': 'i4X3O6pkgSy2QVrjTp3vZhJ+T0k=',
  'cf-ray': '84707d10fd820e1b-MXP',
  'cf-cache-status': 'DYNAMIC',
  'set-cookie': [
    '_cfuvid=L683UfuKzUAIfKAmtUfAKER28jtalDaaDA6LbSALDXo-1705514329842-0-604800000; path=/; domain=.onrender.com; HttpOnly; Secure; SameSite=None'
  ],
  server: 'cloudflare',
  'alt-svc': 'h3=":443"; ma=86400'
}

It seems that

  1. ws: redirects to wss:. Your client might not follow redirects.
  2. The response header is lower cased and your client might not like that.
zekageri commented 5 months ago

Oh its redirecting. Thank you for your help. I will investigate that.

lpinca commented 5 months ago

I'm closing this as answered.

zekageri commented 5 months ago

The problem still presist, most likely the lowercase headers causing it

lpinca commented 5 months ago

Yes, but it's not a ws issue.