#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 кб) ? но я бы ожидал, что даже в этом случае файл будет разбит на куски и его можно будет загрузить.
Есть идеи, как исправить код сервера ?
Спасибо!