Skip to content

Server returns 400: "invalid character in chunk size header" for valid request #5220

@romasku

Description

@romasku

🐞 Describe the bug
When server ignores content of request with Transfer-Encoding: chunked, parsing of next request can fail.

💡 To Reproduce

The following script:

import asyncio

from aiohttp import web, ClientSession


async def start_server():
    async def hello(request):
        return web.Response(text="OK", status=200)

    app = web.Application()
    app.add_routes([web.get('/', hello)])
    app.add_routes([web.put('/', hello)])

    runner = web.AppRunner(app)
    await runner.setup()
    site = web.TCPSite(runner, 'localhost', 8080)
    await site.start()


async def main():
    await start_server()

    async def data_gen():
        for _ in range(10):
            yield b'just data'
            await asyncio.sleep(0.1)  # Make sending of content slow

    async with ClientSession() as session:
        while True:
            # Do put
            async with session.put("http://localhost:8080", data=data_gen()):
                pass
            # Do get
            async with session.get("http://localhost:8080") as resp:
                if resp.status != 200:
                    print("failed with status: ", resp.status)
                    print("content is: ", await resp.content.read())
                    return
            await asyncio.sleep(0.1)

asyncio.run(main())

Prints the following:

$ python3 reproduce.py 
Error handling request
Traceback (most recent call last):
  File ".../venv/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 315, in data_received
    messages, upgraded, tail = self._request_parser.feed_data(data)
  File "aiohttp/_http_parser.pyx", line 546, in aiohttp._http_parser.HttpParser.feed_data
aiohttp.http_exceptions.BadHttpMessage: 400, message='invalid character in chunk size header'
failed with status:  400
content is:  b'invalid character in chunk size header'

If I add await request.content.read(), the problem disappears.

💡 Expected behavior

Server should not fail to parse valid request.

📋 Your version of the Python

$ python --version
Python 3.7.9

📋 Your version of the aiohttp/yarl/multidict distributions

$ python -m pip show aiohttp
Name: aiohttp
Version: 3.7.2
...
$ python -m pip show multidict
Name: multidict
Version: 4.7.6
...
$ python -m pip show yarl
Name: yarl
Version: 1.6.2
...

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions