We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: Enabling gzip only sends large streaming responses
### Description

Enabling gzip compression causes small streaming responses to be completely ignored and never sent to the client browser.
I have verified that the request headers to specify at the very least:
`Accept-Encoding: gzip`
As can be seen in the logs.

### URL to code causing the issue

https://github.com/LeckerenSirupwaffeln/Litestar_StreamingResponseGzip_Bug

### MCVE

```python
https://github.com/LeckerenSirupwaffeln/Litestar_StreamingResponseGzip_Bug
```


### Steps to reproduce

```bash
1. git clone https://github.com/LeckerenSirupwaffeln/Litestar_StreamingResponseGzip_Bug
2. cd Litestar_StreamingResponseGzip_Bug
3. docker compose up
4. Open your browser
5. Navigate to http://127.0.0.1:8000/event
6. Open developer tools, go to Console
7. Click "Start retrieving data"
8. Observe that only the large arrays of data get received by the client browser. These arrays should have a size of 1000000, while arrays that have a size of 500 do not get printed to the console, and thus do not get received.

Alternatively:
Disable gzip compression in app construction and observe that arrays of size of 500 do get printed to the console as do the arrays of size of 10000000.
```


### Screenshots

_No response_

### Logs

```bash
Request headers:

POST /event HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,nl-NL;q=0.8,nl;q=0.7
Connection: keep-alive
Content-Length: 2
Content-Type: application/json
DNT: 1
Host: 127.0.0.1:8000
Origin: http://127.0.0.1:8000
Referer: http://127.0.0.1:8000/event
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="113", "Chromium";v="113", "Not-A.Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
```


### Litestar Version

2.0.0alpha3

### Platform

