Remove support for old Hixie protocols.
Hybi protocols 7 and 8 are still supported, in addition to protocol 13 - RFC 6455.
This commit is contained in:
parent
805026360e
commit
b2fe57c950
|
@ -6,9 +6,9 @@ Copyright 2011 Joel Martin
|
||||||
Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
|
Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
|
||||||
|
|
||||||
Supports following protocol versions:
|
Supports following protocol versions:
|
||||||
- http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75
|
- http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-07
|
||||||
- http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
|
|
||||||
- http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10
|
- http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10
|
||||||
|
- http://tools.ietf.org/html/rfc6455
|
||||||
|
|
||||||
You can make a cert/key with openssl using:
|
You can make a cert/key with openssl using:
|
||||||
openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
|
openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
|
||||||
|
@ -37,8 +37,8 @@ try: from http.server import SimpleHTTPRequestHandler
|
||||||
except: from SimpleHTTPServer import SimpleHTTPRequestHandler
|
except: from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||||
|
|
||||||
# python 2.6 differences
|
# python 2.6 differences
|
||||||
try: from hashlib import md5, sha1
|
try: from hashlib import sha1
|
||||||
except: from md5 import md5; from sha import sha as sha1
|
except: from sha import sha as sha1
|
||||||
|
|
||||||
# python 2.5 differences
|
# python 2.5 differences
|
||||||
try:
|
try:
|
||||||
|
@ -72,14 +72,6 @@ class WebSocketServer(object):
|
||||||
|
|
||||||
buffer_size = 65536
|
buffer_size = 65536
|
||||||
|
|
||||||
|
|
||||||
server_handshake_hixie = """HTTP/1.1 101 Web Socket Protocol Handshake\r
|
|
||||||
Upgrade: WebSocket\r
|
|
||||||
Connection: Upgrade\r
|
|
||||||
%sWebSocket-Origin: %s\r
|
|
||||||
%sWebSocket-Location: %s://%s%s\r
|
|
||||||
"""
|
|
||||||
|
|
||||||
server_handshake_hybi = """HTTP/1.1 101 Switching Protocols\r
|
server_handshake_hybi = """HTTP/1.1 101 Switching Protocols\r
|
||||||
Upgrade: websocket\r
|
Upgrade: websocket\r
|
||||||
Connection: Upgrade\r
|
Connection: Upgrade\r
|
||||||
|
@ -381,33 +373,6 @@ Sec-WebSocket-Accept: %s\r
|
||||||
|
|
||||||
return f
|
return f
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def encode_hixie(buf):
|
|
||||||
return s2b("\x00" + b2s(b64encode(buf)) + "\xff"), 1, 1
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def decode_hixie(buf):
|
|
||||||
end = buf.find(s2b('\xff'))
|
|
||||||
return {'payload': b64decode(buf[1:end]),
|
|
||||||
'hlen': 1,
|
|
||||||
'masked': False,
|
|
||||||
'length': end - 1,
|
|
||||||
'left': len(buf) - (end + 1)}
|
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def gen_md5(keys):
|
|
||||||
""" Generate hash value for WebSockets hixie-76. """
|
|
||||||
key1 = keys['Sec-WebSocket-Key1']
|
|
||||||
key2 = keys['Sec-WebSocket-Key2']
|
|
||||||
key3 = keys['key3']
|
|
||||||
spaces1 = key1.count(" ")
|
|
||||||
spaces2 = key2.count(" ")
|
|
||||||
num1 = int("".join([c for c in key1 if c.isdigit()])) / spaces1
|
|
||||||
num2 = int("".join([c for c in key2 if c.isdigit()])) / spaces2
|
|
||||||
|
|
||||||
return b2s(md5(pack('>II8s',
|
|
||||||
int(num1), int(num2), key3)).digest())
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# WebSocketServer logging/output functions
|
# WebSocketServer logging/output functions
|
||||||
|
@ -444,16 +409,10 @@ Sec-WebSocket-Accept: %s\r
|
||||||
|
|
||||||
if bufs:
|
if bufs:
|
||||||
for buf in bufs:
|
for buf in bufs:
|
||||||
if self.version.startswith("hybi"):
|
if self.base64:
|
||||||
if self.base64:
|
encbuf, lenhead, lentail = self.encode_hybi(buf, opcode=1, base64=True)
|
||||||
encbuf, lenhead, lentail = self.encode_hybi(
|
|
||||||
buf, opcode=1, base64=True)
|
|
||||||
else:
|
|
||||||
encbuf, lenhead, lentail = self.encode_hybi(
|
|
||||||
buf, opcode=2, base64=False)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
encbuf, lenhead, lentail = self.encode_hixie(buf)
|
encbuf, lenhead, lentail = self.encode_hybi(buf, opcode=2, base64=False)
|
||||||
|
|
||||||
if self.rec:
|
if self.rec:
|
||||||
self.rec.write("%s,\n" %
|
self.rec.write("%s,\n" %
|
||||||
|
@ -498,41 +457,21 @@ Sec-WebSocket-Accept: %s\r
|
||||||
self.recv_part = None
|
self.recv_part = None
|
||||||
|
|
||||||
while buf:
|
while buf:
|
||||||
if self.version.startswith("hybi"):
|
frame = self.decode_hybi(buf, base64=self.base64)
|
||||||
|
#print("Received buf: %s, frame: %s" % (repr(buf), frame))
|
||||||
frame = self.decode_hybi(buf, base64=self.base64)
|
|
||||||
#print("Received buf: %s, frame: %s" % (repr(buf), frame))
|
|
||||||
|
|
||||||
if frame['payload'] == None:
|
|
||||||
# Incomplete/partial frame
|
|
||||||
self.traffic("}.")
|
|
||||||
if frame['left'] > 0:
|
|
||||||
self.recv_part = buf[-frame['left']:]
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
if frame['opcode'] == 0x8: # connection close
|
|
||||||
closed = {'code': frame['close_code'],
|
|
||||||
'reason': frame['close_reason']}
|
|
||||||
break
|
|
||||||
|
|
||||||
|
if frame['payload'] == None:
|
||||||
|
# Incomplete/partial frame
|
||||||
|
self.traffic("}.")
|
||||||
|
if frame['left'] > 0:
|
||||||
|
self.recv_part = buf[-frame['left']:]
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
if buf[0:2] == s2b('\xff\x00'):
|
if frame['opcode'] == 0x8: # connection close
|
||||||
closed = {'code': 1000,
|
closed = {'code': frame['close_code'],
|
||||||
'reason': "Client sent orderly close frame"}
|
'reason': frame['close_reason']}
|
||||||
break
|
break
|
||||||
|
|
||||||
elif buf[0:2] == s2b('\x00\xff'):
|
|
||||||
buf = buf[2:]
|
|
||||||
continue # No-op
|
|
||||||
|
|
||||||
elif buf.count(s2b('\xff')) == 0:
|
|
||||||
# Partial frame
|
|
||||||
self.traffic("}.")
|
|
||||||
self.recv_part = buf
|
|
||||||
break
|
|
||||||
|
|
||||||
frame = self.decode_hixie(buf)
|
|
||||||
|
|
||||||
self.traffic("}")
|
self.traffic("}")
|
||||||
|
|
||||||
if self.rec:
|
if self.rec:
|
||||||
|
@ -560,17 +499,9 @@ Sec-WebSocket-Accept: %s\r
|
||||||
def send_close(self, code=1000, reason=''):
|
def send_close(self, code=1000, reason=''):
|
||||||
""" Send a WebSocket orderly close frame. """
|
""" Send a WebSocket orderly close frame. """
|
||||||
|
|
||||||
if self.version.startswith("hybi"):
|
msg = pack(">H%ds" % len(reason), code, reason)
|
||||||
msg = pack(">H%ds" % len(reason), code, reason)
|
buf, h, t = self.encode_hybi(msg, opcode=0x08, base64=False)
|
||||||
|
self.client.send(buf)
|
||||||
buf, h, t = self.encode_hybi(msg, opcode=0x08, base64=False)
|
|
||||||
self.client.send(buf)
|
|
||||||
|
|
||||||
elif self.version == "hixie-76":
|
|
||||||
buf = s2b('\xff\x00')
|
|
||||||
self.client.send(buf)
|
|
||||||
|
|
||||||
# No orderly close for 75
|
|
||||||
|
|
||||||
def do_websocket_handshake(self, headers, path):
|
def do_websocket_handshake(self, headers, path):
|
||||||
h = self.headers = headers
|
h = self.headers = headers
|
||||||
|
@ -612,28 +543,7 @@ Sec-WebSocket-Accept: %s\r
|
||||||
response += "\r\n"
|
response += "\r\n"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Hixie version of the protocol (75 or 76)
|
raise self.EClose("Missing Sec-WebSocket-Version header. Hixie protocols not supported.")
|
||||||
|
|
||||||
if h.get('key3'):
|
|
||||||
trailer = self.gen_md5(h)
|
|
||||||
pre = "Sec-"
|
|
||||||
self.version = "hixie-76"
|
|
||||||
else:
|
|
||||||
trailer = ""
|
|
||||||
pre = ""
|
|
||||||
self.version = "hixie-75"
|
|
||||||
|
|
||||||
# We only support base64 in Hixie era
|
|
||||||
self.base64 = True
|
|
||||||
|
|
||||||
response = self.server_handshake_hixie % (pre,
|
|
||||||
h['Origin'], pre, self.scheme, h['Host'], path)
|
|
||||||
|
|
||||||
if 'base64' in protocols:
|
|
||||||
response += "%sWebSocket-Protocol: base64\r\n" % pre
|
|
||||||
else:
|
|
||||||
self.msg("Warning: client does not report 'base64' protocol support")
|
|
||||||
response += "\r\n" + trailer
|
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@ -957,11 +867,6 @@ class WSRequestHandler(SimpleHTTPRequestHandler):
|
||||||
if (self.headers.get('upgrade') and
|
if (self.headers.get('upgrade') and
|
||||||
self.headers.get('upgrade').lower() == 'websocket'):
|
self.headers.get('upgrade').lower() == 'websocket'):
|
||||||
|
|
||||||
if (self.headers.get('sec-websocket-key1') or
|
|
||||||
self.headers.get('websocket-key1')):
|
|
||||||
# For Hixie-76 read out the key hash
|
|
||||||
self.headers.__setitem__('key3', self.rfile.read(8))
|
|
||||||
|
|
||||||
# Just indicate that an WebSocket upgrade is needed
|
# Just indicate that an WebSocket upgrade is needed
|
||||||
self.last_code = 101
|
self.last_code = 101
|
||||||
self.last_message = "101 Switching Protocols"
|
self.last_message = "101 Switching Protocols"
|
||||||
|
|
Loading…
Reference in New Issue