Countour-Integral
Countour-Integral

Reputation: 1154

Websocket Handshake - Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value

I am using Python's socket to respond to Websocket requests and I am facing problems with the Sec-WebSocket-Accept header. There might have been problems like this asked before but no one worked for me

The documentation at https://developer.mozilla.org states that for the connection to be established :

The server takes the value of the Sec-WebSocket-Key sent in the handshake request, appends 258EAFA5-E914-47DA-95CA-C5AB0DC85B11, takes SHA-1 of the new value, and is then base64 encoded.

The response I am currently sending is wrapped in a function that takes in the key from the request and does what is said in the documentation

def socket101(self,template,key):
    key = key.strip()
    key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" #Add the key
    key = sha1(key.encode()).digest() #Take the sha1
    key = b64encode(key) #B64 encode it
    return (b"HTTP/1.1 101 Switching Protocols\n"
            +b"Content-Type: text/html\n"
            +b"Connection: Upgrade\n"
            +b"Upgrade: websocket\n"
            +"Sec-WebSocket-Accept: {}\n".format(key).encode()
            +b"\n"
            )    

Then I am calling the above method as follows

def AwaitMessage(client,address):
    while True:
        data = client.recv(1024)
        try:
            if str(data.strip()) != '': 
                headers = ParseHeaders(data) #Parses the request headers
                HTTP_MSG = socket101(headers['Sec-WebSocket-Key']) #Call the function above passing the key
                client.send(HTTP_MSG) #Send the message
        except Exception as f:
              pass
    client.close()

But this does not want whatever I do and throws the following error:

Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value

The browser does not provide any information on why it is incorrect and I can't guess.

The JavaScript code is just making the connection with the socket.

const host = window.location.host
const PORT = 8000;
const socket = new WebSocket(`ws://${host}:${PORT}/ws/connection`)

Any ideas?

Upvotes: 0

Views: 1942

Answers (1)

Countour-Integral
Countour-Integral

Reputation: 1154

The following code worked for me

from base64 import b64encode 
from hashlib import sha1

key = b64encode(sha1((key + GUID).encode()).digest()) #This
return (b"HTTP/1.1 101 Switching Protocols\n"
        +b"Content-Type: text/html\n"
        +b"Connection: Upgrade\n"
        +b"Upgrade: websocket\n"
        +b"Sec-WebSocket-Accept: " + key + b"\n" #Maybe this did something?
        +b"\n"
        )    

I am almost sure that it is exactly the same as the thing I have above but the above does not work.

EDIT: The problem was that type(key) is bytes and thus f'{key}' will wrap quotes arround it, but on the snippet above it is concatinated with other bytes.

Upvotes: 1

Related Questions