Non UTF-8 binary data is corrupted when passed to File() parameter without file name #11800
-
First Check
Commit to Help
Example Codefrom fastapi import FastAPI, File
from fastapi.testclient import TestClient
from typing_extensions import Annotated
app = FastAPI()
@app.post("/action")
def post_action(file: Annotated[bytes, File()]):
return {"file_bytes": len(file)}
if __name__ == "__main__":
client = TestClient(app)
# With filename works as expected
filename_body = b"""\
--Test\r\n\
Content-Type: application/octet-stream\r\n\
Content-Disposition: form-data; name="file"; filename="file"\r\n\
\r\n\
\xc3\x28\r\n\
--Test--\
"""
with open("request_filename_body.bin", "wb") as f:
f.write(filename_body)
r = client.post(
"/action",
headers={"Content-Type": "multipart/form-data; boundary=Test"},
content=filename_body,
)
assert r.status_code == 200, r.text
# OK!
assert r.json() == {"file_bytes": 2}, r.json()
# OK!
# Without filename the data got corrupted
no_filename_body = b"""\
--Test\r\n\
Content-Type: application/octet-stream\r\n\
Content-Disposition: form-data; name="file"\r\n\
\r\n\
\xc3\x28\r\n\
--Test--\
"""
with open("request_no_filename_body.bin", "wb") as f:
f.write(no_filename_body)
r = client.post(
"/action",
headers={"Content-Type": "multipart/form-data; boundary=Test"},
content=no_filename_body,
)
assert r.status_code == 200, r.text
# OK!
assert r.json() == {"file_bytes": 2}, r.json()
# AssertionError: {'file_bytes': 3} DescriptionNon UTF-8 data got corrupted if passed to To reproduce by To reproduce by curl:
Operating SystemLinux Operating System DetailsNo response FastAPI Version0.111.0 Pydantic Version2.7.4 Python Version3.8.10 Additional ContextOther packages versions that, I think, may affect:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
See the Note box at the bottom of this page referencing rfc 7578 |
Beta Was this translation helpful? Give feedback.
-
Hi @jgould22 as @DenisKuplyakov has mentioned, the docs from starlette says you should add a filename to be able to identify there is a file in the request, despite the RFC says isn't mandatory, the starlette docs explain the expected behavior. If you still feel disagree with it, feel free to open a feature request in startlette repo about this stuff. |
Beta Was this translation helpful? Give feedback.
Thanks, looks like this one should be reported to starlette. I will do it later.
Regarding the current starlette behaviour. Just for the clarity of this discussion I copy-pasted the note from the link: