Skip to content

Websocket connections are not closed properly when we use them with WSGI middleware. #543

@Hardtack

Description

@Hardtack

I'm getting following error whenever websocket connections are closed.

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 580, in handle_one_response
    write(b'')
  File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 472, in write
    raise AssertionError("write() before start_response()")
AssertionError: write() before start_response()

More precisely, I'm using Flask-SocketIO with eventlet, with Flask integration of sentry-sdk.

As I see it, the problem occurred by following reason.

In eventlet.websocket, you made a special object called ALREADY_HANDLED which makes special functionalities for websocket handlers

# use this undocumented feature of eventlet.wsgi to ensure that it
# doesn't barf on the fact that we didn't call start_response
return wsgi.ALREADY_HANDLED

And, in eventlet.wsgi

The websocket-specific functionalities are handled by type of the return value of WSGI app.

eventlet/eventlet/wsgi.py

Lines 547 to 550 in 05d613d

result = self.application(self.environ, start_response)
if (isinstance(result, _AlreadyHandled)
or isinstance(getattr(result, '_obj', None), _AlreadyHandled)):
self.close_connection = 1

However, In sentry-sdk, the plugin wraps the WSGI responses (which are iterable objects) with there wrapper called _ScopedResponse.

This is fine, since PEP 3333 specifies the return value of WSGI app just have to be an iterable object.

But it breaks the type check on eventlet.wsgi. So eventlet doesn't finish at the if statement, and emits the above error message.

I think, you may have to use another way to handle websocekt specific features.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions