多部分文件上载w/aiohttp testclient在第二次请求时导致“无效http方法”错误

u91tlkcl  于 2021-09-08  发布在  Java
关注(0)|答案(0)|浏览(327)

我继承了一个利用 aiohttp ,我不熟悉。在尝试修改测试时,我发现在一行中上载两个多部分文件(不仅仅是表单)会导致服务器返回 400 Bad status line 'invalid HTTP method' 错误(但请参见下面的注解1)。
添加 await request.release() 对服务器方法的语句解决了问题,但您不应该这样做。
在这一点上,我不知道如何解决这个问题。我已将代码库缩减为这个最小的应用程序:

from aiohttp import web

routes = web.RouteTableDef()

@routes.post("/thing")
async def thing(request: web.Request):
    # await request.release()                       # uncommenting this line fixes the issue
    return web.json_response({"hey": "there"})

def app_factory():
    app = web.Application()
    app.router.add_routes(routes)
    return app

... 这是一个最小的测试用例,它仍然在大的方面:

import asyncio
import os

from aiohttp import test_utils

import gdi.app_min as app

class AppClient:
    def __init__(self):
        self.server = test_utils.TestServer(app.app_factory())

    async def __aenter__(self):
        await self.server.start_server(loop=asyncio.get_event_loop())
        self.client = test_utils.TestClient(self.server, loop=asyncio.get_event_loop())
        return self.client

    async def __aexit__(self, *args):
        await self.server.close()
        await self.client.close()

async def test_upload():
    testdir = os.path.normpath(os.path.join(os.getcwd(), './temptest/'))
    os.makedirs(testdir, exist_ok=True)
    async with AppClient() as cli:
        await _do_thing(cli, testdir, "test_file_1")
        await _do_thing(cli, testdir, "test_file_2")

async def _do_thing(cli, testdir, filename):
    path = os.path.join(testdir, filename)
    with open(path, encoding="utf-8", mode="w") as f:
        f.write("testtext")

    # failure only occurs with file upload & no await request.release() in app
    # data={"uploads": "stuff"} is ok
    with open(path, "rb") as f:
        res = await cli.post("thing", data={"uploads": f})
    print(f'\n***res for {filename}***')
    print(await(res.text()))
    print(f"***")
    assert res.status == 200

这将导致第二次调用时服务器日志中出现403和以下错误:

Error handling request
Traceback (most recent call last):
  File "/home/<user>/.local/share/virtualenvs/<dir>-YbLpo7lw/lib/python3.6/site-packages/aiohttp/web_protocol.py", line 314, 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.BadStatusLine: 400, message="Bad status line 'invalid HTTP method'"

在这一点上,我花了一天的大部分时间阅读aiohttp文档,试图弄明白这一点,我不太确定下一步该去哪里。如有任何建议,将不胜感激。
编辑:看起来这是一个已知的错误。
注1:显然,错误状态行错误具有误导性:https://github.com/aio-libs/aiohttp/issues/3287#issuecomment-425008291

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题