fix: allow multipart/form-data boundary to end with a newline (#5660)

The RFC 7578 spec for multipart/form-data requests does not require the
body of a request to end with a CRLF, only that each section begins with
a CRLF. While many clients implement multipart requests with the
trailing CRLF, the implementation for fetch in Node.js version 22 and
below does not.

This caused my a good number of hours debugging!

It does turn out that in September 2024 the Node.js fetch implementation
added the CRLF (https://github.com/nodejs/undici/pull/3625), though this
hasn't made it to a Node.js release yet.

This change allows the boundary to end with a newline or
not, as long as the boundary is followed by the end of the request body.
This commit is contained in:
Phil Nash 2025-01-21 12:56:11 +11:00 committed by GitHub
commit c7f6554ea0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -193,9 +193,12 @@ def create_app():
body = await request.body()
boundary_start = f"--{boundary}".encode()
# The multipart/form-data spec doesn't require a newline after the boundary, however many clients do
# implement it that way
boundary_end = f"--{boundary}--\r\n".encode()
boundary_end_no_newline = f"--{boundary}--".encode()
if not body.startswith(boundary_start) or not body.endswith(boundary_end):
if not body.startswith(boundary_start) or not body.endswith((boundary_end, boundary_end_no_newline)):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content={"detail": "Invalid multipart formatting"},