Websocket: C-Server --> Browser invalid frame header

80 Views Asked by At

Dear stackoverflow forum,

I have a problem with the communication between my C-server and the client (javascript). I am using a Rasperry Pi 4 as server and Chrome as browser (I have also tested my stuff with Firefox and Edge).

My question is what the frame headers of the handshake look like. The handshake should change the communication protocol from HTTP to websocket. My headers look like this:

GET / HTTP/1.1
Host: 192.168.1.100:8000
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/119.0.0.0 Safari/537.36
Upgrade: websocket
Origin: http://192.168.1.100
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Sec-WebSocket-Key: 6Hw/S8rXFY4ExVDMGWWn6Q==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

The answer from the server (the code for generating the response request is attached):

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 57dCnQc8YJrJ51osdI/I71QHYi4=

Now I get the message in the browser:

script.js:8 WebSocket connection to 'ws://192.168.1.100:8000/' failed: Invalid frame header.

In wireshark, I can see that the frame headers look exactly as they do above. The browser (client) responds with a message highlighted in red: The reset flag is set on the response.

Does anyone see an error in the frame header? Or could the hash code be wrong?

Touby

1

There are 1 best solutions below

0
Touby On

Well I found a solution, I had a wrong handling of the incomming data. The data has to be decoded like this:

int rxDataLen = 0;
char rxBuf[rxBufferSize];
char selectedObject;
int16_t controlledValue;
WH_Status_t ret = OK;
uint8_t k = 0;

char rxBuf[rxBufferSize];
int rx_data_len = recv (comSockId, (void *)rxBuf, rxBufferSize, MSG_DONTWAIT);
        // Has a new WebSocket message have been received
        if (rx_data_len > 0) {
            rxBuf[rx_data_len] = '\0';
            // Is the message a handshake request
            if (strncmp(rxBuf, "GET", 3) == 0) {
                printf("%s\n", rxBuf);
                // Yes -> create the handshake response and send it back
                char response[WS_HS_ACCLEN];
                get_handshake_response(rxBuf, response);
                send(comSockId, (void *)response, strlen(response), 0);
                printf("Handshake done\n");
            }
            else {
                /* No -> decode incoming message,
                process the command and
                send back an acknowledge message */
                char command[rx_data_len];
                decode_incoming_request(rxBuf, command);
                command[strlen(command)] = '\0';

                /* Check, if the website has been closed. */
                if (strncmp(command, "close", 5) == 0){
                    printf("Cliend closed connection.\n");
                    return closeClient;
                }

                // Decode the message string to control the webhouse.
                analyseMessage((char*)&command, &selectedObject, &controlledValue);

                char response[6] = {0};
                sendMessage((char*)&(response), &selectedObject, actualTemperature, alarmState);
                printf("Answer: %s\n", response);
                char codedResponse[strlen(response)+1];
                code_outgoing_response (response, codedResponse);
                send(comSockId, (void *)codedResponse,
                strlen(codedResponse), 0);
            }
        }

While a connection is active, you have to loop through this codelines until the connection is closed or you close it from server side.With this, there is no more invalid frame header.