WebSocket server responds incorrectly if connection is closed without a status code
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 45/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- python
- Domain
- networking
Research direction
Start by reproducing the issue with examples/echo_gevent_server.py using the documented browser steps and compare behavior at commit 961c07ce16ce4eedc34ca1fdacd29442870feccc. Trace the server's handling of a client close without a status code. Done means the server no longer sends status code 1005 in its close frame while still handling the connection correctly.
Written by the indexing model from the issue text.
Description
If a client closes a connection without providing a status code, the WebSocket server will respond to the client with a close frame that has an invalid status code of 1005. This will cause some browsers, including Chrome and Safari, to display an error in the console.
Steps to reproduce:
I tested using Python 3.6.9 against commit 961c07ce16ce4eedc34ca1fdacd29442870feccc:
- Apply the following diff to
examples/echo_gevent_server.py:
diff --git a/example/echo_gevent_server.py b/example/echo_gevent_server.py
index 100a536..3ed19f9 100644
--- a/example/echo_gevent_server.py
+++ b/example/echo_gevent_server.py
@@ -78,7 +78,7 @@ class EchoWebSocketApplication(object):
start_response(status, headers)
- return """<html>
+ response = """<html>
<head>
<script type='application/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'></script>
<script type='application/javascript'>
@@ -120,6 +120,9 @@ class EchoWebSocketApplication(object):
$('#message').val("");
return false;
});
+ $('#disconnect').click(function () {
+ ws.close();
+ });
});
</script>
</head>
@@ -130,11 +133,13 @@ class EchoWebSocketApplication(object):
<label for='message'>%(username)s: </label><input type='text' id='message' />
<input id='send' type='submit' value='Send' />
</form>
+ <button id='disconnect'>Disconnect</button>
</body>
</html>
""" % {'username': "User%d" % random.randint(0, 100),
'host': self.host,
'port': self.port}
+ yield response.encode()
if __name__ == '__main__':
from ws4py import configure_logger
- Run
python example/echo_gevent_server.py - Open http://127.0.0.1:9000 in Chrome and click the "Disconnect" button
- The following error is displayed in the console:
Notes:
It is correct for the server to internally synthesize the status code 1005 when it receives a close frame for the client with no status code, but this particular status code should never be sent back to the client. From the WebSocket RFC:
1005 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting a status code to indicate that no status code was actually present.
In our application we worked around the issue on the client side by always setting a status code when closing the connection. See https://github.com/hypothesis/client/pull/1941 for details.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 285
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Lawouach/WebSocket-for-Python
-
Difficulty 3/5 1-2 days Newbie friendliness 45/100
Lawouach/WebSocket-for-Python#300 ·
-
question
Lawouach/WebSocket-for-Python#297 · 2 comments · 1 assignee ·
-
Difficulty 4/5 3-5 days Newbie friendliness 20/100
Lawouach/WebSocket-for-Python#296 ·
-
Lawouach/WebSocket-for-Python#280 · 1 comment · 1 assignee ·
-
Setup new CI Open
Lawouach/WebSocket-for-Python#275 · 1 assignee ·
All issues in Lawouach/WebSocket-for-Python
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100