python - 带 aiohttp TestClient 的多部分文件上传导致第二次请求出现“无效的 HTTP 方法”错误
问题描述
我继承了一个使用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
解决方案
推荐阅读
- java - 当 xml 中存在相同节点作为空标记时,将节点添加到 xml
- c++ - 重构类:无法将派生类中成员函数的通用代码移回基类
- c# - 当执行策略设置为 RemoteSigned 时,为什么从 Internet (azure blob) 下载后执行脚本
- css - 如何减少引导程序中选择之间的填充
- javascript - 让超时工作
- java - Gradle build with Lombok
- wix - WIX 合并 C++ 运行时
- wordpress - 重新提交解析验证后,提交时的重力表不收集条目
- jsf - p:fileUpload 不适用于同一页面中的 pe:blockUI
- magento - Magento 中缺少购物车信息