encode / starlette

The little ASGI framework that shines. 🌟

Home Page:https://www.starlette.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TrustedHostMiddleware raises RuntimeError on sending response to websocket

Kludex opened this issue · comments

Discussed in #2225

Originally posted by Budek July 24, 2023

from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.middleware.trustedhost import TrustedHostMiddleware
from starlette.routing import WebSocketRoute


async def app(websocket):
    await websocket.accept()
    await websocket.send_text("Hello, world!")
    await websocket.close()


routes = [
    WebSocketRoute("/ws", app),
]

middleware = [
    Middleware(
        TrustedHostMiddleware,
        allowed_hosts=["example.com", "*.example.com"],
    ),
]

app = Starlette(routes=routes, middleware=middleware)

Using the provided example code and making a request websocket request without header Host or with invalid header i get the following exception.

ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/home/bdk/.virtualenvs/example/lib/python3.11/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 254, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/bdk/.virtualenvs/example/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/bdk/.virtualenvs/example/lib/python3.11/site-packages/starlette/applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/bdk/.virtualenvs/example/lib/python3.11/site-packages/starlette/middleware/errors.py", line 149, in __call__
    await self.app(scope, receive, send)
  File "/home/bdk/.virtualenvs/example/lib/python3.11/site-packages/starlette/middleware/trustedhost.py", line 60, in __call__
    await response(scope, receive, send)
  File "/home/bdk/.virtualenvs/example/lib/python3.11/site-packages/starlette/responses.py", line 164, in __call__
    await send(
  File "/home/bdk/.virtualenvs/example/lib/python3.11/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 317, in asgi_send
    raise RuntimeError(msg % message_type)
RuntimeError: Expected ASGI message 'websocket.accept' or 'websocket.close', but got 'http.response.start'.

Important

  • We're using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar

Given that we implemented the WebSocket Denial Response, the above is not reproducible anymore.