We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: `FileResponse` doesn't set `content-encoding` headers on gzip/brotli compressed files
### Description

When using `StaticFilesConfig` to serve compressed files (think `styles.css.gz`), Litestar will happily serve the file and even properly infer the mimetype, but won't set the correct `content-encoding` header required by the browser.

I will provide a PR with a test.

### URL to code causing the issue

_No response_

### MCVE

_No response_

### Steps to reproduce

_No response_

### Screenshots

```bash
"![SCREENSHOT_DESCRIPTION](SCREENSHOT_LINK.png)"
```


### Logs

_No response_

### Litestar Version

1.51.10

### 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: `starlite/response/file.py`
Content:
```
1 from email.utils import formatdate
2 from inspect import iscoroutine
3 from mimetypes import guess_type
4 from typing import (
5     TYPE_CHECKING,
6     Any,
7     AsyncGenerator,
8     Coroutine,
9     Dict,
10     Literal,
11     Optional,
12     Union,
13     cast,
14 )
15 from urllib.parse import quote
16 from zlib import adler32
17 
18 from starlite.constants import ONE_MEGABYTE
19 from starlite.enums import MediaType
20 from starlite.exceptions import ImproperlyConfiguredException
21 from starlite.response.streaming import StreamingResponse
22 from starlite.status_codes import HTTP_200_OK
23 from starlite.utils.file import BaseLocalFileSystem, FileSystemAdapter
24 
25 if TYPE_CHECKING:
26     from os import PathLike
27     from os import stat_result as stat_result_type
28 
29     from anyio import Path
30 
31     from starlite.datastructures import BackgroundTask, BackgroundTasks, ETag
32     from starlite.types import (
33         HTTPResponseBodyEvent,
34         PathType,
35         Receive,
36         ResponseCookies,
37         Send,
38     )
39     from starlite.types.file_types import FileInfo, FileSystemProtocol
40 
41 
42 async def async_file_iterator(
43     file_path: "PathType", chunk_size: int, adapter: "FileSystemAdapter"
44 ) -> AsyncGenerator[bytes, None]:
45     """Return an async that asynchronously reads a file and yields its chunks.
46 
47     Args:
48         file_path: A path to a file.
49         chunk_size: The chunk file to use.
50         adapter: File system adapter class.
51         adapter: File system adapter class.
52 
53     Returns:
54         An async generator.
55     """
56     async with await adapter.open(file_path) as file:
57         while chunk := await file.read(chunk_size):
58             yield chunk
59 
60 
61 def create_etag_for_file(path: "PathType", modified_time: float, file_size: int) -> str:
62     """Create an etag.
63 
64     Notes:
65         - Function is derived from flask.
66 
67     Returns:
68         An etag.
69     """
70     check = adler32(str(path).encode("utf-8")) & 0xFFFFFFFF
71     return f'"{modified_time}-{file_size}-{check}"'
72 
73 
74 class FileResponse(StreamingResponse):
75     """A response, streaming a file as response body."""
76 
77     __slots__ = (
78         "chunk_size",
79         "content_disposition_type",
80         "etag",
81         "file_path",
82         "filename",
83         "adapter",
84         "file_info",
85     )
86 
87     def __init__(
88         self,
89         path: Union[str, "PathLike", "Path"],
90         *,
91         background: Optional[Union["BackgroundTask", "BackgroundTasks"]] = None,
92         chunk_size: int = ONE_MEGABYTE,
93         content_disposition_type: Literal["attachment", "inline"] = "attachment",
94         cookies: Optional["ResponseCookies"] = None,
95         encoding: str = "utf-8",
96         etag: Optional["ETag"] = None,
97         file_system: Optional["FileSystemProtocol"] = None,
98         filename: Optional[str] = None,
99         file_info: Optional["FileInfo"] = None,
100         headers: Optional[Dict[str, Any]] = None,
101         is_head_response: bool = False,
102         media_type: Optional[Union[Literal[MediaType.TEXT], str]] = None,
103         stat_result: Optional["stat_result_type"] = None,
104         status_code: int = HTTP_200_OK,
105     ) -> None:
106         """Initialize ``FileResponse``
107 
108         Notes:
109             - This class extends the :class:`StreamingResponse <starlite.response.StreamingResponse>` class.
110 
111         Args:
112             path: A file path in one of the supported formats.
113             status_code: An HTTP status code.
114             media_type: A value for the response 'Content-Type' header. If not provided, the value will be either
115                 derived from the filename if provided and supported by the stdlib, or will default to
116                 'application/octet-stream'.
117             background: A :class:`BackgroundTask <starlite.datastructures.BackgroundTask>` instance or
118                 :class:`BackgroundTasks <starlite.datastructures.BackgroundTasks>` to execute after the response is finished.
119                 Defaults to None.
120             headers: A string keyed dictionary of response headers. Header keys are insensitive.
121             cookies: A list of :class:`Cookie <starlite.datastructures.Cookie>` instances to be set under the response 'Set-Cookie' header.
122             encoding: The encoding to be used for the response headers.
123             is_head_response: Whether the response should send only the headers ("head" request) or also the content.
124             filename: An optional filename to set in the header.
125             stat_result: An optional result of calling 'os.stat'. If not provided, this will be done by the response
126                 constructor.
127             chunk_size: The chunk sizes to use when streaming the file. Defaults to 1MB.
128             content_disposition_type: The type of the 'Content-Disposition'. Either ``inline`` or ``attachment``.
129             etag: An optional :class:`ETag <starlite.datastructures.ETag>` instance.
130                 If not provided, an etag will be automatically generated.
131             file_system: An implementation of the :class:`FileSystemProtocol <starlite.types.FileSystemProtocol>`. If provided
132                 it will be used to load the file.
133             file_info: The output of calling ``file_system.info(..)``, equivalent to providing a ``stat_result``.
134         """
135         if not media_type:
136             mimetype, _ = guess_type(filename) if filename else (None, None)
137             media_type = mimetype or "application/octet-stream"
138 
139         self.chunk_size = chunk_size
140         self.content_disposition_type = content_disposition_type
141         self.etag = etag
142         self.file_path = path
143         self.filename = filename or ""
144         self.adapter = FileSystemAdapter(file_system or BaseLocalFileSystem())
145 
146         super().__init__(
147             content=async_file_iterator(file_path=path, chunk_size=chunk_size, adapter=self.adapter),
148             status_code=status_code,
149             media_type=media_type,
150             background=background,
151             headers=headers,
152             cookies=cookies,
153             encoding=encoding,
154             is_head_response=is_head_response,
155         )
156 
157         if file_info:
158             self.file_info: Union["FileInfo", "Coroutine[Any, Any, 'FileInfo']"] = file_info
159         elif stat_result:
160             self.file_info = self.adapter.parse_stat_result(result=stat_result, path=path)
161         else:
162             self.file_info = self.adapter.info(self.file_path)
163 
164     @property
165     def content_disposition(self) -> str:
166         """Content disposition.
167 
168         Returns:
169             A value for the 'Content-Disposition' header.
170         """
171         quoted_filename = quote(self.filename)
172         is_utf8 = quoted_filename == self.filename
173         if is_utf8:
174             return f'{self.content_disposition_type}; filename="{self.filename}"'
175         return f"{self.content_disposition_type}; filename*=utf-8''{quoted_filename}"
176 
177     @property
178     def content_length(self) -> int:
179         """Content length of the response if applicable.
180 
181         Returns:
182             Returns the value of 'self.stat_result.st_size' to populate the 'Content-Length' header.
183         """
184         if isinstance(self.file_info, dict):
185             return self.file_info["size"]
186         return 0
187 
188     async def send_body(self, send: "Send", receive: "Receive") -> None:
189         """Emit a stream of events correlating with the response body.
190 
191         Args:
192             send: The ASGI send function.
193             receive: The ASGI receive function.
194 
195         Returns:
196             None
197         """
198         if self.chunk_size < self.content_length:
199             await super().send_body(send=send, receive=receive)
200             return
201 
202         async with await self.adapter.open(self.file_path) as file:
203             body_event: "HTTPResponseBodyEvent" = {
204                 "type": "http.response.body",
205                 "body": await file.read(),
206                 "more_body": False,
207             }
208             await send(body_event)
209 
210     async def start_response(self, send: "Send") -> None:
211         """Emit the start event of the response. This event includes the headers and status codes.
212 
213         Args:
214             send: The ASGI send function.
215 
216         Returns:
217             None
218         """
219         try:
220             fs_info = self.file_info = cast(
221                 "FileInfo", (await self.file_info if iscoroutine(self.file_info) else self.file_info)
222             )
223         except FileNotFoundError as e:
224             raise ImproperlyConfiguredException(f"{self.file_path} does not exist") from e
225 
226         if fs_info["type"] != "file":
227             raise ImproperlyConfiguredException(f"{self.file_path} is not a file")
228 
229         self.set_header("last-modified", formatdate(fs_info["mtime"], usegmt=True))
230         self.set_header("content-disposition", self.content_disposition)
231         self.set_etag(
232             self.etag
233             or create_etag_for_file(path=self.file_path, modified_time=fs_info["mtime"], file_size=fs_info["size"])
234         )
235 
236         await super().start_response(send=send)
237
```
--- 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/starlite/response/file.py b/starlite/response/file.py
--- a/starlite/response/file.py
+++ b/starlite/response/file.py
@@ -1,6 +1,6 @@
 from email.utils import formatdate
 from inspect import iscoroutine
