Skip to content

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

@robertknight

Description

@robertknight

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions