First Check
Commit to Help
Example Code
from typing import Awaitable, Callable
from fastapi import FastAPI
from fastapi.middleware.gzip import GZipMiddleware
from starlette.requests import Request
app = FastAPI()
@app.middleware("http")
async def noop_middleware(request: Request, call_next: Callable[[Request], Awaitable]):
return await call_next(request)
@app.get("/", status_code=304)
def youve_seen_this_before():
pass
app.add_middleware(GZipMiddleware)
Description
curl -sH "Accept-Encoding: gzip" localhost:8000
This will reliably:
a) Give the expected 304 empty response.
b) Show a stack trace "Response content longer than Content-Length"
The root cause I believe is the base middleware (in this example the noop one) creates a StreamingResponse for what is ultimately an empty response, it consists of two streaming chunks ("", more=True), ("", more=False); which bypasses the minimum length check in the GZip middleware.
GZip then compresses the 'nothing' resulting in the GZip minimum boilerplate, but an expected content length of 0 then throws. This is post-response so the client wont see the error but the server will.
Operating System
Linux, macOS
Operating System Details
Don't think this is relevant.
FastAPI Version
0.63.0
Python Version
3.8.10
Additional Context
This is actually the root cause of issue: #2818
In the case of that issue the trigger is the StaticFiles mount has not-modified support, and on getting a non-modified static resource returns a 304. I suspect the original issue reporter stopped running into it either as a by-product of not getting 304 as often, or alternatively changing their middleware so as not to create the StreamingResponse.
First Check
Commit to Help
Example Code
Description
curl -sH "Accept-Encoding: gzip" localhost:8000
This will reliably:
a) Give the expected 304 empty response.
b) Show a stack trace "Response content longer than Content-Length"
The root cause I believe is the base middleware (in this example the noop one) creates a StreamingResponse for what is ultimately an empty response, it consists of two streaming chunks ("", more=True), ("", more=False); which bypasses the minimum length check in the GZip middleware.
GZip then compresses the 'nothing' resulting in the GZip minimum boilerplate, but an expected content length of 0 then throws. This is post-response so the client wont see the error but the server will.
Operating System
Linux, macOS
Operating System Details
Don't think this is relevant.
FastAPI Version
0.63.0
Python Version
3.8.10
Additional Context
This is actually the root cause of issue: #2818
In the case of that issue the trigger is the StaticFiles mount has not-modified support, and on getting a non-modified static resource returns a 304. I suspect the original issue reporter stopped running into it either as a by-product of not getting 304 as often, or alternatively changing their middleware so as not to create the StreamingResponse.