From f21c6f2ca512a026ce7f0f6c6311f62d6a638866 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 21:54:12 +0100 Subject: [PATCH] [PR #8335/5a6949da backport][3.9] Add Content-Disposition automatically (#8336) **This is a backport of PR #8335 as merged into master (5a6949da642d1db6cf414fd0d1f70e54c7b7be14).** Co-authored-by: Sam Bull --- CHANGES/8335.bugfix.rst | 1 + aiohttp/multipart.py | 4 ++++ tests/test_multipart.py | 22 +++++++++++++++++----- 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 CHANGES/8335.bugfix.rst diff --git a/CHANGES/8335.bugfix.rst b/CHANGES/8335.bugfix.rst new file mode 100644 index 00000000000..cd93b864a50 --- /dev/null +++ b/CHANGES/8335.bugfix.rst @@ -0,0 +1 @@ +Added default Content-Disposition in multipart/form-data responses -- by :user:`Dreamsorcerer`. diff --git a/aiohttp/multipart.py b/aiohttp/multipart.py index fcdf16183cd..71fc2654a1c 100644 --- a/aiohttp/multipart.py +++ b/aiohttp/multipart.py @@ -852,6 +852,10 @@ def append_payload(self, payload: Payload) -> Payload: not {CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_TRANSFER_ENCODING} & payload.headers.keys() ) + # Set default Content-Disposition in case user doesn't create one + if CONTENT_DISPOSITION not in payload.headers: + name = f"section-{len(self._parts)}" + payload.set_content_disposition("form-data", name=name) else: # compression encoding = payload.headers.get(CONTENT_ENCODING, "").lower() diff --git a/tests/test_multipart.py b/tests/test_multipart.py index 37ac54797fb..436b70957fa 100644 --- a/tests/test_multipart.py +++ b/tests/test_multipart.py @@ -1282,12 +1282,24 @@ def test_append_multipart(self, writer) -> None: part = writer._parts[0][0] assert part.headers[CONTENT_TYPE] == "test/passed" - async def test_set_content_disposition_after_append(self): + def test_set_content_disposition_after_append(self): writer = aiohttp.MultipartWriter("form-data") - payload = writer.append("some-data") - payload.set_content_disposition("form-data", name="method") - assert CONTENT_DISPOSITION in payload.headers - assert "name=" in payload.headers[CONTENT_DISPOSITION] + part = writer.append("some-data") + part.set_content_disposition("form-data", name="method") + assert 'name="method"' in part.headers[CONTENT_DISPOSITION] + + def test_automatic_content_disposition(self): + writer = aiohttp.MultipartWriter("form-data") + writer.append_json(()) + part = payload.StringPayload("foo") + part.set_content_disposition("form-data", name="second") + writer.append_payload(part) + writer.append("foo") + + disps = tuple(p[0].headers[CONTENT_DISPOSITION] for p in writer._parts) + assert 'name="section-0"' in disps[0] + assert 'name="second"' in disps[1] + assert 'name="section-2"' in disps[2] def test_with(self) -> None: with aiohttp.MultipartWriter(boundary=":") as writer: