我正在尝试创建一个数据端点,它可以流式传输整个文件,也可以适当地响应范围请求。流式传输整个文件似乎可以理解,但我不清楚如何处理范围请求。特别是,我看不到aiohttp.MultipartWriter
如何写入StreamResponse
。在
到目前为止,以下是我代码的抽象形式:
from aiohttp.web import Request, StreamResponse
from aiohttp.multipart import MultipartWriter
async def data_handler(req:Request) -> StreamResponse:
is_range_request = "Range" in req.headers
with open("my_big_file", "rb") as f:
if is_range_request:
status_code = 202
content_type = "multipart/bytes"
else:
status_code = 200
content_type = "application/octet-stream"
resp = SteamResponse(status=status_code, headers={"Content-Type": content_type})
resp.enable_chunked_encoding()
resp.enable_compression()
await resp.prepare(req)
if is_range_request:
# _parse_range_header :: str -> List[ByteRange]
# ByteRange = Tuple[int, int] i.e., "from" and "to", inclusive
ranges = _parse_range_header(req.headers["Range"])
mpwriter = MultipartWriter("bytes")
for r in ranges:
range_from, range_to = r
range_size = (range_to - range_from) + 1
range_header = {"Content-Type": "application/octet-stream"}
# FIXME Won't this block?
f.seek(range_from)
mpwriter.append(f.read(range_size), range_header)
# TODO Write to response. How?...
else:
while True:
data = f.read(8192)
if not data:
await resp.drain()
break
resp.write(data)
return resp
这也不会返回响应,直到它到达最后。在我看来,这似乎不正确:在返回响应之前,上游调用如何知道发生了什么;或者asyncio
的东西是自动为我做这件事的?在
目前没有回答
相关问题 更多 >
编程相关推荐