aio-libs / aiohttp

Asynchronous HTTP client/server framework for asyncio and Python
https://docs.aiohttp.org
Other
15.12k stars 2.02k forks source link

HTTPRequestEntityTooLarge not raised when using request.multipart() #3702

Open samuelcolvin opened 5 years ago

samuelcolvin commented 5 years ago

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.

ljluestc commented 11 months ago
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)
Dreamsorcerer commented 2 months ago

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.