Skip to content

Commit

Permalink
replace version identifier and require user action
Browse files Browse the repository at this point in the history
  • Loading branch information
Kriechi committed Aug 19, 2017
1 parent 5ea2da6 commit aa527ab
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
29 changes: 29 additions & 0 deletions test/test_upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,35 @@ def test_wrong_method(self):
event = next(ws.events())
assert isinstance(event, ConnectionFailed)

@pytest.mark.parametrize('versions', [
b'',
b'12',
b'14',
b'10,11,12',
b'10, 11, 12',
b'10-12',
])
def test_unsupported_version(self, versions):
test_host = 'frob.nitz'
test_path = '/fnord'

ws = WSConnection(SERVER)

nonce = bytes(random.getrandbits(8) for x in range(0, 16))
nonce = base64.b64encode(nonce)

request = b'GET ' + test_path.encode('ascii') + b' HTTP/1.1\r\n'
request += b'Host: ' + test_host.encode('ascii') + b'\r\n'
request += b'Connection: Upgrade\r\n'
request += b'Upgrade: WebSocket\r\n'
request += b'Sec-WebSocket-Version: ' + versions + b'\r\n'
request += b'Sec-WebSocket-Key: ' + nonce + b'\r\n'
request += b'\r\n'

ws.receive_bytes(request)
event = next(ws.events())
assert isinstance(event, ConnectionFailed)

def test_bad_connection(self):
test_host = 'frob.nitz'
test_path = '/fnord'
Expand Down
12 changes: 7 additions & 5 deletions wsproto/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
# RFC6455, Section 1.3 - Opening Handshake
ACCEPT_GUID = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

# RFC6455, Section 4.2.1/6 - Reading the Client's Opening Handshake
WEBSOCKET_VERSION = '13'

class ConnectionState(Enum):
"""
Expand Down Expand Up @@ -109,8 +111,6 @@ def __init__(self, conn_type, host=None, resource=None, extensions=None,
self.subprotocols = subprotocols or []
self.extensions = extensions or []

self.version = b'13'

self._state = ConnectionState.CONNECTING
self._close_reason = None

Expand Down Expand Up @@ -141,7 +141,7 @@ def initiate_connection(self):
b"Upgrade": b'WebSocket',
b"Connection": b'Upgrade',
b"Sec-WebSocket-Key": self._nonce,
b"Sec-WebSocket-Version": self.version,
b"Sec-WebSocket-Version": WEBSOCKET_VERSION,
}

if self.subprotocols:
Expand Down Expand Up @@ -378,8 +378,10 @@ def _process_connection_request(self, event):
if b'sec-websocket-version' not in headers:
return ConnectionFailed(CloseReason.PROTOCOL_ERROR,
"Missing Sec-WebSocket-Version header")
# XX FIXME: need to check Sec-Websocket-Version, and respond with a
# 400 if it's not what we expect
versions = _split_comma_header(headers[b'sec-websocket-version'])
if WEBSOCKET_VERSION not in versions:
return ConnectionFailed(CloseReason.PROTOCOL_ERROR,
"Unsupported Sec-WebSocket-Version")

if b'sec-websocket-protocol' in headers:
proposed_subprotocols = _split_comma_header(
Expand Down
5 changes: 5 additions & 0 deletions wsproto/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ def __repr__(self):


class ConnectionFailed(ConnectionClosed):
"""
The ConnectionFailed event is fired when the upgrade handshake failed.
Users must handle this error by appropriate responses to deal with the
connection, e.g., sending a 400 HTTP response for a failed client handshake.
"""
pass


Expand Down

0 comments on commit aa527ab

Please sign in to comment.