Chrome browser refuses IDF Websocket upgrade response

PeterR
Posts: 568
Joined: Mon Jun 04, 2018 2:47 pm

Chrome browser refuses IDF Websocket upgrade response

Postby PeterR » Thu Oct 01, 2020 11:18 am

I have created an MQTT QoS0 server using the (new) ESP-IDF websocket server.
I am testing the MQTT server using the HiveMQ client but have also created a quick Pahoo webpage hack.
HiveMQ seems to work fine under Firefox but fails to MQTT connect under Chrome reporting 'Connect failed: AMQJS0007E Socket error:undefined'.
Wireshark shows that Chrome disconnects immediately after receiving the MQTT server's (well actually the HTTP server at this stage) Websocket upgrade response.

Throwing together a webpage using Paho Javascript MQTT client and Chrome console reports:

Code: Select all

mqttws31.js:982 WebSocket connection to 'ws://192.168.80.100/mqtt' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
Paho.MQTT.ClientImpl._doConnect @ mqttws31.js:982
Paho.MQTT.ClientImpl.connect @ mqttws31.js:852
Client.connect @ mqttws31.js:1809
Enclosed are Wireshark captures etc.
There seems to be an issue with the ESP websocket server library?

EDIT: I tried the websocket echo server example. The following Javascript works within Chrome. Why would one upgrade work & not the other?

Code: Select all

function test_websocket()
{   
    if ("WebSocket" in window) {
        //alert("WebSocket is supported by your Browser!");
        
        // Let us open a web socket
        var ws = new WebSocket("ws://192.168.0.48/ws");
            
        ws.onopen = function() {
            
            // Web Socket is connected, send data using send()
            ws.send("Message to send");
            alert("Message is sent...");
        };
            
        ws.onmessage = function (evt) { 
            var received_msg = evt.data;
            alert("Message is received...'" + received_msg + "'");
        };
            
        ws.onclose = function() { 
            
            // websocket is closed.
            alert("Connection is closed..."); 
        };
    } else {        
        // The browser doesn't support WebSocket
        alert("WebSocket NOT supported by your Browser!");
    }
}
Attachments
chrome_websocket.zip
Chrome websocket logs
(22.14 KiB) Downloaded 24 times
& I also believe that IDF CAN should be fixed.

ESP-Marius
Posts: 56
Joined: Wed Oct 23, 2019 1:49 am

Re: Chrome browser refuses IDF Websocket upgrade response

Postby ESP-Marius » Fri Oct 09, 2020 10:35 am

Seems like your websocket client requests the subprocotol mqttv3.1. However the esp32 websocket server doesn't support any subprotocols at the moment and doesn't include this field in the reply (which is a valid response as far as I can see from the RFC)

So my guess would be that with Firefox the browser doesnt care that you didnt select the subprotocol, while Chrome does and terminates the connection.

As for why the last javascript code works from Chrome: it probably doesnt specify a subprotocol (just a normal websocket connection) so everything works fine.

PeterR
Posts: 568
Joined: Mon Jun 04, 2018 2:47 pm

Re: Chrome browser refuses IDF Websocket upgrade response

Postby PeterR » Fri Oct 09, 2020 3:24 pm

Thanks,
Yes, I think you are right. I did not dig into the RFC but the subprotocol & hash were the only differences I could see.

It remains though that Chrome (& I guess other WebKit browsers) will not work with the ESP MQTT client.
Even if Chrome is being naughty & is outside the RFC its quite a popular browser to loose (the debugger is better I feel). AFAIK accepting this subprotocol does not impose on the Websocket.
How about then just 'fake it' & accept the subprotocol?

I'll have a poke & see if I can figure where to add the response.
& I also believe that IDF CAN should be fixed.

ESP-Marius
Posts: 56
Joined: Wed Oct 23, 2019 1:49 am

Re: Chrome browser refuses IDF Websocket upgrade response

Postby ESP-Marius » Sat Oct 10, 2020 8:52 am

I agree, this limits the usability of the websocket server a bit.

Have an in-progress MR for adding subprotocol as a config option for websocket URIs

You can try the attached diff if you are interested.
Attachments
ws_server_protocol_diff.txt
(7.31 KiB) Downloaded 25 times

PeterR
Posts: 568
Joined: Mon Jun 04, 2018 2:47 pm

Re: Chrome browser refuses IDF Websocket upgrade response

Postby PeterR » Mon Oct 12, 2020 12:18 pm

Thanks, that works for me.
For anyone following; I had to change the uri initialiser:

Code: Select all

    static const httpd_uri_t mqttHandler = {
            .method     = HTTP_GET,
            .handler    = mqtts_process,
            .user_ctx   = NULL,
            .is_websocket = true,
            .handle_ws_control_frames = false,
            .subprotocol = "mqttv3.1"
    };
& boost the header buffer using menuconfig

I have access to a number of embedded web browsers. I will test using those over the next week or so & report back.
& I also believe that IDF CAN should be fixed.

ESP-Marius
Posts: 56
Joined: Wed Oct 23, 2019 1:49 am

Re: Chrome browser refuses IDF Websocket upgrade response

Postby ESP-Marius » Tue Oct 13, 2020 1:25 am

That's great!

Who is online

Users browsing this forum: No registered users and 30 guests