серверу aiohttp не удается загрузить файл, размер которого превышает некоторый порог

#python #http #curl #server #aiohttp

Вопрос:

Я использую следующий упрощенный код сервера, который должен загрузить файл ./upgrades/file.bin (относительно расположения кода сервера) в ответ на любой запрос POST от клиента.

 import aiohttp
from aiohttp import web, WSCloseCode
import asyncio
import os

FILE_PATH = "./upgrades/file.bin"
async def http_post_handler(request):
    with open(FILE_PATH, 'rb') as f:
        fs = os.fstat(f.fileno())
        headers = {"Content-Type": 'application/octet-stream',
                   "Content-Disposition": 'attachment; filename="{}"'.format(os.path.basename(FILE_PATH)),
                   "Content-Length": str(fs.st_size)}

        return web.Response(body=f.read(), headers=headers)


def create_runner():
    app = web.Application()
    app.add_routes([
        web.post('/{post:.*}', http_post_handler),
    ])
    return web.AppRunner(app)

async def start_server(host="192.168.1.1", port=44444):
    runner = create_runner()
    await runner.setup()
    site = web.TCPSite(runner, host, port)
    await site.start()


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(start_server())
    loop.run_forever()
 

и на стороне клиента я вызываю запрос POST :

curl -X POST "http://192.168.1.1:44444/post/upgrade" --output /tmp/121

—> один раз, когда размер файла превышает допустимое значение. в этом случае операция надолго останавливается и в конечном итоге загружается поврежденный файл (содержимое файла включает некоторые заголовки http-ответов, и похоже, что последние 100 байт файла перемещаются назад к началу целевого файла).

dd if=original of=file.bin bs=1 count=65840

—> и еще один до этого предела. в этом случае успех операции быстро

dd if=original of=file.bin bs=1 count=65839

Я также заметил, что если клиент будет работать на той же машине, что и сервер. и сервер будет прослушивать адрес 0.0.0.0, а клиент подключится к обратному адресу, проблема не возникнет, и оба действия будут успешно завершены в одно мгновение.

Возможно, размер файла превышает пороговое значение http-сообщения (64 кб) ? но я бы ожидал, что даже в этом случае файл будет разбит на куски и его можно будет загрузить.

Есть идеи, как исправить код сервера ?

Спасибо!