aiohttp icon indicating copy to clipboard operation
aiohttp copied to clipboard

HTTPRequestEntityTooLarge not raised when using request.multipart()

Open samuelcolvin opened this issue 6 years ago • 2 comments

Long story short

processing a request using

reader = await request.multipart()
foobar = await reader.next()
...

Should raise HTTPRequestEntityTooLarge if the request size exceeds client_max_size, currently I think it does not.

At the very least this should be documented.

samuelcolvin avatar Apr 18 '19 17:04 samuelcolvin

from aiohttp import web, MultipartReader, HTTPRequestEntityTooLarge

async def handle_upload(request):
    # Check the content length of the request
    content_length = request.content_length
    max_content_length = 1024 * 1024  # Set your maximum allowed content length here

    if content_length is not None and content_length > max_content_length:
        raise HTTPRequestEntityTooLarge

    reader = MultipartReader.from_response(request)
    
    try:
        while True:
            part = await reader.next()
            if part is None:
                break
            # Process each part of the multipart request
            # ...
    
    except HTTPRequestEntityTooLarge:
        # Handle the request size exceeding the limit
        return web.HTTPRequestEntityTooLarge()
    
    return web.Response(text='Upload successful')

app = web.Application()
app.router.add_post('/upload', handle_upload)
web.run_app(app)

ljluestc avatar Nov 20 '23 15:11 ljluestc

Simple reproducer:

from aiohttp import web

async def handle_upload(request):
    print(request.content_length, request.client_max_size)

    reader = await request.multipart()
    
    while True:
        part = await reader.next()
        if part is None:
            break
    
    return web.Response(text='Upload successful')

app = web.Application(client_max_size=10)
app.router.add_post('/', handle_upload)
web.run_app(app)
curl http://localhost:8080/ -X POST -F key=1234567890abcd

It appears that the attribute is only used in the convenience methods, so it works when using request.post() or request.read(). I would assume the same issue would occur if using request.content directly too, though as that's for streaming, maybe it shouldn't matter.

I also wonder if max size isn't something that should be handled by a firewall/proxy to avoid the overhead here.

Dreamsorcerer avatar Aug 12 '24 19:08 Dreamsorcerer