Skip to content

Commit

Permalink
flush() after writing to gzip_file
Browse files Browse the repository at this point in the history
In order to better support streaming responses where the chunks are smaller than the file buffer size, we flush after writing.

Without the explicit flush, the writes are buffered and the subsequent reads see an empty self.gzip_buffer until the file automatically flushes due to either
(1) the write buffer fills, probably at 8kiB, or (2) the file is closed because the streaming response is complete.

Without flushing, the GZipMiddleware doesn't work as expected for streaming responses, especially not for Server-Sent Events which are expected to be delivered immediately to clients. The code as written appears to intend to flush immediately rather than buffering, as it does immediately call `await self.send(message)`, but in practice that `message` is often empty.
  • Loading branch information
vin authored Nov 15, 2024
1 parent 427a8dc commit f1b1ef8
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions starlette/middleware/gzip.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ async def send_with_gzip(self, message: Message) -> None:
del headers["Content-Length"]

self.gzip_file.write(body)
self.gzip_file.flush()
message["body"] = self.gzip_buffer.getvalue()
self.gzip_buffer.seek(0)
self.gzip_buffer.truncate()
Expand All @@ -94,6 +95,7 @@ async def send_with_gzip(self, message: Message) -> None:
more_body = message.get("more_body", False)

self.gzip_file.write(body)
self.gzip_file.flush()
if not more_body:
self.gzip_file.close()

Expand Down

0 comments on commit f1b1ef8

Please sign in to comment.