Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebSocket server responds incorrectly if connection is closed without a status code #263

Open
robertknight opened this issue Jun 1, 2020 · 0 comments

Comments

@robertknight
Copy link

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 961c07c:

  1. 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
  1. Run python example/echo_gevent_server.py
  2. Open http://127.0.0.1:9000 in Chrome and click the "Disconnect" button
  3. The following error is displayed in the console:

Screenshot 2020-06-01 11 14 20

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 hypothesis/client#1941 for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant