We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: Header values should not be lowercased
**Describe the bug**
Headers keys and values are lowercased before being rendered. While lowercasing key is fine (as per HTTP2 spec), lowercasing values should not be done.

For my use case, integrating with a payment provider involves passing a transaction ID as a header. This ID contains lowercase, uppercase letters, and is not case-insensitive.

**To Reproduce**
1. Create a new route_handler.
2. In the route_handler, modify the response: `response.headers["Foo"] = "Bar"` .
3. Observe that the key and value are returned as lowercase:

![2022-10-27_16-23](https://user-images.githubusercontent.com/546693/198312809-fc5b8947-be88-4354-b909-033270ae188f.png)

4. While reporting this, I noticed that `date` and `vary` headers are not lowercased.

**Additional context**
Looking at the Git history, it seems that originally Starlette was used for handling the responses. I thought that Starlette might also have this behaviour, but they do not lowercase the header values. See https://github.com/encode/starlette/blob/fa737beb2838f568fe2477e2316a7fdf3d3eb257/starlette/responses.py#L72 .

The relevant code in Starlite is here: https://github.com/starlite-api/starlite/blob/95379f102be249f3c9453fbf9d216a41eede2d6f/starlite/response/base.py#L257


--- 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/base.py`
Content:
```
1 from typing import (
2     TYPE_CHECKING,
3     Any,
4     Dict,
5     Generic,
6     List,
7     Optional,
8     Tuple,
9     TypeVar,
10     Union,
11     cast,
12 )
13 
14 from orjson import OPT_INDENT_2, OPT_OMIT_MICROSECONDS, OPT_SERIALIZE_NUMPY, dumps
15 from pydantic_openapi_schema.v3_1_0 import OpenAPI
16 from yaml import dump as dump_yaml
17 
18 from starlite.datastructures import Cookie, ETag
19 from starlite.enums import MediaType, OpenAPIMediaType
20 from starlite.exceptions import ImproperlyConfiguredException
21 from starlite.status_codes import (
22     HTTP_200_OK,
23     HTTP_204_NO_CONTENT,
24     HTTP_304_NOT_MODIFIED,
25 )
26 from starlite.utils.helpers import get_enum_string_value
27 from starlite.utils.serialization import default_serializer
28 
29 if TYPE_CHECKING:
30     from typing_extensions import Literal
31 
32     from starlite.datastructures import BackgroundTask, BackgroundTasks
33     from starlite.types import (
34         HTTPResponseBodyEvent,
35         HTTPResponseStartEvent,
36         Receive,
37         ResponseCookies,
38         Scope,
39         Send,
40     )
41 
42 T = TypeVar("T")
43 
44 
45 class Response(Generic[T]):
46     __slots__ = (
47         "status_code",
48         "media_type",
49         "background",
50         "headers",
51         "cookies",
52         "encoding",
53         "body",
54         "status_allows_body",
55         "is_head_response",
56     )
57 
58     def __init__(
59         self,
60         content: T,
61         *,
62         status_code: int = HTTP_200_OK,
63         media_type: Union[MediaType, "OpenAPIMediaType", str] = MediaType.JSON,
64         background: Optional[Union["BackgroundTask", "BackgroundTasks"]] = None,
65         headers: Optional[Dict[str, Any]] = None,
66         cookies: Optional["ResponseCookies"] = None,
67         encoding: str = "utf-8",
68         is_head_response: bool = False,
69     ) -> None:
70         """This is the base Starlite HTTP response class, used as the basis for
71         all other response classes.
72 
73         Args:
74             content: A value for the response body that will be rendered into bytes string.
75             status_code: An HTTP status code.
76             media_type: A value for the response 'Content-Type' header.
77             background: A [BackgroundTask][starlite.datastructures.BackgroundTask] instance or
78                 [BackgroundTasks][starlite.datastructures.BackgroundTasks] to execute after the response is finished.
79                 Defaults to None.
80             headers: A string keyed dictionary of response headers. Header keys are insensitive.
81             cookies: A list of [Cookie][starlite.datastructures.Cookie] instances to be set under the response 'Set-Cookie' header.
82             encoding: The encoding to be used for the response headers.
83             is_head_response: Whether the response should send only the headers ("head" request) or also the content.
84         """
85         self.status_code = status_code
86         self.media_type = get_enum_string_value(media_type)
87         self.background = background
88         self.headers = headers or {}
89         self.cookies = cookies or []
90         self.encoding = encoding
91         self.is_head_response = is_head_response
92         self.status_allows_body = not (
93             self.status_code in {HTTP_204_NO_CONTENT, HTTP_304_NOT_MODIFIED} or self.status_code < HTTP_200_OK
94         )
95         self.body = self.render(content) if not self.is_head_response else b""
96 
97     def set_cookie(
98         self,
99         key: str,
100         value: Optional[str] = None,
101         max_age: Optional[int] = None,
102         expires: Optional[int] = None,
103         path: str = "/",
104         domain: Optional[str] = None,
105         secure: bool = False,
106         httponly: bool = False,
107         samesite: 'Literal["lax", "strict", "none"]' = "lax",
108     ) -> None:
109         """Sets a cookie on the response.
110 
111         Args:
112             key: Key for the cookie.
113             value: Value for the cookie, if none given defaults to empty string.
114             max_age: Maximal age of the cookie before its invalidated.
115             expires: Expiration date as unix MS timestamp.
116             path: Path fragment that must exist in the request url for the cookie to be valid. Defaults to '/'.
117             domain: Domain for which the cookie is valid.
118             secure: Https is required for the cookie.
119             httponly: Forbids javascript to access the cookie via 'Document.cookie'.
120             samesite: Controls whether a cookie is sent with cross-site requests. Defaults to 'lax'.
121 
122         Returns:
123             None.
124         """
125         self.cookies.append(
126             Cookie(
127                 domain=domain,
128                 expires=expires,
129                 httponly=httponly,
130                 key=key,
131                 max_age=max_age,
132                 path=path,
133                 samesite=samesite,
134                 secure=secure,
135                 value=value,
136             )
137         )
138 
139     def set_header(self, key: str, value: str) -> None:
140         """Sets a header on the response.
141 
142         Args:
143             key: Header key.
144             value: Header value.
145 
146         Returns:
147             None.
148         """
149         self.headers[key] = value
150 
151     def set_etag(self, etag: Union[str, "ETag"]) -> None:
152         """Sets an etag header.
153 
154         Args:
155             etag: An etag value.
156 
157         Returns:
158             None
159         """
160         self.headers["etag"] = etag.to_header() if isinstance(etag, ETag) else etag
161 
162     def delete_cookie(
163         self,
164         key: str,
165         path: str = "/",
166         domain: Optional[str] = None,
167     ) -> None:
168         """Deletes a cookie.
169 
170         Args:
171             key: Key of the cookie.
172             path: Path of the cookie.
173             domain: Domain of the cookie.
174 
175         Returns:
176             None.
177         """
178         cookie = Cookie(key=key, path=path, domain=domain, expires=0, max_age=0)
179         self.cookies = [c for c in self.cookies if c != cookie]
180         self.cookies.append(cookie)
181 
182     @staticmethod
183     def serializer(value: Any) -> Any:
184         """Serializer hook for orjson to handle pydantic models.
185 
186         Args:
187             value: A value to serialize
188         Returns:
189             A serialized value
190         Raises:
191             TypeError: if value is not supported
192         """
193         return default_serializer(value)
194 
195     def render(self, content: Any) -> bytes:
196         """
197         Handles the rendering of content T into a bytes string.
198         Args:
199             content: A value for the response body that will be rendered into bytes string.
200 
201         Returns:
202             An encoded bytes string
203         """
204         if self.status_allows_body:
205             if isinstance(content, bytes):
206                 return content
207             if isinstance(content, str):
208                 return content.encode(self.encoding)
209             if self.media_type == MediaType.JSON:
210                 try:
211                     return dumps(content, default=self.serializer, option=OPT_SERIALIZE_NUMPY | OPT_OMIT_MICROSECONDS)
212                 except (AttributeError, ValueError, TypeError) as e:
213                     raise ImproperlyConfiguredException("Unable to serialize response content") from e
214             if isinstance(content, OpenAPI):
215                 content_dict = content.dict(by_alias=True, exclude_none=True)
216                 if self.media_type == OpenAPIMediaType.OPENAPI_YAML:
217                     return cast("bytes", dump_yaml(content_dict, default_flow_style=False).encode("utf-8"))
218                 return dumps(content_dict, option=OPT_INDENT_2 | OPT_OMIT_MICROSECONDS)
219             if content is None:
220                 return b""
221             raise ImproperlyConfiguredException(
222                 f"unable to render response body for the given {content} with media_type {self.media_type}"
223             )
224         if content is not None:
225             raise ImproperlyConfiguredException(
226                 f"status_code {self.status_code} does not support a response body value"
227             )
228         return b""
229 
230     @property
231     def content_length(self) -> Optional[int]:
232         """
233 
234         Returns:
235             The content length of the body (e.g. for use in a "Content-Length" header).
236             If the response does not have a body, this value is `None`
237         """
238         if self.status_allows_body:
239             return len(self.body)
240         return None
241 
242     @property
243     def encoded_headers(self) -> List[Tuple[bytes, bytes]]:
244         """
245         Notes:
246             - A 'Content-Length' header will be added if appropriate and not provided by the user.
247 
248         Returns:
249             A list of tuples containing the headers and cookies of the request in a format ready for ASGI transmission.
250         """
251 
252         if self.media_type.startswith("text/"):
253             content_type = f"{self.media_type}; charset={self.encoding}"
254         else:
255             content_type = self.media_type
256 
257         encoded_headers = [
258             *((k.lower().encode("latin-1"), str(v).lower().encode("latin-1")) for k, v in self.headers.items()),
259             *((b"set-cookie", cookie.to_header(header="").encode("latin-1")) for cookie in self.cookies),
260             (b"content-type", content_type.encode("latin-1")),
261         ]
262 
263         if self.content_length and not any(key == b"content-length" for key, _ in encoded_headers):
264             encoded_headers.append((b"content-length", str(self.content_length).encode("latin-1")))
265         return encoded_headers
266 
267     async def after_response(self) -> None:
268         """Executed after the response is sent.
269 
270         Returns:
271             None
272         """
273         if self.background is not None:
274             await self.background()
275 
276     async def start_response(self, send: "Send") -> None:
277         """
278         Emits the start event of the response. This event includes the headers and status codes.
279         Args:
280             send: The ASGI send function.
281 
282         Returns:
283             None
284         """
285         event: "HTTPResponseStartEvent" = {
286             "type": "http.response.start",
287             "status": self.status_code,
288             "headers": self.encoded_headers,
289         }
290 
291         await send(event)
292 
293     async def send_body(self, send: "Send", receive: "Receive") -> None:  # pylint: disable=unused-argument
294         """Emits the response body.
295 
296         Args:
297             send: The ASGI send function.
298             receive: The ASGI receive function.
299 
300         Notes:
301             - Response subclasses should customize this method if there is a need to customize sending data.
302 
303         Returns:
304             None
305         """
306         event: "HTTPResponseBodyEvent" = {"type": "http.response.body", "body": self.body, "more_body": False}
307         await send(event)
308 
309     async def __call__(self, scope: "Scope", receive: "Receive", send: "Send") -> None:
310         """The call method of the response is an "ASGIApp".
311 
312         Args:
313             scope: The ASGI connection scope.
314             receive: The ASGI receive function.
315             send: The ASGI send function.
316 
317         Returns:
318             None
319         """
320         await self.start_response(send=send)
321 
322         if self.is_head_response:
323             event: "HTTPResponseBodyEvent" = {"type": "http.response.body", "body": b"", "more_body": False}
324             await send(event)
325         else:
326             await self.send_body(send=send, receive=receive)
327 
328         await self.after_response()
329
```
--- 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/base.py b/starlite/response/base.py
--- a/starlite/response/base.py
+++ b/starlite/response/base.py
@@ -255,7 +255,7 @@
             content_type = self.media_type
 
         encoded_headers = [
-            *((k.lower().encode("latin-1"), str(v).lower().encode("latin-1")) for k, v in self.headers.items()),
+            *((k.lower().encode("latin-1"), str(v).encode("latin-1")) for k, v in self.headers.items()),
             *((b"set-cookie", cookie.to_header(header="").encode("latin-1")) for cookie in self.cookies),
             (b"content-type", content_type.encode("latin-1")),
         ]

{"golden_diff": "diff --git a/starlite/response/base.py b/starlite/response/base.py\n--- a/starlite/response/base.py\n+++ b/starlite/response/base.py\n@@ -255,7 +255,7 @@\n             content_type = self.media_type\n \n         encoded_headers = [\n-            *((k.lower().encode(\"latin-1\"), str(v).lower().encode(\"latin-1\")) for k, v in self.headers.items()),\n+            *((k.lower().encode(\"latin-1\"), str(v).encode(\"latin-1\")) for k, v in self.headers.items()),\n             *((b\"set-cookie\", cookie.to_header(header=\"\").encode(\"latin-1\")) for cookie in self.cookies),\n             (b\"content-type\", content_type.encode(\"latin-1\")),\n         ]\n", "issue": "Bug: Header values should not be lowercased\n**Describe the bug**\r\nHeaders keys and values are lowercased before being rendered. While lowercasing key is fine (as per HTTP2 spec), lowercasing values should not be done.\r\n\r\nFor my use case, integrating with a payment provider involves passing a transaction ID as a header. This ID contains lowercase, uppercase letters, and is not case-insensitive.\r\n\r\n**To Reproduce**\r\n1. Create a new route_handler.\r\n2. In the route_handler, modify the response: `response.headers[\"Foo\"] = \"Bar\"` .\r\n3. Observe that the key and value are returned as lowercase:\r\n\r\n![2022-10-27_16-23](https://user-images.githubusercontent.com/546693/198312809-fc5b8947-be88-4354-b909-033270ae188f.png)\r\n\r\n4. While reporting this, I noticed that `date` and `vary` headers are not lowercased.\r\n\r\n**Additional context**\r\nLooking at the Git history, it seems that originally Starlette was used for handling the responses. I thought that Starlette might also have this behaviour, but they do not lowercase the header values. See https://github.com/encode/starlette/blob/fa737beb2838f568fe2477e2316a7fdf3d3eb257/starlette/responses.py#L72 .\r\n\r\nThe relevant code in Starlite is here: https://github.com/starlite-api/starlite/blob/95379f102be249f3c9453fbf9d216a41eede2d6f/starlite/response/base.py#L257\r\n\n", "before_files": [{"content": "from typing import (\n    TYPE_CHECKING,\n    Any,\n    Dict,\n    Generic,\n    List,\n    Optional,\n    Tuple,\n    TypeVar,\n    Union,\n    cast,\n)\n\nfrom orjson import OPT_INDENT_2, OPT_OMIT_MICROSECONDS, OPT_SERIALIZE_NUMPY, dumps\nfrom pydantic_openapi_schema.v3_1_0 import OpenAPI\nfrom yaml import dump as dump_yaml\n\nfrom starlite.datastructures import Cookie, ETag\nfrom starlite.enums import MediaType, OpenAPIMediaType\nfrom starlite.exceptions import ImproperlyConfiguredException\nfrom starlite.status_codes import (\n    HTTP_200_OK,\n    HTTP_204_NO_CONTENT,\n    HTTP_304_NOT_MODIFIED,\n)\nfrom starlite.utils.helpers import get_enum_string_value\nfrom starlite.utils.serialization import default_serializer\n\nif TYPE_CHECKING:\n    from typing_extensions import Literal\n\n    from starlite.datastructures import BackgroundTask, BackgroundTasks\n    from starlite.types import (\n        HTTPResponseBodyEvent,\n        HTTPResponseStartEvent,\n        Receive,\n        ResponseCookies,\n        Scope,\n        Send,\n    )\n\nT = TypeVar(\"T\")\n\n\nclass Response(Generic[T]):\n    __slots__ = (\n        \"status_code\",\n        \"media_type\",\n        \"background\",\n        \"headers\",\n        \"cookies\",\n        \"encoding\",\n        \"body\",\n        \"status_allows_body\",\n        \"is_head_response\",\n    )\n\n    def __init__(\n        self,\n        content: T,\n        *,\n        status_code: int = HTTP_200_OK,\n        media_type: Union[MediaType, \"OpenAPIMediaType\", str] = MediaType.JSON,\n        background: Optional[Union[\"BackgroundTask\", \"BackgroundTasks\"]] = None,\n        headers: Optional[Dict[str, Any]] = None,\n        cookies: Optional[\"ResponseCookies\"] = None,\n        encoding: str = \"utf-8\",\n        is_head_response: bool = False,\n    ) -> None:\n        \"\"\"This is the base Starlite HTTP response class, used as the basis for\n        all other response classes.\n\n        Args:\n            content: A value for the response body that will be rendered into bytes string.\n            status_code: An HTTP status code.\n            media_type: A value for the response 'Content-Type' header.\n            background: A [BackgroundTask][starlite.datastructures.BackgroundTask] instance or\n                [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 [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        \"\"\"\n        self.status_code = status_code\n        self.media_type = get_enum_string_value(media_type)\n        self.background = background\n        self.headers = headers or {}\n        self.cookies = cookies or []\n        self.encoding = encoding\n        self.is_head_response = is_head_response\n        self.status_allows_body = not (\n            self.status_code in {HTTP_204_NO_CONTENT, HTTP_304_NOT_MODIFIED} or self.status_code < HTTP_200_OK\n        )\n        self.body = self.render(content) if not self.is_head_response else b\"\"\n\n    def set_cookie(\n        self,\n        key: str,\n        value: Optional[str] = None,\n        max_age: Optional[int] = None,\n        expires: Optional[int] = None,\n        path: str = \"/\",\n        domain: Optional[str] = None,\n        secure: bool = False,\n        httponly: bool = False,\n        samesite: 'Literal[\"lax\", \"strict\", \"none\"]' = \"lax\",\n    ) -> None:\n        \"\"\"Sets a cookie on the response.\n\n        Args:\n            key: Key for the cookie.\n            value: Value for the cookie, if none given defaults to empty string.\n            max_age: Maximal age of the cookie before its invalidated.\n            expires: Expiration date as unix MS timestamp.\n            path: Path fragment that must exist in the request url for the cookie to be valid. Defaults to '/'.\n            domain: Domain for which the cookie is valid.\n            secure: Https is required for the cookie.\n            httponly: Forbids javascript to access the cookie via 'Document.cookie'.\n            samesite: Controls whether a cookie is sent with cross-site requests. Defaults to 'lax'.\n\n        Returns:\n            None.\n        \"\"\"\n        self.cookies.append(\n            Cookie(\n                domain=domain,\n                expires=expires,\n                httponly=httponly,\n                key=key,\n                max_age=max_age,\n                path=path,\n                samesite=samesite,\n                secure=secure,\n                value=value,\n            )\n        )\n\n    def set_header(self, key: str, value: str) -> None:\n        \"\"\"Sets a header on the response.\n\n        Args:\n            key: Header key.\n            value: Header value.\n\n        Returns:\n            None.\n        \"\"\"\n        self.headers[key] = value\n\n    def set_etag(self, etag: Union[str, \"ETag\"]) -> None:\n        \"\"\"Sets an etag header.\n\n        Args:\n            etag: An etag value.\n\n        Returns:\n            None\n        \"\"\"\n        self.headers[\"etag\"] = etag.to_header() if isinstance(etag, ETag) else etag\n\n    def delete_cookie(\n        self,\n        key: str,\n        path: str = \"/\",\n        domain: Optional[str] = None,\n    ) -> None:\n        \"\"\"Deletes a cookie.\n\n        Args:\n            key: Key of the cookie.\n            path: Path of the cookie.\n            domain: Domain of the cookie.\n\n        Returns:\n            None.\n        \"\"\"\n        cookie = Cookie(key=key, path=path, domain=domain, expires=0, max_age=0)\n        self.cookies = [c for c in self.cookies if c != cookie]\n        self.cookies.append(cookie)\n\n    @staticmethod\n    def serializer(value: Any) -> Any:\n        \"\"\"Serializer hook for orjson to handle pydantic models.\n\n        Args:\n            value: A value to serialize\n        Returns:\n            A serialized value\n        Raises:\n            TypeError: if value is not supported\n        \"\"\"\n        return default_serializer(value)\n\n    def render(self, content: Any) -> bytes:\n        \"\"\"\n        Handles the rendering of content T into a bytes string.\n        Args:\n            content: A value for the response body that will be rendered into bytes string.\n\n        Returns:\n            An encoded bytes string\n        \"\"\"\n        if self.status_allows_body:\n            if isinstance(content, bytes):\n                return content\n            if isinstance(content, str):\n                return content.encode(self.encoding)\n            if self.media_type == MediaType.JSON:\n                try:\n                    return dumps(content, default=self.serializer, option=OPT_SERIALIZE_NUMPY | OPT_OMIT_MICROSECONDS)\n                except (AttributeError, ValueError, TypeError) as e:\n                    raise ImproperlyConfiguredException(\"Unable to serialize response content\") from e\n            if isinstance(content, OpenAPI):\n                content_dict = content.dict(by_alias=True, exclude_none=True)\n                if self.media_type == OpenAPIMediaType.OPENAPI_YAML:\n                    return cast(\"bytes\", dump_yaml(content_dict, default_flow_style=False).encode(\"utf-8\"))\n                return dumps(content_dict, option=OPT_INDENT_2 | OPT_OMIT_MICROSECONDS)\n            if content is None:\n                return b\"\"\n            raise ImproperlyConfiguredException(\n                f\"unable to render response body for the given {content} with media_type {self.media_type}\"\n            )\n        if content is not None:\n            raise ImproperlyConfiguredException(\n                f\"status_code {self.status_code} does not support a response body value\"\n            )\n        return b\"\"\n\n    @property\n    def content_length(self) -> Optional[int]:\n        \"\"\"\n\n        Returns:\n            The content length of the body (e.g. for use in a \"Content-Length\" header).\n            If the response does not have a body, this value is `None`\n        \"\"\"\n        if self.status_allows_body:\n            return len(self.body)\n        return None\n\n    @property\n    def encoded_headers(self) -> List[Tuple[bytes, bytes]]:\n        \"\"\"\n        Notes:\n            - A 'Content-Length' header will be added if appropriate and not provided by the user.\n\n        Returns:\n            A list of tuples containing the headers and cookies of the request in a format ready for ASGI transmission.\n        \"\"\"\n\n        if self.media_type.startswith(\"text/\"):\n            content_type = f\"{self.media_type}; charset={self.encoding}\"\n        else:\n            content_type = self.media_type\n\n        encoded_headers = [\n            *((k.lower().encode(\"latin-1\"), str(v).lower().encode(\"latin-1\")) for k, v in self.headers.items()),\n            *((b\"set-cookie\", cookie.to_header(header=\"\").encode(\"latin-1\")) for cookie in self.cookies),\n            (b\"content-type\", content_type.encode(\"latin-1\")),\n        ]\n\n        if self.content_length and not any(key == b\"content-length\" for key, _ in encoded_headers):\n            encoded_headers.append((b\"content-length\", str(self.content_length).encode(\"latin-1\")))\n        return encoded_headers\n\n    async def after_response(self) -> None:\n        \"\"\"Executed after the response is sent.\n\n        Returns:\n            None\n        \"\"\"\n        if self.background is not None:\n            await self.background()\n\n    async def start_response(self, send: \"Send\") -> None:\n        \"\"\"\n        Emits the start event of the response. This event includes the headers and status codes.\n        Args:\n            send: The ASGI send function.\n\n        Returns:\n            None\n        \"\"\"\n        event: \"HTTPResponseStartEvent\" = {\n            \"type\": \"http.response.start\",\n            \"status\": self.status_code,\n            \"headers\": self.encoded_headers,\n        }\n\n        await send(event)\n\n    async def send_body(self, send: \"Send\", receive: \"Receive\") -> None:  # pylint: disable=unused-argument\n        \"\"\"Emits the response body.\n\n        Args:\n            send: The ASGI send function.\n            receive: The ASGI receive function.\n\n        Notes:\n            - Response subclasses should customize this method if there is a need to customize sending data.\n\n        Returns:\n            None\n        \"\"\"\n        event: \"HTTPResponseBodyEvent\" = {\"type\": \"http.response.body\", \"body\": self.body, \"more_body\": False}\n        await send(event)\n\n    async def __call__(self, scope: \"Scope\", receive: \"Receive\", send: \"Send\") -> None:\n        \"\"\"The call method of the response is an \"ASGIApp\".\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        await self.start_response(send=send)\n\n        if self.is_head_response:\n            event: \"HTTPResponseBodyEvent\" = {\"type\": \"http.response.body\", \"body\": b\"\", \"more_body\": False}\n            await send(event)\n        else:\n            await self.send_body(send=send, receive=receive)\n\n        await self.after_response()\n", "path": "starlite/response/base.py"}], "after_files": [{"content": "from typing import (\n    TYPE_CHECKING,\n    Any,\n    Dict,\n    Generic,\n    List,\n    Optional,\n    Tuple,\n    TypeVar,\n    Union,\n    cast,\n)\n\nfrom orjson import OPT_INDENT_2, OPT_OMIT_MICROSECONDS, OPT_SERIALIZE_NUMPY, dumps\nfrom pydantic_openapi_schema.v3_1_0 import OpenAPI\nfrom yaml import dump as dump_yaml\n\nfrom starlite.datastructures import Cookie, ETag\nfrom starlite.enums import MediaType, OpenAPIMediaType\nfrom starlite.exceptions import ImproperlyConfiguredException\nfrom starlite.status_codes import (\n    HTTP_200_OK,\n    HTTP_204_NO_CONTENT,\n    HTTP_304_NOT_MODIFIED,\n)\nfrom starlite.utils.helpers import get_enum_string_value\nfrom starlite.utils.serialization import default_serializer\n\nif TYPE_CHECKING:\n    from typing_extensions import Literal\n\n    from starlite.datastructures import BackgroundTask, BackgroundTasks\n    from starlite.types import (\n        HTTPResponseBodyEvent,\n        HTTPResponseStartEvent,\n        Receive,\n        ResponseCookies,\n        Scope,\n        Send,\n    )\n\nT = TypeVar(\"T\")\n\n\nclass Response(Generic[T]):\n    __slots__ = (\n        \"status_code\",\n        \"media_type\",\n        \"background\",\n        \"headers\",\n        \"cookies\",\n        \"encoding\",\n        \"body\",\n        \"status_allows_body\",\n        \"is_head_response\",\n    )\n\n    def __init__(\n        self,\n        content: T,\n        *,\n        status_code: int = HTTP_200_OK,\n        media_type: Union[MediaType, \"OpenAPIMediaType\", str] = MediaType.JSON,\n        background: Optional[Union[\"BackgroundTask\", \"BackgroundTasks\"]] = None,\n        headers: Optional[Dict[str, Any]] = None,\n        cookies: Optional[\"ResponseCookies\"] = None,\n        encoding: str = \"utf-8\",\n        is_head_response: bool = False,\n    ) -> None:\n        \"\"\"This is the base Starlite HTTP response class, used as the basis for\n        all other response classes.\n\n        Args:\n            content: A value for the response body that will be rendered into bytes string.\n            status_code: An HTTP status code.\n            media_type: A value for the response 'Content-Type' header.\n            background: A [BackgroundTask][starlite.datastructures.BackgroundTask] instance or\n                [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 [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        \"\"\"\n        self.status_code = status_code\n        self.media_type = get_enum_string_value(media_type)\n        self.background = background\n        self.headers = headers or {}\n        self.cookies = cookies or []\n        self.encoding = encoding\n        self.is_head_response = is_head_response\n        self.status_allows_body = not (\n            self.status_code in {HTTP_204_NO_CONTENT, HTTP_304_NOT_MODIFIED} or self.status_code < HTTP_200_OK\n        )\n        self.body = self.render(content) if not self.is_head_response else b\"\"\n\n    def set_cookie(\n        self,\n        key: str,\n        value: Optional[str] = None,\n        max_age: Optional[int] = None,\n        expires: Optional[int] = None,\n        path: str = \"/\",\n        domain: Optional[str] = None,\n        secure: bool = False,\n        httponly: bool = False,\n        samesite: 'Literal[\"lax\", \"strict\", \"none\"]' = \"lax\",\n    ) -> None:\n        \"\"\"Sets a cookie on the response.\n\n        Args:\n            key: Key for the cookie.\n            value: Value for the cookie, if none given defaults to empty string.\n            max_age: Maximal age of the cookie before its invalidated.\n            expires: Expiration date as unix MS timestamp.\n            path: Path fragment that must exist in the request url for the cookie to be valid. Defaults to '/'.\n            domain: Domain for which the cookie is valid.\n            secure: Https is required for the cookie.\n            httponly: Forbids javascript to access the cookie via 'Document.cookie'.\n            samesite: Controls whether a cookie is sent with cross-site requests. Defaults to 'lax'.\n\n        Returns:\n            None.\n        \"\"\"\n        self.cookies.append(\n            Cookie(\n                domain=domain,\n                expires=expires,\n                httponly=httponly,\n                key=key,\n                max_age=max_age,\n                path=path,\n                samesite=samesite,\n                secure=secure,\n                value=value,\n            )\n        )\n\n    def set_header(self, key: str, value: str) -> None:\n        \"\"\"Sets a header on the response.\n\n        Args:\n            key: Header key.\n            value: Header value.\n\n        Returns:\n            None.\n        \"\"\"\n        self.headers[key] = value\n\n    def set_etag(self, etag: Union[str, \"ETag\"]) -> None:\n        \"\"\"Sets an etag header.\n\n        Args:\n            etag: An etag value.\n\n        Returns:\n            None\n        \"\"\"\n        self.headers[\"etag\"] = etag.to_header() if isinstance(etag, ETag) else etag\n\n    def delete_cookie(\n        self,\n        key: str,\n        path: str = \"/\",\n        domain: Optional[str] = None,\n    ) -> None:\n        \"\"\"Deletes a cookie.\n\n        Args:\n            key: Key of the cookie.\n            path: Path of the cookie.\n            domain: Domain of the cookie.\n\n        Returns:\n            None.\n        \"\"\"\n        cookie = Cookie(key=key, path=path, domain=domain, expires=0, max_age=0)\n        self.cookies = [c for c in self.cookies if c != cookie]\n        self.cookies.append(cookie)\n\n    @staticmethod\n    def serializer(value: Any) -> Any:\n        \"\"\"Serializer hook for orjson to handle pydantic models.\n\n        Args:\n            value: A value to serialize\n        Returns:\n            A serialized value\n        Raises:\n            TypeError: if value is not supported\n        \"\"\"\n        return default_serializer(value)\n\n    def render(self, content: Any) -> bytes:\n        \"\"\"\n        Handles the rendering of content T into a bytes string.\n        Args:\n            content: A value for the response body that will be rendered into bytes string.\n\n        Returns:\n            An encoded bytes string\n        \"\"\"\n        if self.status_allows_body:\n            if isinstance(content, bytes):\n                return content\n            if isinstance(content, str):\n                return content.encode(self.encoding)\n            if self.media_type == MediaType.JSON:\n                try:\n                    return dumps(content, default=self.serializer, option=OPT_SERIALIZE_NUMPY | OPT_OMIT_MICROSECONDS)\n                except (AttributeError, ValueError, TypeError) as e:\n                    raise ImproperlyConfiguredException(\"Unable to serialize response content\") from e\n            if isinstance(content, OpenAPI):\n                content_dict = content.dict(by_alias=True, exclude_none=True)\n                if self.media_type == OpenAPIMediaType.OPENAPI_YAML:\n                    return cast(\"bytes\", dump_yaml(content_dict, default_flow_style=False).encode(\"utf-8\"))\n                return dumps(content_dict, option=OPT_INDENT_2 | OPT_OMIT_MICROSECONDS)\n            if content is None:\n                return b\"\"\n            raise ImproperlyConfiguredException(\n                f\"unable to render response body for the given {content} with media_type {self.media_type}\"\n            )\n        if content is not None:\n            raise ImproperlyConfiguredException(\n                f\"status_code {self.status_code} does not support a response body value\"\n            )\n        return b\"\"\n\n    @property\n    def content_length(self) -> Optional[int]:\n        \"\"\"\n\n        Returns:\n            The content length of the body (e.g. for use in a \"Content-Length\" header).\n            If the response does not have a body, this value is `None`\n        \"\"\"\n        if self.status_allows_body:\n            return len(self.body)\n        return None\n\n    @property\n    def encoded_headers(self) -> List[Tuple[bytes, bytes]]:\n        \"\"\"\n        Notes:\n            - A 'Content-Length' header will be added if appropriate and not provided by the user.\n\n        Returns:\n            A list of tuples containing the headers and cookies of the request in a format ready for ASGI transmission.\n        \"\"\"\n\n        if self.media_type.startswith(\"text/\"):\n            content_type = f\"{self.media_type}; charset={self.encoding}\"\n        else:\n            content_type = self.media_type\n\n        encoded_headers = [\n            *((k.lower().encode(\"latin-1\"), str(v).encode(\"latin-1\")) for k, v in self.headers.items()),\n            *((b\"set-cookie\", cookie.to_header(header=\"\").encode(\"latin-1\")) for cookie in self.cookies),\n            (b\"content-type\", content_type.encode(\"latin-1\")),\n        ]\n\n        if self.content_length and not any(key == b\"content-length\" for key, _ in encoded_headers):\n            encoded_headers.append((b\"content-length\", str(self.content_length).encode(\"latin-1\")))\n        return encoded_headers\n\n    async def after_response(self) -> None:\n        \"\"\"Executed after the response is sent.\n\n        Returns:\n            None\n        \"\"\"\n        if self.background is not None:\n            await self.background()\n\n    async def start_response(self, send: \"Send\") -> None:\n        \"\"\"\n        Emits the start event of the response. This event includes the headers and status codes.\n        Args:\n            send: The ASGI send function.\n\n        Returns:\n            None\n        \"\"\"\n        event: \"HTTPResponseStartEvent\" = {\n            \"type\": \"http.response.start\",\n            \"status\": self.status_code,\n            \"headers\": self.encoded_headers,\n        }\n\n        await send(event)\n\n    async def send_body(self, send: \"Send\", receive: \"Receive\") -> None:  # pylint: disable=unused-argument\n        \"\"\"Emits the response body.\n\n        Args:\n            send: The ASGI send function.\n            receive: The ASGI receive function.\n\n        Notes:\n            - Response subclasses should customize this method if there is a need to customize sending data.\n\n        Returns:\n            None\n        \"\"\"\n        event: \"HTTPResponseBodyEvent\" = {\"type\": \"http.response.body\", \"body\": self.body, \"more_body\": False}\n        await send(event)\n\n    async def __call__(self, scope: \"Scope\", receive: \"Receive\", send: \"Send\") -> None:\n        \"\"\"The call method of the response is an \"ASGIApp\".\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        await self.start_response(send=send)\n\n        if self.is_head_response:\n            event: \"HTTPResponseBodyEvent\" = {\"type\": \"http.response.body\", \"body\": b\"\", \"more_body\": False}\n            await send(event)\n        else:\n            await self.send_body(send=send, receive=receive)\n\n        await self.after_response()\n", "path": "starlite/response/base.py"}]}