There are two pieces of information you can use here:
Sometimes the Content-Length header is set; parsing ensures that this is accurate for the actual data uploaded. If so, you can get this value from the FileStorage.content_length
attribute.
The files uploaded are file objects (either temporary files on disk or in-memory file-like objects); just use file.seek()
and file.tell()
on these to determine their size without having to read the whole object. It may be that an in-memory file object doesn't support seeking, at which point you should be able to read the whole file into memory as it'll be small enough not to need a temporary on-disk file.
Combined, the best way to test for individual file sizes then is:
def get_size(fobj):
if fobj.content_length:
return fobj.content_length
try:
pos = fobj.tell()
fobj.seek(0, 2) #seek to end
size = fobj.tell()
fobj.seek(pos) # back to original position
return size
except (AttributeError, IOError):
pass
# in-memory file object that doesn't support seeking or tell
return 0 #assume small enough
then in your loop:
for fobj in request.files.getlist('f[]'):
if get_size(fobj) > 50 * (1024 ** 2):
abort(413) # request entity too large
This avoids having to read data into memory altogether.