django / asgiref

ASGI specification and utilities
https://asgi.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
1.46k stars 207 forks source link

Can asig http extensions be used in WebSocket Denial Response? #433

Closed synodriver closed 7 months ago

synodriver commented 7 months ago

From the spec we know that WebSocket Denial Response is just regular http response, so I wonder if it's possible for an asgi app to use regular asgi http extensions in WebSocket Denial Response such as http.response.trailers and http.response.zerocopysend? Just like the following app.

async def wstrailer(scope, receive, send):
    assert scope["type"] == "websocket"
    if scope["type"] == "websocket":
        await send(
            {
                "type": "websocket.http.response.start",
                "status": 200,
                "headers": [
                    (b"Cache-Control", b"no-cache"),
                    (b"Trailer", b"grpc-status"),
                ],
                "reason": "OK",
                "trailers": True
            }
        )
        await send(
            {
                "type": "websocket.http.response.body",
                "body": b"1235"
            }
        )
        await send({"type": "http.response.trailers", "headers": [(b"grpc-status", b"0")]})

And should we change their name like websocket.http.response.trailers and websocket.http.response.zerocopysend?

andrewgodwin commented 7 months ago

No, it's not possible given the current spec - the only way to HTTP reject a socket in the websocket part of the spec is to send websocket.close, which will translate to a HTTP 403 error if sent before the socket is accepted.

If you want this precise a control over your websocket server you may want to investigate writing or extending your own; I've never seen anyone send trailers on websocket rejections, and I suspect we wouldn't integrate it into any ASGI spec until it became at least somewhat common.

synodriver commented 7 months ago

Ok I see it. Thanks for you answer.