我为FastAPI实现了一个中间件。对于包含一些内容的响应,它可以完美地工作。但是如果一个响应没有body,就会导致LocalProtocolError("Too much data for declared Content-Length")
异常。
为了隔离问题,我将中间件类缩减为:
from starlette.middleware.base import BaseHTTPMiddleware
from fastapi import FastAPI, Request
class LanguageManagerMiddleware(BaseHTTPMiddleware):
def __init__(self, app: FastAPI):
super().__init__(app)
async def dispatch(self, request: Request, call_next) -> None:
return await call_next(request)
它基本上什么都不做。
当我添加中间件时,我有一个例外:
raise LocalProtocolError("Too much data for declared Content-Length")
h11._util.LocalProtocolError: Too much data for declared Content-Length
当我禁用中间件时,我没有问题。
下面是创建触发异常的响应的代码行:
return Response(status_code=HTTP_204_NO_CONTENT)
为了进一步调试这个问题,我在h11/_writers.py
x 1 m2n1x类中激活了一个断点,实际的异常发生在这个断点上。
我试着用utf-8和cp 437解码字节流,但没有成功。
class ContentLengthWriter(BodyWriter):
def __init__(self, length: int) -> None:
self._length = length
def send_data(self, data: bytes, write: Writer) -> None:
self._length -= len(data)
if self._length < 0:
raise LocalProtocolError("Too much data for declared Content-Length")
write(data)
我在这一行停止代码:self._length -= len(data)
如果中间件被禁用,data
看起来像这样:b''
如果中间件是启用的,data
看起来像这样:b'\x1f\x8b\x08\x00\xf6God\x02\xff'
如何修改响应的内容?
1条答案
按热度按时间xe55xuns1#
我已经解决了我刚刚更改了添加中间件的顺序。当我把中间件移到GZIP中间件之后,问题就消失了。
感谢MatsLindh指出它是一个gzip头文件。