-from mimetypes import guess_type
+from mimetypes import encodings_map, guess_type
 from typing import (
     TYPE_CHECKING,
     Any,
@@ -38,6 +38,9 @@
     )
     from starlite.types.file_types import FileInfo, FileSystemProtocol
 
+# brotli not supported in 'mimetypes.encodings_map' until py 3.9.
+encodings_map[".br"] = "br"
+
 
 async def async_file_iterator(
     file_path: "PathType", chunk_size: int, adapter: "FileSystemAdapter"
@@ -133,8 +136,11 @@
             file_info: The output of calling ``file_system.info(..)``, equivalent to providing a ``stat_result``.
         """
         if not media_type:
-            mimetype, _ = guess_type(filename) if filename else (None, None)
+            mimetype, content_encoding = guess_type(filename) if filename else (None, None)
             media_type = mimetype or "application/octet-stream"
+            if content_encoding is not None:
+                headers = headers or {}
+                headers.update({"content-encoding": content_encoding})
 
         self.chunk_size = chunk_size
         self.content_disposition_type = content_disposition_type

{"golden_diff": "diff --git a/starlite/response/file.py b/starlite/response/file.py\n--- a/starlite/response/file.py\n+++ b/starlite/response/file.py\n@@ -1,6 +1,6 @@\n from email.utils import formatdate\n from inspect import iscoroutine\n-from mimetypes import guess_type\n+from mimetypes import encodings_map, guess_type\n from typing import (\n     TYPE_CHECKING,\n     Any,\n@@ -38,6 +38,9 @@\n     )\n     from starlite.types.file_types import FileInfo, FileSystemProtocol\n \n+# brotli not supported in 'mimetypes.encodings_map' until py 3.9.\n+encodings_map[\".br\"] = \"br\"\n+\n \n async def async_file_iterator(\n     file_path: \"PathType\", chunk_size: int, adapter: \"FileSystemAdapter\"\n@@ -133,8 +136,11 @@\n             file_info: The output of calling ``file_system.info(..)``, equivalent to providing a ``stat_result``.\n         \"\"\"\n         if not media_type:\n-            mimetype, _ = guess_type(filename) if filename else (None, None)\n+            mimetype, content_encoding = guess_type(filename) if filename else (None, None)\n             media_type = mimetype or \"application/octet-stream\"\n+            if content_encoding is not None:\n+                headers = headers or {}\n+                headers.update({\"content-encoding\": content_encoding})\n \n         self.chunk_size = chunk_size\n         self.content_disposition_type = content_disposition_type\n", "issue": "Bug: `FileResponse` doesn't set `content-encoding` headers on gzip/brotli compressed files\n### Description\n\nWhen using `StaticFilesConfig` to serve compressed files (think `styles.css.gz`), Litestar will happily serve the file and even properly infer the mimetype, but won't set the correct `content-encoding` header required by the browser.\r\n\r\nI will provide a PR with a test.\n\n### URL to code causing the issue\n\n_No response_\n\n### MCVE\n\n_No response_\n\n### Steps to reproduce\n\n_No response_\n\n### Screenshots\n\n```bash\n\"![SCREENSHOT_DESCRIPTION](SCREENSHOT_LINK.png)\"\n```\n\n\n### Logs\n\n_No response_\n\n### Litestar Version\n\n1.51.10\n\n### Platform\n\n- [X] Linux\n- [ ] Mac\n- [ ] Windows\n- [ ] Other (Please specify in the description above)\n", "before_files": [{"content": "from email.utils import formatdate\nfrom inspect import iscoroutine\nfrom mimetypes import guess_type\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    AsyncGenerator,\n    Coroutine,\n    Dict,\n    Literal,\n    Optional,\n    Union,\n    cast,\n)\nfrom urllib.parse import quote\nfrom zlib import adler32\n\nfrom starlite.constants import ONE_MEGABYTE\nfrom starlite.enums import MediaType\nfrom starlite.exceptions import ImproperlyConfiguredException\nfrom starlite.response.streaming import StreamingResponse\nfrom starlite.status_codes import HTTP_200_OK\nfrom starlite.utils.file import BaseLocalFileSystem, FileSystemAdapter\n\nif TYPE_CHECKING:\n    from os import PathLike\n    from os import stat_result as stat_result_type\n\n    from anyio import Path\n\n    from starlite.datastructures import BackgroundTask, BackgroundTasks, ETag\n    from starlite.types import (\n        HTTPResponseBodyEvent,\n        PathType,\n        Receive,\n        ResponseCookies,\n        Send,\n    )\n    from starlite.types.file_types import FileInfo, FileSystemProtocol\n\n\nasync def async_file_iterator(\n    file_path: \"PathType\", chunk_size: int, adapter: \"FileSystemAdapter\"\n) -> AsyncGenerator[bytes, None]:\n    \"\"\"Return an async that asynchronously reads a file and yields its chunks.\n\n    Args:\n        file_path: A path to a file.\n        chunk_size: The chunk file to use.\n        adapter: File system adapter class.\n        adapter: File system adapter class.\n\n    Returns:\n        An async generator.\n    \"\"\"\n    async with await adapter.open(file_path) as file:\n        while chunk := await file.read(chunk_size):\n            yield chunk\n\n\ndef create_etag_for_file(path: \"PathType\", modified_time: float, file_size: int) -> str:\n    \"\"\"Create an etag.\n\n    Notes:\n        - Function is derived from flask.\n\n    Returns:\n        An etag.\n    \"\"\"\n    check = adler32(str(path).encode(\"utf-8\")) & 0xFFFFFFFF\n    return f'\"{modified_time}-{file_size}-{check}\"'\n\n\nclass FileResponse(StreamingResponse):\n    \"\"\"A response, streaming a file as response body.\"\"\"\n\n    __slots__ = (\n        \"chunk_size\",\n        \"content_disposition_type\",\n        \"etag\",\n        \"file_path\",\n        \"filename\",\n        \"adapter\",\n        \"file_info\",\n    )\n\n    def __init__(\n        self,\n        path: Union[str, \"PathLike\", \"Path\"],\n        *,\n        background: Optional[Union[\"BackgroundTask\", \"BackgroundTasks\"]] = None,\n        chunk_size: int = ONE_MEGABYTE,\n        content_disposition_type: Literal[\"attachment\", \"inline\"] = \"attachment\",\n        cookies: Optional[\"ResponseCookies\"] = None,\n        encoding: str = \"utf-8\",\n        etag: Optional[\"ETag\"] = None,\n        file_system: Optional[\"FileSystemProtocol\"] = None,\n        filename: Optional[str] = None,\n        file_info: Optional[\"FileInfo\"] = None,\n        headers: Optional[Dict[str, Any]] = None,\n        is_head_response: bool = False,\n        media_type: Optional[Union[Literal[MediaType.TEXT], str]] = None,\n        stat_result: Optional[\"stat_result_type\"] = None,\n        status_code: int = HTTP_200_OK,\n    ) -> None:\n        \"\"\"Initialize ``FileResponse``\n\n        Notes:\n            - This class extends the :class:`StreamingResponse <starlite.response.StreamingResponse>` class.\n\n        Args:\n            path: A file path in one of the supported formats.\n            status_code: An HTTP status code.\n            media_type: A value for the response 'Content-Type' header. If not provided, the value will be either\n                derived from the filename if provided and supported by the stdlib, or will default to\n                'application/octet-stream'.\n            background: A :class:`BackgroundTask <starlite.datastructures.BackgroundTask>` instance or\n                :class:`BackgroundTasks <starlite.datastructures.BackgroundTasks>` to execute after the response is finished.\n                Defaults to None.\n            headers: A string keyed dictionary of response headers. Header keys are insensitive.\n            cookies: A list of :class:`Cookie <starlite.datastructures.Cookie>` instances to be set under the response 'Set-Cookie' header.\n            encoding: The encoding to be used for the response headers.\n            is_head_response: Whether the response should send only the headers (\"head\" request) or also the content.\n            filename: An optional filename to set in the header.\n            stat_result: An optional result of calling 'os.stat'. If not provided, this will be done by the response\n                constructor.\n            chunk_size: The chunk sizes to use when streaming the file. Defaults to 1MB.\n            content_disposition_type: The type of the 'Content-Disposition'. Either ``inline`` or ``attachment``.\n            etag: An optional :class:`ETag <starlite.datastructures.ETag>` instance.\n                If not provided, an etag will be automatically generated.\n            file_system: An implementation of the :class:`FileSystemProtocol <starlite.types.FileSystemProtocol>`. If provided\n                it will be used to load the file.\n            file_info: The output of calling ``file_system.info(..)``, equivalent to providing a ``stat_result``.\n        \"\"\"\n        if not media_type:\n            mimetype, _ = guess_type(filename) if filename else (None, None)\n            media_type = mimetype or \"application/octet-stream\"\n\n        self.chunk_size = chunk_size\n        self.content_disposition_type = content_disposition_type\n        self.etag = etag\n        self.file_path = path\n        self.filename = filename or \"\"\n        self.adapter = FileSystemAdapter(file_system or BaseLocalFileSystem())\n\n        super().__init__(\n            content=async_file_iterator(file_path=path, chunk_size=chunk_size, adapter=self.adapter),\n            status_code=status_code,\n            media_type=media_type,\n            background=background,\n            headers=headers,\n            cookies=cookies,\n            encoding=encoding,\n            is_head_response=is_head_response,\n        )\n\n        if file_info:\n            self.file_info: Union[\"FileInfo\", \"Coroutine[Any, Any, 'FileInfo']\"] = file_info\n        elif stat_result:\n            self.file_info = self.adapter.parse_stat_result(result=stat_result, path=path)\n        else:\n            self.file_info = self.adapter.info(self.file_path)\n\n    @property\n    def content_disposition(self) -> str:\n        \"\"\"Content disposition.\n\n        Returns:\n            A value for the 'Content-Disposition' header.\n        \"\"\"\n        quoted_filename = quote(self.filename)\n        is_utf8 = quoted_filename == self.filename\n        if is_utf8:\n            return f'{self.content_disposition_type}; filename=\"{self.filename}\"'\n        return f\"{self.content_disposition_type}; filename*=utf-8''{quoted_filename}\"\n\n    @property\n    def content_length(self) -> int:\n        \"\"\"Content length of the response if applicable.\n\n        Returns:\n            Returns the value of 'self.stat_result.st_size' to populate the 'Content-Length' header.\n        \"\"\"\n        if isinstance(self.file_info, dict):\n            return self.file_info[\"size\"]\n        return 0\n\n    async def send_body(self, send: \"Send\", receive: \"Receive\") -> None:\n        \"\"\"Emit a stream of events correlating with the response body.\n\n        Args:\n            send: The ASGI send function.\n            receive: The ASGI receive function.\n\n        Returns:\n            None\n        \"\"\"\n        if self.chunk_size < self.content_length:\n            await super().send_body(send=send, receive=receive)\n            return\n\n        async with await self.adapter.open(self.file_path) as file:\n            body_event: \"HTTPResponseBodyEvent\" = {\n                \"type\": \"http.response.body\",\n                \"body\": await file.read(),\n                \"more_body\": False,\n            }\n            await send(body_event)\n\n    async def start_response(self, send: \"Send\") -> None:\n        \"\"\"Emit the start event of the response. This event includes the headers and status codes.\n\n        Args:\n            send: The ASGI send function.\n\n        Returns:\n            None\n        \"\"\"\n        try:\n            fs_info = self.file_info = cast(\n                \"FileInfo\", (await self.file_info if iscoroutine(self.file_info) else self.file_info)\n            )\n        except FileNotFoundError as e:\n            raise ImproperlyConfiguredException(f\"{self.file_path} does not exist\") from e\n\n        if fs_info[\"type\"] != \"file\":\n            raise ImproperlyConfiguredException(f\"{self.file_path} is not a file\")\n\n        self.set_header(\"last-modified\", formatdate(fs_info[\"mtime\"], usegmt=True))\n        self.set_header(\"content-disposition\", self.content_disposition)\n        self.set_etag(\n            self.etag\n            or create_etag_for_file(path=self.file_path, modified_time=fs_info[\"mtime\"], file_size=fs_info[\"size\"])\n        )\n\n        await super().start_response(send=send)\n", "path": "starlite/response/file.py"}], "after_files": [{"content": "from email.utils import formatdate\nfrom inspect import iscoroutine\nfrom mimetypes import encodings_map, guess_type\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    AsyncGenerator,\n    Coroutine,\n    Dict,\n    Literal,\n    Optional,\n    Union,\n    cast,\n)\nfrom urllib.parse import quote\nfrom zlib import adler32\n\nfrom starlite.constants import ONE_MEGABYTE\nfrom starlite.enums import MediaType\nfrom starlite.exceptions import ImproperlyConfiguredException\nfrom starlite.response.streaming import StreamingResponse\nfrom starlite.status_codes import HTTP_200_OK\nfrom starlite.utils.file import BaseLocalFileSystem, FileSystemAdapter\n\nif TYPE_CHECKING:\n    from os import PathLike\n    from os import stat_result as stat_result_type\n\n    from anyio import Path\n\n    from starlite.datastructures import BackgroundTask, BackgroundTasks, ETag\n    from starlite.types import (\n        HTTPResponseBodyEvent,\n        PathType,\n        Receive,\n        ResponseCookies,\n        Send,\n    )\n    from starlite.types.file_types import FileInfo, FileSystemProtocol\n\n# brotli not supported in 'mimetypes.encodings_map' until py 3.9.\nencodings_map[\".br\"] = \"br\"\n\n\nasync def async_file_iterator(\n    file_path: \"PathType\", chunk_size: int, adapter: \"FileSystemAdapter\"\n) -> AsyncGenerator[bytes, None]:\n    \"\"\"Return an async that asynchronously reads a file and yields its chunks.\n\n    Args:\n        file_path: A path to a file.\n        chunk_size: The chunk file to use.\n        adapter: File system adapter class.\n        adapter: File system adapter class.\n\n    Returns:\n        An async generator.\n    \"\"\"\n    async with await adapter.open(file_path) as file:\n        while chunk := await file.read(chunk_size):\n            yield chunk\n\n\ndef create_etag_for_file(path: \"PathType\", modified_time: float, file_size: int) -> str:\n    \"\"\"Create an etag.\n\n    Notes:\n        - Function is derived from flask.\n\n    Returns:\n        An etag.\n    \"\"\"\n    check = adler32(str(path).encode(\"utf-8\")) & 0xFFFFFFFF\n    return f'\"{modified_time}-{file_size}-{check}\"'\n\n\nclass FileResponse(StreamingResponse):\n    \"\"\"A response, streaming a file as response body.\"\"\"\n\n    __slots__ = (\n        \"chunk_size\",\n        \"content_disposition_type\",\n        \"etag\",\n        \"file_path\",\n        \"filename\",\n        \"adapter\",\n        \"file_info\",\n    )\n\n    def __init__(\n        self,\n        path: Union[str, \"PathLike\", \"Path\"],\n        *,\n        background: Optional[Union[\"BackgroundTask\", \"BackgroundTasks\"]] = None,\n        chunk_size: int = ONE_MEGABYTE,\n        content_disposition_type: Literal[\"attachment\", \"inline\"] = \"attachment\",\n        cookies: Optional[\"ResponseCookies\"] = None,\n        encoding: str = \"utf-8\",\n        etag: Optional[\"ETag\"] = None,\n        file_system: Optional[\"FileSystemProtocol\"] = None,\n        filename: Optional[str] = None,\n        file_info: Optional[\"FileInfo\"] = None,\n        headers: Optional[Dict[str, Any]] = None,\n        is_head_response: bool = False,\n        media_type: Optional[Union[Literal[MediaType.TEXT], str]] = None,\n        stat_result: Optional[\"stat_result_type\"] = None,\n        status_code: int = HTTP_200_OK,\n    ) -> None:\n        \"\"\"Initialize ``FileResponse``\n\n        Notes:\n            - This class extends the :class:`StreamingResponse <starlite.response.StreamingResponse>` class.\n\n        Args:\n            path: A file path in one of the supported formats.\n            status_code: An HTTP status code.\n            media_type: A value for the response 'Content-Type' header. If not provided, the value will be either\n                derived from the filename if provided and supported by the stdlib, or will default to\n                'application/octet-stream'.\n            background: A :class:`BackgroundTask <starlite.datastructures.BackgroundTask>` instance or\n                :class:`BackgroundTasks <starlite.datastructures.BackgroundTasks>` to execute after the response is finished.\n                Defaults to None.\n            headers: A string keyed dictionary of response headers. Header keys are insensitive.\n            cookies: A list of :class:`Cookie <starlite.datastructures.Cookie>` instances to be set under the response 'Set-Cookie' header.\n            encoding: The encoding to be used for the response headers.\n            is_head_response: Whether the response should send only the headers (\"head\" request) or also the content.\n            filename: An optional filename to set in the header.\n            stat_result: An optional result of calling 'os.stat'. If not provided, this will be done by the response\n                constructor.\n            chunk_size: The chunk sizes to use when streaming the file. Defaults to 1MB.\n            content_disposition_type: The type of the 'Content-Disposition'. Either ``inline`` or ``attachment``.\n            etag: An optional :class:`ETag <starlite.datastructures.ETag>` instance.\n                If not provided, an etag will be automatically generated.\n            file_system: An implementation of the :class:`FileSystemProtocol <starlite.types.FileSystemProtocol>`. If provided\n                it will be used to load the file.\n            file_info: The output of calling ``file_system.info(..)``, equivalent to providing a ``stat_result``.\n        \"\"\"\n        if not media_type:\n            mimetype, content_encoding = guess_type(filename) if filename else (None, None)\n            media_type = mimetype or \"application/octet-stream\"\n            if content_encoding is not None:\n                headers = headers or {}\n                headers.update({\"content-encoding\": content_encoding})\n\n        self.chunk_size = chunk_size\n        self.content_disposition_type = content_disposition_type\n        self.etag = etag\n        self.file_path = path\n        self.filename = filename or \"\"\n        self.adapter = FileSystemAdapter(file_system or BaseLocalFileSystem())\n\n        super().__init__(\n            content=async_file_iterator(file_path=path, chunk_size=chunk_size, adapter=self.adapter),\n            status_code=status_code,\n            media_type=media_type,\n            background=background,\n            headers=headers,\n            cookies=cookies,\n            encoding=encoding,\n            is_head_response=is_head_response,\n        )\n\n        if file_info:\n            self.file_info: Union[\"FileInfo\", \"Coroutine[Any, Any, 'FileInfo']\"] = file_info\n        elif stat_result:\n            self.file_info = self.adapter.parse_stat_result(result=stat_result, path=path)\n        else:\n            self.file_info = self.adapter.info(self.file_path)\n\n    @property\n    def content_disposition(self) -> str:\n        \"\"\"Content disposition.\n\n        Returns:\n            A value for the 'Content-Disposition' header.\n        \"\"\"\n        quoted_filename = quote(self.filename)\n        is_utf8 = quoted_filename == self.filename\n        if is_utf8:\n            return f'{self.content_disposition_type}; filename=\"{self.filename}\"'\n        return f\"{self.content_disposition_type}; filename*=utf-8''{quoted_filename}\"\n\n    @property\n    def content_length(self) -> int:\n        \"\"\"Content length of the response if applicable.\n\n        Returns:\n            Returns the value of 'self.stat_result.st_size' to populate the 'Content-Length' header.\n        \"\"\"\n        if isinstance(self.file_info, dict):\n            return self.file_info[\"size\"]\n        return 0\n\n    async def send_body(self, send: \"Send\", receive: \"Receive\") -> None:\n        \"\"\"Emit a stream of events correlating with the response body.\n\n        Args:\n            send: The ASGI send function.\n            receive: The ASGI receive function.\n\n        Returns:\n            None\n        \"\"\"\n        if self.chunk_size < self.content_length:\n            await super().send_body(send=send, receive=receive)\n            return\n\n        async with await self.adapter.open(self.file_path) as file:\n            body_event: \"HTTPResponseBodyEvent\" = {\n                \"type\": \"http.response.body\",\n                \"body\": await file.read(),\n                \"more_body\": False,\n            }\n            await send(body_event)\n\n    async def start_response(self, send: \"Send\") -> None:\n        \"\"\"Emit the start event of the response. This event includes the headers and status codes.\n\n        Args:\n            send: The ASGI send function.\n\n        Returns:\n            None\n        \"\"\"\n        try:\n            fs_info = self.file_info = cast(\n                \"FileInfo\", (await self.file_info if iscoroutine(self.file_info) else self.file_info)\n            )\n        except FileNotFoundError as e:\n            raise ImproperlyConfiguredException(f\"{self.file_path} does not exist\") from e\n\n        if fs_info[\"type\"] != \"file\":\n            raise ImproperlyConfiguredException(f\"{self.file_path} is not a file\")\n\n        self.set_header(\"last-modified\", formatdate(fs_info[\"mtime\"], usegmt=True))\n        self.set_header(\"content-disposition\", self.content_disposition)\n        self.set_etag(\n            self.etag\n            or create_etag_for_file(path=self.file_path, modified_time=fs_info[\"mtime\"], file_size=fs_info[\"size\"])\n        )\n\n        await super().start_response(send=send)\n", "path": "starlite/response/file.py"}]}