python-websockets / websockets

Library for building WebSocket servers and clients in Python

Home Page:https://websockets.readthedocs.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Incorrect use of process_request silently aborts connections

Rosuav opened this issue · comments

async def process_request(path, headers):
    return (200, [], b"Hello, world")

async def main():
    async with websockets.serve(connection, "localhost", 8000, process_request=process_request):
        await asyncio.Future()

The documentation for process_request correctly says that the first value should be an HTTPStatus; however, this example passes a plain int instead.

Expected result: An exception is thrown or displayed on the console. (Or ideally, this particular case should work correctly, since IntEnum and integer are mostly interchangeable.)

Actual result: The exception is swallowed by # Last-ditch attempt to avoid leaking connections on errors and the connection is summarily closed with no message to client or console.

Requesting that the last-ditch handler report errors to the console, possibly with a message indicating how this could be suppressed.

I completed your example as follows:

#!/usr/bin/env python

import asyncio
import websockets

async def connection(ws):
    await asyncio.sleep(1)
    await ws.send("it works")

async def process_request(path, headers):
    return (200, [], b"Hello, world")

async def main():
    async with websockets.serve(connection, "localhost", 8000, process_request=process_request):
        await asyncio.Future()

if __name__ == "__main__":
    asyncio.run(main())

It doesn't crash:

$ curl -v http://localhost:8000/
*   Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sat, 21 Oct 2023 13:30:35 GMT
< Server: Python/3.11 websockets/12.0.dev36+ged6cb1b
< Content-Length: 12
< Content-Type: text/plain
< Connection: close
<
* Closing connection 0
Hello, world%

It was fixed in #1309..

Ahh cool, that solves this particular issue. It may still be possible to cause other types of errors that will silently abort connections though. Is there any other way to write the handler that will result in the same last-ditch exception handler being triggered?