Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[python] websocket handshake gaat fout

Pagina: 1
Acties:

  • williewonka03
  • Registratie: Augustus 2010
  • Laatst online: 16-06-2024
hallo allemaal,

ik probeer op het moment een websocket server te maken in python 3. Het probleem is alleen dat ik bij iedere poging de volgende foutmelding krijg:
code:
1
Error during WebSocket handshake: Sec-WebSocket-Accept mismatch

aan de clientside.
ik heb opgezocht hoe die key gegenereert wordt en heb de volgende functie voor gemaakt:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    def HandShake(self, request):
        specificationGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
        websocketkey = ""
        protocol = ""
        for line in request.split("\n"):
            if "Sec-WebSocket-Key:" in line:
                websocketkey = line.split(" ")[1]
            elif "Sec-WebSocket-Protocol" in line:
                protocol = line.split(":")[1].strip()

        print("websocketkey: " + websocketkey + "\n")
        fullKey = hashlib.sha1(websocketkey.encode("utf-8") + specificationGUID.encode("utf-8")).digest()
        acceptKey = base64.b64encode(fullKey)
        print("acceptKey: " + str(acceptKey, "utf-8") + "\n")
        if protocol != "":
            handshake = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: " + str(acceptKey, "utf-8") + "\r\nSec-WebSocket-Protocol: " + protocol + "\r\n\r\n"
        else:
            handshake = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: " + str(acceptKey, "utf-8") + "\r\n\r\n"
        print(handshake)
        self.request.send(bytes(handshake, "utf-8"))

ik heb de key van wikipedia ingevuld en gekeken wat eruit kwam en dit klopte precies. Op google zijn er veel topics over te vinden maar dat gaat of over dat er hexdigest wordt gebruikt ipv digest of wordt de key niet volgens de juiste manier berekend, waarop er vervolgens een wiki link wordt gestuurd.
maar bij mij klopt de key dus volgens de officiele methode. heb ook netjes /r/n gebruikt en aan het einde een whiteline.
Toch gereject de client deze handshake. weet iemand wat ik fout doe/kan proberen te verbeteren? alvast bedankt!

EDIT:
de output wat de prints geven:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server started, waiting for connections...
request:
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localhost:600
Origin: http://localhost
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: yLffHPqMU4gIW2WnKq+4BQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36


websocketkey: yLffHPqMU4gIW2WnKq+4BQ==

acceptKey: A0eCd19URtkji0OPV162okWsCns=

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: A0eCd19URtkji0OPV162okWsCns=

[ Voor 14% gewijzigd door williewonka03 op 22-12-2013 13:02 ]


  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Hier wordt een volledig 'working example' gepost: http://stackoverflow.com/...websocket-accept-mismatch

Als dat voorbeeld wel werkt, dan kan vergelijken wat er daar gestuurd wordt en wat er in jouw code gestuurd wordt, en op basis daarvan je probleem terugvinden.

  • williewonka03
  • Registratie: Augustus 2010
  • Laatst online: 16-06-2024
ValHallASW schreef op zondag 22 december 2013 @ 12:03:
Hier wordt een volledig 'working example' gepost: http://stackoverflow.com/...websocket-accept-mismatch

Als dat voorbeeld wel werkt, dan kan vergelijken wat er daar gestuurd wordt en wat er in jouw code gestuurd wordt, en op basis daarvan je probleem terugvinden.
ja die had ik ook gevonden en ik stuur gewoon hetzelfde, dus snap niet waarom dat wel zou werken en dat van mij niet. dat is ook overigens in python 2
Ik zal trouwens even de print output in de op zetten

[ Voor 4% gewijzigd door williewonka03 op 22-12-2013 13:01 ]


  • WernerL
  • Registratie: December 2006
  • Nu online
Haal in ieder geval encode('utf-8') eens weg uit je code. Dit is voor zover ik weet helemaal niet nodig. Bij mij werkte het iig ook zonder.

Dit is de functie die ik een hele tijd terug heb geschreven voor een websocket server (ook python).

Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
    def getHandshake(self, headers):
        print "Sending Hybi handshake"
        
        wsid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
        response = base64.b64encode(hashlib.sha1(headers[2] + wsid).digest())
        
        shake = (
                "HTTP/1.1 101 Switching Protocols\r\n"
                "Upgrade: websocket\r\n"
                "Connection: Upgrade\r\n"
                "Sec-WebSocket-Accept: %s\r\n\r\n") % response

        return shake


In jouw output mist ik trouwens de 2 enters die meegestuurd moeten worden aan het einde van de response. Zou dat niet de reden kunnen zijn dat de webbrower gewoon NEE zegt? :-)

[ Voor 12% gewijzigd door WernerL op 22-12-2013 14:47 ]

Roses are red, violets are blue, unexpected '{' on line 32.


  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
williewonka03 schreef op zondag 22 december 2013 @ 13:01:
ja die had ik ook gevonden en ik stuur gewoon hetzelfde, dus snap niet waarom dat wel zou werken en dat van mij niet. dat is ook overigens in python 2
*denk* je dat het hetzelfde doet op basis van de code, of heb je *gecheckt* dat daadwerkelijk dezelfde data over 'the wire' gaat (met mitmproxy, wireshark of zelfs in Chrome's network panel?)
WernerL schreef op zondag 22 december 2013 @ 14:43:
Haal in ieder geval encode('utf-8') eens weg uit je code. Dit is voor zover ik weet helemaal niet nodig. Bij mij werkte het iig ook zonder.
Dit gaat over Python 3, niet over Python 2. Dat neemt overigens niet weg dat utf-8 gebruiken fout is -- je zou /of/ het geheel in bytes objects moeten samenvoegen (maar dat is gedoe), /of/ je zou een latin-1-translatie kunnen gebruiken. Met latin-1 kan je immers een round-trip doen van elke binary data, met utf-8 niet.

  • Cornholio
  • Registratie: Augustus 2009
  • Laatst online: 30-09 13:19
Ik ben hier ook een tijdje mee bezig geweest. Toen besloot ik de library Tornado te gebruiken, deze werkt heel goed met websockets:
https://pypi.python.org/pypi/tornado/3.1.1

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09 23:18

djc

Je neemt de \r uit de "Sec-WebSocket-Key: yLffHPqMU4gIW2WnKq+4BQ==\r\n"-regel mee in je key, dat klopt natuurlijk niet. Ik kan de foutieve return key op die manier reconstrueren:

Python:
1
2
3
4
5
6
7
8
>>> import hashlib
>>> import base64
>>> hashlib.sha1('yLffHPqMU4gIW2WnKq+4BQ==' + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest()
'aX\xca\xaaS\x11\xc6\\\xf33\xbd\x0bI\xc3}V\x80\xacn\x82'
>>> base64.b64encode(hashlib.sha1('yLffHPqMU4gIW2WnKq+4BQ==' + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest())
'YVjKqlMRxlzzM70LScN9VoCsboI='
>>> base64.b64encode(hashlib.sha1('yLffHPqMU4gIW2WnKq+4BQ==\r' + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest())
'A0eCd19URtkji0OPV162okWsCns='


In het Wikipedia-voorbeeld heb je wellicht een ingekorte request meegegeven waar die \r niet in staat?

Rustacean


  • williewonka03
  • Registratie: Augustus 2010
  • Laatst online: 16-06-2024
WernerL schreef op zondag 22 december 2013 @ 14:43:
Haal in ieder geval encode('utf-8') eens weg uit je code. Dit is voor zover ik weet helemaal niet nodig. Bij mij werkte het iig ook zonder.

Dit is de functie die ik een hele tijd terug heb geschreven voor een websocket server (ook python).

Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
    def getHandshake(self, headers):
        print "Sending Hybi handshake"
        
        wsid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
        response = base64.b64encode(hashlib.sha1(headers[2] + wsid).digest())
        
        shake = (
                "HTTP/1.1 101 Switching Protocols\r\n"
                "Upgrade: websocket\r\n"
                "Connection: Upgrade\r\n"
                "Sec-WebSocket-Accept: %s\r\n\r\n") % response

        return shake

In jouw output mist ik trouwens de 2 enters die meegestuurd moeten worden aan het einde van de response. Zou dat niet de reden kunnen zijn dat de webbrower gewoon NEE zegt? :-)
zonder utf encodingen slikt de hashlib het niet. en ja de laatste witregel staat er anders krijg je ook die error niet. dan blijft ie gewoon wachten totdat die regel is ontvangen.
djc schreef op zondag 22 december 2013 @ 21:52:
Je neemt de \r uit de "Sec-WebSocket-Key: yLffHPqMU4gIW2WnKq+4BQ==\r\n"-regel mee in je key, dat klopt natuurlijk niet. Ik kan de foutieve return key op die manier reconstrueren:

Python:
1
2
3
4
5
6
7
8
>>> import hashlib
>>> import base64
>>> hashlib.sha1('yLffHPqMU4gIW2WnKq+4BQ==' + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest()
'aX\xca\xaaS\x11\xc6\\\xf33\xbd\x0bI\xc3}V\x80\xacn\x82'
>>> base64.b64encode(hashlib.sha1('yLffHPqMU4gIW2WnKq+4BQ==' + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest())
'YVjKqlMRxlzzM70LScN9VoCsboI='
>>> base64.b64encode(hashlib.sha1('yLffHPqMU4gIW2WnKq+4BQ==\r' + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest())
'A0eCd19URtkji0OPV162okWsCns='


In het Wikipedia-voorbeeld heb je wellicht een ingekorte request meegegeven waar die \r niet in staat?
dankje dat was het probleem. ik moet splitsen op \r\n ipv alleen \n. op die manier bleef er een \r in de key staan. de print statement liet die niet zien. in shell wel
Pagina: 1