ariadne
ariadne copied to clipboard
multipart.File has no MIME type information
Unfortunately, multipart's File
class seems to have a serious regression compared to cgi's FieldStorage
class: Where FieldStorage.type
contained the declared MIME type of the uploaded file (or None
if not given), File
does not seem to have this information. This makes is basically impossible to download uploaded files while keeping the file type intact.
Pull request resolving this is welcome. But I'm afraid this will require changes upstream to the library we are using for request parsing. :/
Can't this be worked around by checking uploaded file's extension and contents? Those are sent by browser in the first place and can be spoofed anyway.
It's kind of possible to try to determine the MIME type server side, using a library that does that, but it's more reliable to use the uploaded file type when the file is just transparently stored server-side. For example, a user might upload a file from a proprietary program that correctly registers its (custom) MIME type in the OS. When downloading that file, the MIME type will still be correct. The server would most likely not recognize the file type and just use application/octet-stream
.
Of course there are certain security implications when trusting the client's MIME type, but those are application-specific.
Until somebody contributes a fix to either Ariadne or upstream to python-multipart, this will be a limitation that will have to be worked around I'm afraid.
We just can't maintain custom HTTP parser as part of Ariadne. We are GraphQL library and not HTTP library.
Other workarounds that come to mind here are replacing ariadne.wsgi
with one of existing WSGI frameworks like Flask.
Multipart's limitations keep coming up on Encode's GitHub, and will be discussed on our next meeting. 🤞
I've started musing if moving WSGI app to use the Werkzeug wouldn't solve the problem. That way people using Ariadne's WSGI app would get layer of sanity between raw environ
dict and proper Request
and Response
objects that Flask already uses.
We could have a quick Ariadne release with ariadne.wsgi_future
module that has new WSGI app powered by Werkzeug, and after few versions move it under wsgi
and drop old one.
Issue on python-multipart repo: https://github.com/andrew-d/python-multipart/issues/58