From 6c44fb8ab8268c93e617d333f188651c7e917e40 Mon Sep 17 00:00:00 2001 From: Gabe Van Engel Date: Mon, 10 Nov 2025 19:19:35 -0800 Subject: [PATCH 1/2] Handle Content-Type being explicitly unset on a multipart file upload This allows for properly setting the multipart boundary even if the Content-Type has been set on a Session. --- src/requests/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/requests/models.py b/src/requests/models.py index c4b25fa079..8e190db319 100644 --- a/src/requests/models.py +++ b/src/requests/models.py @@ -563,8 +563,8 @@ def prepare_body(self, data, files, json=None): self.prepare_content_length(body) - # Add content-type if it wasn't explicitly provided. - if content_type and ("content-type" not in self.headers): + # Add content-type if it wasn't explicitly provided, or it was explicitly unset + if content_type and self.headers.get("content-type") is None: self.headers["Content-Type"] = content_type self.body = body From 104446deaa1ac561cf17e8d7082ed4e6e76cb65b Mon Sep 17 00:00:00 2001 From: Gabe Van Engel Date: Tue, 11 Nov 2025 00:51:12 -0800 Subject: [PATCH 2/2] Add test to verify multipart session content type override --- tests/test_requests.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_requests.py b/tests/test_requests.py index 75d2deff2e..e2e72b91ab 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -1852,6 +1852,18 @@ def test_can_send_objects_with_files(self, httpbin, files): p = r.prepare() assert "multipart/form-data" in p.headers["Content-Type"] + def test_can_override_session_content_type_with_multipart_request(self, httpbin): + s = requests.Session() + s.headers["Content-Type"] = "application/json" + data = {"a": "this is a string"} + files = {"b": "foo"} + headers = {"Content-Type": None} + r = requests.Request( + "POST", httpbin("post"), headers=headers, data=data, files=files + ) + p = s.prepare_request(r) + assert "multipart/form-data" in p.headers["Content-Type"] + def test_can_send_file_object_with_non_string_filename(self, httpbin): f = io.BytesIO() f.name = 2