From 1e17127f49d2d16f4e988bbb6f57441388aa6c44 Mon Sep 17 00:00:00 2001 From: n Date: Wed, 9 Sep 2026 04:21:46 +0000 Subject: [PATCH] fix: treat whitespace-only body as empty ({}) not a 400 Gate finding on #7336: read_body() rejected whitespace-only bodies that worked on master (a body-optional DELETE/PATCH/PUT can send b' \n'), returning 400 Invalid JSON body. Normalize a fully-whitespace body to {} before json.loads, matching the pre-#7336 lenient behavior for that shape. Adds a parametrized regression test. Co-authored-by: zicochaos --- api/helpers.py | 5 +++++ tests/test_read_body_json_validation.py | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/api/helpers.py b/api/helpers.py index 679bf713..9a8e7f36 100644 --- a/api/helpers.py +++ b/api/helpers.py @@ -1268,6 +1268,11 @@ def read_body(handler) -> dict: pass raise ValueError(f'Request body too large ({length} bytes, max {MAX_BODY_BYTES})') raw = handler.rfile.read(length) if length else b'{}' + # A body-optional endpoint (e.g. DELETE /api/mcp/servers/{name}) may send a + # whitespace-only body; treat it like an empty body ({}) rather than a 400, + # matching the pre-#7336 lenient behavior for that shape (see gate finding). + if not raw.strip(): + return {} try: parsed = _json.loads(raw) except Exception: diff --git a/tests/test_read_body_json_validation.py b/tests/test_read_body_json_validation.py index a88a0f33..45451519 100644 --- a/tests/test_read_body_json_validation.py +++ b/tests/test_read_body_json_validation.py @@ -42,6 +42,15 @@ def test_read_body_empty_body_defaults_to_empty_dict(): assert read_body(handler) == {} +@pytest.mark.parametrize("raw", [b" ", b"\n", b" \n\t ", b"\r\n"]) +def test_read_body_whitespace_only_body_defaults_to_empty_dict(raw): + """A body-optional endpoint (e.g. DELETE /api/mcp/servers/{name}) may send a + whitespace-only body; it must be treated like an empty body ({}), not a 400.""" + from api.helpers import read_body + + assert read_body(_handler(raw)) == {} + + @pytest.mark.parametrize("raw", [b"{bad json"]) def test_read_body_raises_on_malformed_json(raw): from api.helpers import read_body