From 0d73aafdf9ed02e5f13a0093be4595ff851b267b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sat, 3 Jul 2021 17:32:03 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Assume=20JSON=20when?= =?UTF-8?q?=20no=20Content-Type=20header=20is=20provided?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit as that doesn't risk CSRF problems that would always have headers, and because many clients already depend on that default behavior --- fastapi/routing.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fastapi/routing.py b/fastapi/routing.py index 9b51f03cac562..3cf35f5095659 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -184,7 +184,9 @@ async def app(request: Request) -> Response: if body_bytes: json_body: Any = Undefined content_type_value = request.headers.get("content-type") - if content_type_value: + if not content_type_value: + json_body = await request.json() + else: message = email.message.Message() message["content-type"] = content_type_value if message.get_content_maintype() == "application": From 540f19ffefde9525f82af748f282b61a707f0f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sat, 3 Jul 2021 17:33:32 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=85=20Add=20tests=20to=20check=20that?= =?UTF-8?q?=20by=20default=20request=20bodies=20are=20assumed=20as=20JSON?= =?UTF-8?q?=20when=20no=20content-type=20header=20is=20provided?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_tutorial/test_body/test_tutorial001.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_tutorial/test_body/test_tutorial001.py b/tests/test_tutorial/test_body/test_tutorial001.py index c90240ae4c349..7bf62c907db79 100644 --- a/tests/test_tutorial/test_body/test_tutorial001.py +++ b/tests/test_tutorial/test_body/test_tutorial001.py @@ -229,6 +229,20 @@ def test_geo_json(): assert response.status_code == 200, response.text +def test_no_content_type_is_json(): + response = client.post( + "/items/", + data='{"name": "Foo", "price": 50.5}', + ) + assert response.status_code == 200, response.text + assert response.json() == { + "name": "Foo", + "description": None, + "price": 50.5, + "tax": None, + } + + def test_wrong_headers(): data = '{"name": "Foo", "price": 50.5}' invalid_dict = {