英文:
Custom FastAPI middleware causes LocalProtocolError("Too much data for declared Content-Length") exception
问题
I have a middleware implemented for FastAPI. For responses that include some content, it works perfectly. But if a response has no body, it is causing a LocalProtocolError
exception with the message "Too much data for declared Content-Length."
To isolate the problem, I've reduced the middleware class to this:
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)
It basically does nothing.
When I add the middleware, I have an exception:
raise LocalProtocolError("Too much data for declared Content-Length")
h11._util.LocalProtocolError: Too much data for declared Content-Length
When I disable the middleware, I have no problem.
Here is the line that creates the response which triggers the exception:
return Response(status_code=HTTP_204_NO_CONTENT)
To further debug the problem, I've activated a breakpoint in the h11/_writers.py
ContentLengthWriter
class, where the actual exception occurs.
I've tried to decode the byte stream with utf-8 and cp437, but had no luck.
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)
I'm stopping the code at this line: self._length -= len(data)
If the middleware is disabled, data
looks like this: b''
If the middleware is enabled, data
looks like this: b'\x1f\x8b\x08\x00\xf6God\x02\xff'
What would be modifying the content of the response?
英文:
I have a middleware implemented for FastAPI. For responses that includes some content, it works perfectly. But if a response has no body, it is causing LocalProtocolError("Too much data for declared Content-Length")
exception.
To isolate the problem, I've reduced the middleware class to this:
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)
It basically does nothing.
When I add the middleware, I have an exception:
raise LocalProtocolError("Too much data for declared Content-Length")
h11._util.LocalProtocolError: Too much data for declared Content-Length
When I disable the middleware, I have no problem.
Here is the line that creates the response which triggers the exception:
return Response(status_code=HTTP_204_NO_CONTENT)
To further debug the problem, I've activated a breakpoint in the h11/_writers.py
ContentLengthWriter
class, where the actual exception occurs.
I've tried to decode the byte stream with utf-8 and cp437, but had no luch.
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)
I'm stopping the code at this line: self._length -= len(data)
If the middleware is disabled, data
looks like this: b''
If the middleware is enabled, data
looks like this: b'\x1f\x8b\x08\x00\xf6God\x02\xff'
What would be modifying the content of the response?
答案1
得分: 0
我已解决了。我只是改变了中间件添加的顺序。当我将我的中间件移到GZIP中间件之后,问题就消失了。
感谢MatsLindh指出这是一个gzip标头。
英文:
I've solved it. I've just changed the order of which middlewares are added. When I moved my middleware after the GZIP middleware, problem disappeared.
Thanks to MatsLindh for pointing out that it is a gzip header.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论