- [X] Linux
- [ ] Mac
- [ ] Windows
- [ ] Other (Please specify in the description above)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `litestar/middleware/compression.py`
Content:
```
1 from __future__ import annotations
2 
3 from gzip import GzipFile
4 from io import BytesIO
5 from typing import TYPE_CHECKING, Any, Literal, Optional
6 
7 from litestar.constants import SCOPE_STATE_RESPONSE_COMPRESSED
8 from litestar.datastructures import Headers, MutableScopeHeaders
9 from litestar.enums import CompressionEncoding, ScopeType
10 from litestar.exceptions import MissingDependencyException
11 from litestar.middleware.base import AbstractMiddleware
12 from litestar.utils import Ref, set_litestar_scope_state
13 
14 __all__ = ("CompressionFacade", "CompressionMiddleware")
15 
16 
17 if TYPE_CHECKING:
18     from litestar.config.compression import CompressionConfig
19     from litestar.types import (
20         ASGIApp,
21         HTTPResponseStartEvent,
22         Message,
23         Receive,
24         Scope,
25         Send,
26     )
27 
28     try:
29         from brotli import Compressor
30     except ImportError:
31         Compressor = Any
32 
33 
34 class CompressionFacade:
35     """A unified facade offering a uniform interface for different compression libraries."""
36 
37     __slots__ = ("compressor", "buffer", "compression_encoding")
38 
39     compressor: GzipFile | Compressor  # pyright: ignore
40 
41     def __init__(self, buffer: BytesIO, compression_encoding: CompressionEncoding, config: CompressionConfig) -> None:
42         """Initialize ``CompressionFacade``.
43 
44         Args:
45             buffer: A bytes IO buffer to write the compressed data into.
46             compression_encoding: The compression encoding used.
47             config: The app compression config.
48         """
49         self.buffer = buffer
50         self.compression_encoding = compression_encoding
51 
52         if compression_encoding == CompressionEncoding.BROTLI:
53             try:
54                 import brotli  # noqa: F401
55             except ImportError as e:
56                 raise MissingDependencyException("brotli") from e
57 
58             from brotli import MODE_FONT, MODE_GENERIC, MODE_TEXT, Compressor
59 
60             modes: dict[Literal["generic", "text", "font"], int] = {
61                 "text": int(MODE_TEXT),
62                 "font": int(MODE_FONT),
63                 "generic": int(MODE_GENERIC),
64             }
65             self.compressor = Compressor(
66                 quality=config.brotli_quality,
67                 mode=modes[config.brotli_mode],
68                 lgwin=config.brotli_lgwin,
69                 lgblock=config.brotli_lgblock,
70             )
71         else:
72             self.compressor = GzipFile(mode="wb", fileobj=buffer, compresslevel=config.gzip_compress_level)
73 
74     def write(self, body: bytes) -> None:
75         """Write compressed bytes.
76 
77         Args:
78             body: Message body to process
79 
80         Returns:
81             None
82         """
83 
84         if self.compression_encoding == CompressionEncoding.BROTLI:
85             self.buffer.write(self.compressor.process(body) + self.compressor.flush())  # type: ignore
86         else:
87             self.compressor.write(body)
88 
89     def close(self) -> None:
90         """Close the compression stream.
91 
92         Returns:
93             None
94         """
95         if self.compression_encoding == CompressionEncoding.BROTLI:
96             self.buffer.write(self.compressor.finish())  # type: ignore
97         else:
98             self.compressor.close()
99 
100 
101 class CompressionMiddleware(AbstractMiddleware):
102     """Compression Middleware Wrapper.
103 
104     This is a wrapper allowing for generic compression configuration / handler middleware
105     """
106 
107     def __init__(self, app: ASGIApp, config: CompressionConfig) -> None:
108         """Initialize ``CompressionMiddleware``
109 
110         Args:
111             app: The ``next`` ASGI app to call.
112             config: An instance of CompressionConfig.
113         """
114         super().__init__(
115             app=app, exclude=config.exclude, exclude_opt_key=config.exclude_opt_key, scopes={ScopeType.HTTP}
116         )
117         self.config = config
118 
119     async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
120         """ASGI callable.
121 
122         Args:
123             scope: The ASGI connection scope.
124             receive: The ASGI receive function.
125             send: The ASGI send function.
126 
127         Returns:
128             None
129         """
130         accept_encoding = Headers.from_scope(scope).get("accept-encoding", "")
131 
132         if CompressionEncoding.BROTLI in accept_encoding and self.config.backend == "brotli":
133             await self.app(
134                 scope,
135                 receive,
136                 self.create_compression_send_wrapper(
137                     send=send, compression_encoding=CompressionEncoding.BROTLI, scope=scope
138                 ),
139             )
140             return
141 
142         if CompressionEncoding.GZIP in accept_encoding and (
143             self.config.backend == "gzip" or self.config.brotli_gzip_fallback
144         ):
145             await self.app(
146                 scope,
147                 receive,
148                 self.create_compression_send_wrapper(
149                     send=send, compression_encoding=CompressionEncoding.GZIP, scope=scope
150                 ),
151             )
152             return
153 
154         await self.app(scope, receive, send)
155 
156     def create_compression_send_wrapper(
157         self,
158         send: Send,
159         compression_encoding: Literal[CompressionEncoding.BROTLI, CompressionEncoding.GZIP],
160         scope: Scope,
161     ) -> Send:
162         """Wrap ``send`` to handle brotli compression.
163 
164         Args:
165             send: The ASGI send function.
166             compression_encoding: The compression encoding used.
167             scope: The ASGI connection scope
168 
169         Returns:
170             An ASGI send function.
171         """
172 
173         buffer = BytesIO()
174         facade = CompressionFacade(buffer=buffer, compression_encoding=compression_encoding, config=self.config)
175 
176         initial_message = Ref[Optional["HTTPResponseStartEvent"]](None)
177         started = Ref[bool](False)
178 
179         async def send_wrapper(message: Message) -> None:
180             """Handle and compresses the HTTP Message with brotli.
181 
182             Args:
183                 message (Message): An ASGI Message.
184             """
185 
186             if message["type"] == "http.response.start":
187                 initial_message.value = message
188                 return
189 
190             if initial_message.value and message["type"] == "http.response.body":
191                 body = message["body"]
192                 more_body = message.get("more_body")
193 
194                 if not started.value:
195                     started.value = True
196                     if more_body:
197                         headers = MutableScopeHeaders(initial_message.value)
198                         headers["Content-Encoding"] = compression_encoding
199                         headers.extend_header_value("vary", "Accept-Encoding")
200                         del headers["Content-Length"]
201                         set_litestar_scope_state(scope, SCOPE_STATE_RESPONSE_COMPRESSED, True)
202 
203                         facade.write(body)
204 
205                         message["body"] = buffer.getvalue()
206                         buffer.seek(0)
207                         buffer.truncate()
208                         await send(initial_message.value)
209                         await send(message)
210 
211                     elif len(body) >= self.config.minimum_size:
212                         facade.write(body)
213                         facade.close()
214                         body = buffer.getvalue()
215 
216                         headers = MutableScopeHeaders(initial_message.value)
217                         headers["Content-Encoding"] = compression_encoding
218                         headers["Content-Length"] = str(len(body))
219                         headers.extend_header_value("vary", "Accept-Encoding")
220                         message["body"] = body
221                         set_litestar_scope_state(scope, SCOPE_STATE_RESPONSE_COMPRESSED, True)
222 
223                         await send(initial_message.value)
224                         await send(message)
225 
226                     else:
227                         await send(initial_message.value)
228                         await send(message)
229 
230                 else:
231                     facade.write(body)
232                     if not more_body:
233                         facade.close()
234 
235                     message["body"] = buffer.getvalue()
236 
237                     buffer.seek(0)
238                     buffer.truncate()
239 
240                     if not more_body:
241                         buffer.close()
242 
243                     await send(message)
244 
245         return send_wrapper
246
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/litestar/middleware/compression.py b/litestar/middleware/compression.py
--- a/litestar/middleware/compression.py
+++ b/litestar/middleware/compression.py
@@ -85,6 +85,7 @@
             self.buffer.write(self.compressor.process(body) + self.compressor.flush())  # type: ignore
         else:
             self.compressor.write(body)
+            self.compressor.flush()
 
     def close(self) -> None:
         """Close the compression stream.

{"golden_diff": "diff --git a/litestar/middleware/compression.py b/litestar/middleware/compression.py\n--- a/litestar/middleware/compression.py\n+++ b/litestar/middleware/compression.py\n@@ -85,6 +85,7 @@\n             self.buffer.write(self.compressor.process(body) + self.compressor.flush())  # type: ignore\n         else:\n             self.compressor.write(body)\n+            self.compressor.flush()\n \n     def close(self) -> None:\n         \"\"\"Close the compression stream.\n", "issue": "Bug: Enabling gzip only sends large streaming responses\n### Description\n\nEnabling gzip compression causes small streaming responses to be completely ignored and never sent to the client browser.\r\nI have verified that the request headers to specify at the very least:\r\n`Accept-Encoding: gzip`\r\nAs can be seen in the logs.\n\n### URL to code causing the issue\n\nhttps://github.com/LeckerenSirupwaffeln/Litestar_StreamingResponseGzip_Bug\n\n### MCVE\n\n```python\nhttps://github.com/LeckerenSirupwaffeln/Litestar_StreamingResponseGzip_Bug\n```\n\n\n### Steps to reproduce\n\n```bash\n1. git clone https://github.com/LeckerenSirupwaffeln/Litestar_StreamingResponseGzip_Bug\r\n2. cd Litestar_StreamingResponseGzip_Bug\r\n3. docker compose up\r\n4. Open your browser\r\n5. Navigate to http://127.0.0.1:8000/event\r\n6. Open developer tools, go to Console\r\n7. Click \"Start retrieving data\"\r\n8. Observe that only the large arrays of data get received by the client browser. These arrays should have a size of 1000000, while arrays that have a size of 500 do not get printed to the console, and thus do not get received.\r\n\r\nAlternatively:\r\nDisable gzip compression in app construction and observe that arrays of size of 500 do get printed to the console as do the arrays of size of 10000000.\n```\n\n\n### Screenshots\n\n_No response_\n\n### Logs\n\n```bash\nRequest headers:\r\n\r\nPOST /event HTTP/1.1\r\nAccept: application/json\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: en-US,en;q=0.9,nl-NL;q=0.8,nl;q=0.7\r\nConnection: keep-alive\r\nContent-Length: 2\r\nContent-Type: application/json\r\nDNT: 1\r\nHost: 127.0.0.1:8000\r\nOrigin: http://127.0.0.1:8000\r\nReferer: http://127.0.0.1:8000/event\r\nSec-Fetch-Dest: empty\r\nSec-Fetch-Mode: cors\r\nSec-Fetch-Site: same-origin\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36\r\nsec-ch-ua: \"Google Chrome\";v=\"113\", \"Chromium\";v=\"113\", \"Not-A.Brand\";v=\"24\"\r\nsec-ch-ua-mobile: ?0\r\nsec-ch-ua-platform: \"Windows\"\n```\n\n\n### Litestar Version\n\n2.0.0alpha3\n\n### Platform\n\n- [X] Linux\n- [ ] Mac\n- [ ] Windows\n- [ ] Other (Please specify in the description above)\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom gzip import GzipFile\nfrom io import BytesIO\nfrom typing import TYPE_CHECKING, Any, Literal, Optional\n\nfrom litestar.constants import SCOPE_STATE_RESPONSE_COMPRESSED\nfrom litestar.datastructures import Headers, MutableScopeHeaders\nfrom litestar.enums import CompressionEncoding, ScopeType\nfrom litestar.exceptions import MissingDependencyException\nfrom litestar.middleware.base import AbstractMiddleware\nfrom litestar.utils import Ref, set_litestar_scope_state\n\n__all__ = (\"CompressionFacade\", \"CompressionMiddleware\")\n\n\nif TYPE_CHECKING:\n    from litestar.config.compression import CompressionConfig\n    from litestar.types import (\n        ASGIApp,\n        HTTPResponseStartEvent,\n        Message,\n        Receive,\n        Scope,\n        Send,\n    )\n\n    try:\n        from brotli import Compressor\n    except ImportError:\n        Compressor = Any\n\n\nclass CompressionFacade:\n    \"\"\"A unified facade offering a uniform interface for different compression libraries.\"\"\"\n\n    __slots__ = (\"compressor\", \"buffer\", \"compression_encoding\")\n\n    compressor: GzipFile | Compressor  # pyright: ignore\n\n    def __init__(self, buffer: BytesIO, compression_encoding: CompressionEncoding, config: CompressionConfig) -> None:\n        \"\"\"Initialize ``CompressionFacade``.\n\n        Args:\n            buffer: A bytes IO buffer to write the compressed data into.\n            compression_encoding: The compression encoding used.\n            config: The app compression config.\n        \"\"\"\n        self.buffer = buffer\n        self.compression_encoding = compression_encoding\n\n        if compression_encoding == CompressionEncoding.BROTLI:\n            try:\n                import brotli  # noqa: F401\n            except ImportError as e:\n                raise MissingDependencyException(\"brotli\") from e\n\n            from brotli import MODE_FONT, MODE_GENERIC, MODE_TEXT, Compressor\n\n            modes: dict[Literal[\"generic\", \"text\", \"font\"], int] = {\n                \"text\": int(MODE_TEXT),\n                \"font\": int(MODE_FONT),\n                \"generic\": int(MODE_GENERIC),\n            }\n            self.compressor = Compressor(\n                quality=config.brotli_quality,\n                mode=modes[config.brotli_mode],\n                lgwin=config.brotli_lgwin,\n                lgblock=config.brotli_lgblock,\n            )\n        else:\n            self.compressor = GzipFile(mode=\"wb\", fileobj=buffer, compresslevel=config.gzip_compress_level)\n\n    def write(self, body: bytes) -> None:\n        \"\"\"Write compressed bytes.\n\n        Args:\n            body: Message body to process\n\n        Returns:\n            None\n        \"\"\"\n\n        if self.compression_encoding == CompressionEncoding.BROTLI:\n            self.buffer.write(self.compressor.process(body) + self.compressor.flush())  # type: ignore\n        else:\n            self.compressor.write(body)\n\n    def close(self) -> None:\n        \"\"\"Close the compression stream.\n\n        Returns:\n            None\n        \"\"\"\n        if self.compression_encoding == CompressionEncoding.BROTLI:\n            self.buffer.write(self.compressor.finish())  # type: ignore\n        else:\n            self.compressor.close()\n\n\nclass CompressionMiddleware(AbstractMiddleware):\n    \"\"\"Compression Middleware Wrapper.\n\n    This is a wrapper allowing for generic compression configuration / handler middleware\n    \"\"\"\n\n    def __init__(self, app: ASGIApp, config: CompressionConfig) -> None:\n        \"\"\"Initialize ``CompressionMiddleware``\n\n        Args:\n            app: The ``next`` ASGI app to call.\n            config: An instance of CompressionConfig.\n        \"\"\"\n        super().__init__(\n            app=app, exclude=config.exclude, exclude_opt_key=config.exclude_opt_key, scopes={ScopeType.HTTP}\n        )\n        self.config = config\n\n    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        \"\"\"ASGI callable.\n\n        Args:\n            scope: The ASGI connection scope.\n            receive: The ASGI receive function.\n            send: The ASGI send function.\n\n        Returns:\n            None\n        \"\"\"\n        accept_encoding = Headers.from_scope(scope).get(\"accept-encoding\", \"\")\n\n        if CompressionEncoding.BROTLI in accept_encoding and self.config.backend == \"brotli\":\n            await self.app(\n                scope,\n                receive,\n                self.create_compression_send_wrapper(\n                    send=send, compression_encoding=CompressionEncoding.BROTLI, scope=scope\n                ),\n            )\n            return\n\n        if CompressionEncoding.GZIP in accept_encoding and (\n            self.config.backend == \"gzip\" or self.config.brotli_gzip_fallback\n        ):\n            await self.app(\n                scope,\n                receive,\n                self.create_compression_send_wrapper(\n                    send=send, compression_encoding=CompressionEncoding.GZIP, scope=scope\n                ),\n            )\n            return\n\n        await self.app(scope, receive, send)\n\n    def create_compression_send_wrapper(\n        self,\n        send: Send,\n        compression_encoding: Literal[CompressionEncoding.BROTLI, CompressionEncoding.GZIP],\n        scope: Scope,\n    ) -> Send:\n        \"\"\"Wrap ``send`` to handle brotli compression.\n\n        Args:\n            send: The ASGI send function.\n            compression_encoding: The compression encoding used.\n            scope: The ASGI connection scope\n\n        Returns:\n            An ASGI send function.\n        \"\"\"\n\n        buffer = BytesIO()\n        facade = CompressionFacade(buffer=buffer, compression_encoding=compression_encoding, config=self.config)\n\n        initial_message = Ref[Optional[\"HTTPResponseStartEvent\"]](None)\n        started = Ref[bool](False)\n\n        async def send_wrapper(message: Message) -> None:\n            \"\"\"Handle and compresses the HTTP Message with brotli.\n\n            Args:\n                message (Message): An ASGI Message.\n            \"\"\"\n\n            if message[\"type\"] == \"http.response.start\":\n                initial_message.value = message\n                return\n\n            if initial_message.value and message[\"type\"] == \"http.response.body\":\n                body = message[\"body\"]\n                more_body = message.get(\"more_body\")\n\n                if not started.value:\n                    started.value = True\n                    if more_body:\n                        headers = MutableScopeHeaders(initial_message.value)\n                        headers[\"Content-Encoding\"] = compression_encoding\n                        headers.extend_header_value(\"vary\", \"Accept-Encoding\")\n                        del headers[\"Content-Length\"]\n                        set_litestar_scope_state(scope, SCOPE_STATE_RESPONSE_COMPRESSED, True)\n\n                        facade.write(body)\n\n                        message[\"body\"] = buffer.getvalue()\n                        buffer.seek(0)\n                        buffer.truncate()\n                        await send(initial_message.value)\n                        await send(message)\n\n                    elif len(body) >= self.config.minimum_size:\n                        facade.write(body)\n                        facade.close()\n                        body = buffer.getvalue()\n\n                        headers = MutableScopeHeaders(initial_message.value)\n                        headers[\"Content-Encoding\"] = compression_encoding\n                        headers[\"Content-Length\"] = str(len(body))\n                        headers.extend_header_value(\"vary\", \"Accept-Encoding\")\n                        message[\"body\"] = body\n                        set_litestar_scope_state(scope, SCOPE_STATE_RESPONSE_COMPRESSED, True)\n\n                        await send(initial_message.value)\n                        await send(message)\n\n                    else:\n                        await send(initial_message.value)\n                        await send(message)\n\n                else:\n                    facade.write(body)\n                    if not more_body:\n                        facade.close()\n\n                    message[\"body\"] = buffer.getvalue()\n\n                    buffer.seek(0)\n                    buffer.truncate()\n\n                    if not more_body:\n                        buffer.close()\n\n                    await send(message)\n\n        return send_wrapper\n", "path": "litestar/middleware/compression.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom gzip import GzipFile\nfrom io import BytesIO\nfrom typing import TYPE_CHECKING, Any, Literal, Optional\n\nfrom litestar.constants import SCOPE_STATE_RESPONSE_COMPRESSED\nfrom litestar.datastructures import Headers, MutableScopeHeaders\nfrom litestar.enums import CompressionEncoding, ScopeType\nfrom litestar.exceptions import MissingDependencyException\nfrom litestar.middleware.base import AbstractMiddleware\nfrom litestar.utils import Ref, set_litestar_scope_state\n\n__all__ = (\"CompressionFacade\", \"CompressionMiddleware\")\n\n\nif TYPE_CHECKING:\n    from litestar.config.compression import CompressionConfig\n    from litestar.types import (\n        ASGIApp,\n        HTTPResponseStartEvent,\n        Message,\n        Receive,\n        Scope,\n        Send,\n    )\n\n    try:\n        from brotli import Compressor\n    except ImportError:\n        Compressor = Any\n\n\nclass CompressionFacade:\n    \"\"\"A unified facade offering a uniform interface for different compression libraries.\"\"\"\n\n    __slots__ = (\"compressor\", \"buffer\", \"compression_encoding\")\n\n    compressor: GzipFile | Compressor  # pyright: ignore\n\n    def __init__(self, buffer: BytesIO, compression_encoding: CompressionEncoding, config: CompressionConfig) -> None:\n        \"\"\"Initialize ``CompressionFacade``.\n\n        Args:\n            buffer: A bytes IO buffer to write the compressed data into.\n            compression_encoding: The compression encoding used.\n            config: The app compression config.\n        \"\"\"\n        self.buffer = buffer\n        self.compression_encoding = compression_encoding\n\n        if compression_encoding == CompressionEncoding.BROTLI:\n            try:\n                import brotli  # noqa: F401\n            except ImportError as e:\n                raise MissingDependencyException(\"brotli\") from e\n\n            from brotli import MODE_FONT, MODE_GENERIC, MODE_TEXT, Compressor\n\n            modes: dict[Literal[\"generic\", \"text\", \"font\"], int] = {\n                \"text\": int(MODE_TEXT),\n                \"font\": int(MODE_FONT),\n                \"generic\": int(MODE_GENERIC),\n            }\n            self.compressor = Compressor(\n                quality=config.brotli_quality,\n                mode=modes[config.brotli_mode],\n                lgwin=config.brotli_lgwin,\n                lgblock=config.brotli_lgblock,\n            )\n        else:\n            self.compressor = GzipFile(mode=\"wb\", fileobj=buffer, compresslevel=config.gzip_compress_level)\n\n    def write(self, body: bytes) -> None:\n        \"\"\"Write compressed bytes.\n\n        Args:\n            body: Message body to process\n\n        Returns:\n            None\n        \"\"\"\n\n        if self.compression_encoding == CompressionEncoding.BROTLI:\n            self.buffer.write(self.compressor.process(body) + self.compressor.flush())  # type: ignore\n        else:\n            self.compressor.write(body)\n            self.compressor.flush()\n\n    def close(self) -> None:\n        \"\"\"Close the compression stream.\n\n        Returns:\n            None\n        \"\"\"\n        if self.compression_encoding == CompressionEncoding.BROTLI:\n            self.buffer.write(self.compressor.finish())  # type: ignore\n        else:\n            self.compressor.close()\n\n\nclass CompressionMiddleware(AbstractMiddleware):\n    \"\"\"Compression Middleware Wrapper.\n\n    This is a wrapper allowing for generic compression configuration / handler middleware\n    \"\"\"\n\n    def __init__(self, app: ASGIApp, config: CompressionConfig) -> None:\n        \"\"\"Initialize ``CompressionMiddleware``\n\n        Args:\n            app: The ``next`` ASGI app to call.\n            config: An instance of CompressionConfig.\n        \"\"\"\n        super().__init__(\n            app=app, exclude=config.exclude, exclude_opt_key=config.exclude_opt_key, scopes={ScopeType.HTTP}\n        )\n        self.config = config\n\n    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        \"\"\"ASGI callable.\n\n        Args:\n            scope: The ASGI connection scope.\n            receive: The ASGI receive function.\n            send: The ASGI send function.\n\n        Returns:\n            None\n        \"\"\"\n        accept_encoding = Headers.from_scope(scope).get(\"accept-encoding\", \"\")\n\n        if CompressionEncoding.BROTLI in accept_encoding and self.config.backend == \"brotli\":\n            await self.app(\n                scope,\n                receive,\n                self.create_compression_send_wrapper(\n                    send=send, compression_encoding=CompressionEncoding.BROTLI, scope=scope\n                ),\n            )\n            return\n\n        if CompressionEncoding.GZIP in accept_encoding and (\n            self.config.backend == \"gzip\" or self.config.brotli_gzip_fallback\n        ):\n            await self.app(\n                scope,\n                receive,\n                self.create_compression_send_wrapper(\n                    send=send, compression_encoding=CompressionEncoding.GZIP, scope=scope\n                ),\n            )\n            return\n\n        await self.app(scope, receive, send)\n\n    def create_compression_send_wrapper(\n        self,\n        send: Send,\n        compression_encoding: Literal[CompressionEncoding.BROTLI, CompressionEncoding.GZIP],\n        scope: Scope,\n    ) -> Send:\n        \"\"\"Wrap ``send`` to handle brotli compression.\n\n        Args:\n            send: The ASGI send function.\n            compression_encoding: The compression encoding used.\n            scope: The ASGI connection scope\n\n        Returns:\n            An ASGI send function.\n        \"\"\"\n\n        buffer = BytesIO()\n        facade = CompressionFacade(buffer=buffer, compression_encoding=compression_encoding, config=self.config)\n\n        initial_message = Ref[Optional[\"HTTPResponseStartEvent\"]](None)\n        started = Ref[bool](False)\n\n        async def send_wrapper(message: Message) -> None:\n            \"\"\"Handle and compresses the HTTP Message with brotli.\n\n            Args:\n                message (Message): An ASGI Message.\n            \"\"\"\n\n            if message[\"type\"] == \"http.response.start\":\n                initial_message.value = message\n                return\n\n            if initial_message.value and message[\"type\"] == \"http.response.body\":\n                body = message[\"body\"]\n                more_body = message.get(\"more_body\")\n\n                if not started.value:\n                    started.value = True\n                    if more_body:\n                        headers = MutableScopeHeaders(initial_message.value)\n                        headers[\"Content-Encoding\"] = compression_encoding\n                        headers.extend_header_value(\"vary\", \"Accept-Encoding\")\n                        del headers[\"Content-Length\"]\n                        set_litestar_scope_state(scope, SCOPE_STATE_RESPONSE_COMPRESSED, True)\n\n                        facade.write(body)\n\n                        message[\"body\"] = buffer.getvalue()\n                        buffer.seek(0)\n                        buffer.truncate()\n                        await send(initial_message.value)\n                        await send(message)\n\n                    elif len(body) >= self.config.minimum_size:\n                        facade.write(body)\n                        facade.close()\n                        body = buffer.getvalue()\n\n                        headers = MutableScopeHeaders(initial_message.value)\n                        headers[\"Content-Encoding\"] = compression_encoding\n                        headers[\"Content-Length\"] = str(len(body))\n                        headers.extend_header_value(\"vary\", \"Accept-Encoding\")\n                        message[\"body\"] = body\n                        set_litestar_scope_state(scope, SCOPE_STATE_RESPONSE_COMPRESSED, True)\n\n                        await send(initial_message.value)\n                        await send(message)\n\n                    else:\n                        await send(initial_message.value)\n                        await send(message)\n\n                else:\n                    facade.write(body)\n                    if not more_body:\n                        facade.close()\n\n                    message[\"body\"] = buffer.getvalue()\n\n                    buffer.seek(0)\n                    buffer.truncate()\n\n                    if not more_body:\n                        buffer.close()\n\n                    await send(message)\n\n        return send_wrapper\n", "path": "litestar/middleware/compression.py"}]}