-
-
Notifications
You must be signed in to change notification settings - Fork 188
Description
The Request
class, in src/quart/wrappers/request.py
, has a max_content_length
property which is writable: calling code can set it to None
, which should remove any limit on the size of the request body. But the Body
class checks expected_content_length
against max_content_length
in its __init__
function, and the value of max_content_length
there is always the global default from app.config
, because the body object is constructed before application code has a chance to set a different limit on the request. This means that if clients provide Content-Length
headers on their uploads, the only way for the application to allow large uploads is by setting app.config["MAX_CONTENT_LENGTH"] = None
for the entire application, rather than just for the route that expects the large uploads.
(Strictly speaking it's not the only way, since the application could also do request.body._must_raise = None
before reading from the request body within a handler method, but that's a brittle workaround at best. Applications shouldn't have to touch private fields like that.)
Instead, the size should be checked only when the application starts to actually consume the request body, so that the application has a chance to modify max_content_length
before doing that. An application should be able to implement a route like this:
@app.route("/upload", methods = ["PUT"])
async def handle_file_upload():
request.max_content_length = None
async for chunk in request.body:
...
…and have this route allow uploads of unlimited size, while other routes are still subject to the limit from app.config["MAX_CONTENT_LENGTH"]
.
However, this depends on fixing #152, so that Quart doesn't actually start reading the request body until the application starts to consume it. Currently, Quart begins reading the body into memory immediately, so the size limit has to be enforced immediately. There are size checks in both Body.__init__
and Body.append
, both of which can run before the application starts to consume the body. The changes for #152 would involve removing the Body.append
method and changing Body.__anext__
and Body.__await__
to read directly from the client instead of returning already-buffered input, so the size checks could be done in those places instead.