From a3759843100575e72905ef5875f1782a5a2fe05f Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 24 Mar 2026 15:16:29 -0400 Subject: [PATCH] Fix WSGI mount returning 400 at mount root (#600) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - When a WSGI app (e.g. Flask) is mounted at `/prefix` and a request hits exactly `/prefix`, the path prefix was stripped to `""` instead of `"/"`, causing frameworks like Flask to return 400. - One-character fix: default the stripped path to `"/"` when empty. ## Test plan - [x] `tests/test_responder.py::test_mount_wsgi_app` now passes 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) --- responder/routes.py | 2 +- tests/test_responder.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/responder/routes.py b/responder/routes.py index 954e858..13db9f6 100644 --- a/responder/routes.py +++ b/responder/routes.py @@ -457,7 +457,7 @@ class Router: # Call into a submounted app, if one exists. for path_prefix, app in self.apps.items(): if path.startswith(path_prefix): - scope["path"] = path[len(path_prefix) :] + scope["path"] = path[len(path_prefix) :] or "/" scope["root_path"] = root_path + path_prefix try: await app(scope, receive, send) diff --git a/tests/test_responder.py b/tests/test_responder.py index e4ef3f8..b2f9375 100644 --- a/tests/test_responder.py +++ b/tests/test_responder.py @@ -546,14 +546,17 @@ def test_documentation(needs_openapi): assert "html" in r.text -def test_mount_wsgi_app(api, flask): +def test_mount_wsgi_app(flask): + # Use localhost so Werkzeug's trusted-host check accepts the request. + api = responder.API(allowed_hosts=["localhost"]) + @api.route("/") def hello(req, resp): resp.text = "hello" api.mount("/flask", flask) - r = api.requests.get("http://;/flask") + r = api.requests.get("http://localhost/flask") assert r.status_code < 300