Skip to content

Conversation

@martin-joshy
Copy link

…l (#3048)

Hi, this is my first time contribution to open source ever, welcome to all kind feedbacks

Summary

StreamingResponse and FileResponse sent raw http.response.* messages during send_denial_response, but WebSocket context requires websocket.http.response.* prefix.

This caused:

RuntimeError: Expected ASGI message "websocket.accept","websocket.close" or "websocket.http.response.start",but got 'http.response.start'

# Checklist

- [x] I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!) → Discussion already exists: #3048
- [x] I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic changeAdded
- [x] I've updated the documentation accordingly. → No doc changes neededbehavior is now correct as intended

@Kludex
Copy link
Owner

Kludex commented Oct 30, 2025

I think what we want is a send wrapper that will wrap the current send, and check if it's a websocket type.

async def _send_wrap(send: Send, is_websocket_denial: bool):
    
    async def wrapped(message: Message):
        if is_websocket_denial:
            message["type"] = "websocket." + message["type"]
        await send(message)
        
    return wrapped

The idea is to avoid the additional parameter everywhere.

@martin-joshy
Copy link
Author

martin-joshy commented Oct 30, 2025

Hi, thanks for the snippet it made it lot clearer. Below is the code which I tried to run test with, but I am not get 100 % coverage. Not really sure what I should be doing.

    async def send_denial_response(self, response: Response) -> None:
        if "websocket.http.response" in self.scope.get("extensions", {}):
            wrapped_send = self._send_wrap(self.send)
            await response(self.scope, self.receive, wrapped_send)
        else:
            raise RuntimeError("The server doesn't support the Websocket Denial Response extension.")

    @staticmethod
    def _send_wrap(send: Send) -> Send:
        async def wrapped(message: Message) -> None:
            message_type = message["type"]
            if message_type.startswith("http."):
                message["type"] = "websocket." + message_type

            await send(message)

        return wrapped

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

Successfully merging this pull request may close these issues.

2 participants