Custom FastAPI middleware导致LocalProtocolError(“Content-Length声明的数据过多”)异常。

huangapple go评论167阅读模式
英文:

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(&quot;Too much data for declared Content-Length&quot;) 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) -&gt; None:

        return await call_next(request)

It basically does nothing.

When I add the middleware, I have an exception:

    raise LocalProtocolError(&quot;Too much data for declared Content-Length&quot;)
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) -&gt; None:
            self._length = length
    
        def send_data(self, data: bytes, write: Writer) -&gt; None:
            self._length -= len(data)
            if self._length &lt; 0:
                raise LocalProtocolError(&quot;Too much data for declared Content-Length&quot;)
            write(data)

I'm stopping the code at this line: self._length -= len(data)

If the middleware is disabled, data looks like this: b&#39;&#39;

If the middleware is enabled, data looks like this: b&#39;\x1f\x8b\x08\x00\xf6God\x02\xff&#39;

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.

huangapple
  • 本文由 发表于 2023年5月25日 19:43:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76331894.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定