We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Proxy Middleware grabs the last IP in `x-forwarded-for`, not the first
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For says the first IP in is a client IP, but ProxyHeadersMiddleware grabs the last IP:
https://github.com/encode/uvicorn/blob/9d9f8820a8155e36dcb5e4d4023f470e51aa4e03/uvicorn/middleware/proxy_headers.py#L41

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `uvicorn/middleware/proxy_headers.py`
Content:
```
1 """
2 This middleware can be used when a known proxy is fronting the application,
3 and is trusted to be properly setting the `X-Forwarded-Proto` and
4 `X-Forwarded-For` headers with the connecting client information.
5 
6 Modifies the `client` and `scheme` information so that they reference
7 the connecting client, rather that the connecting proxy.
8 
9 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#Proxies
10 """
11 
12 
13 class ProxyHeadersMiddleware:
14     def __init__(self, app, trusted_hosts="127.0.0.1"):
15         self.app = app
16         if isinstance(trusted_hosts, str):
17             self.trusted_hosts = [item.strip() for item in trusted_hosts.split(",")]
18         else:
19             self.trusted_hosts = trusted_hosts
20         self.always_trust = "*" in self.trusted_hosts
21 
22     async def __call__(self, scope, receive, send):
23         if scope["type"] in ("http", "websocket"):
24             client_addr = scope.get("client")
25             client_host = client_addr[0] if client_addr else None
26 
27             if self.always_trust or client_host in self.trusted_hosts:
28                 headers = dict(scope["headers"])
29 
30                 if b"x-forwarded-proto" in headers:
31                     # Determine if the incoming request was http or https based on
32                     # the X-Forwarded-Proto header.
33                     x_forwarded_proto = headers[b"x-forwarded-proto"].decode("latin1")
34                     scope["scheme"] = x_forwarded_proto.strip()
35 
36                 if b"x-forwarded-for" in headers:
37                     # Determine the client address from the last trusted IP in the
38                     # X-Forwarded-For header. We've lost the connecting client's port
39                     # information by now, so only include the host.
40                     x_forwarded_for = headers[b"x-forwarded-for"].decode("latin1")
41                     host = x_forwarded_for.split(",")[-1].strip()
42                     port = 0
43                     scope["client"] = (host, port)
44 
45         return await self.app(scope, receive, send)
46
```
--- 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/uvicorn/middleware/proxy_headers.py b/uvicorn/middleware/proxy_headers.py
--- a/uvicorn/middleware/proxy_headers.py
+++ b/uvicorn/middleware/proxy_headers.py
@@ -8,17 +8,28 @@
 
 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#Proxies
 """
+from typing import List
 
 
 class ProxyHeadersMiddleware:
     def __init__(self, app, trusted_hosts="127.0.0.1"):
         self.app = app
         if isinstance(trusted_hosts, str):
-            self.trusted_hosts = [item.strip() for item in trusted_hosts.split(",")]
+            self.trusted_hosts = {item.strip() for item in trusted_hosts.split(",")}
         else:
-            self.trusted_hosts = trusted_hosts
+            self.trusted_hosts = set(trusted_hosts)
         self.always_trust = "*" in self.trusted_hosts
 
+    def get_trusted_client_host(
+        self, x_forwarded_for_hosts
+    ):  # type: (List[str]) -> str
+        if self.always_trust:
+            return x_forwarded_for_hosts[0]
+
+        for host in reversed(x_forwarded_for_hosts):
+            if host not in self.trusted_hosts:
+                return host
+
     async def __call__(self, scope, receive, send):
         if scope["type"] in ("http", "websocket"):
             client_addr = scope.get("client")
@@ -38,7 +49,10 @@
                     # X-Forwarded-For header. We've lost the connecting client's port
                     # information by now, so only include the host.
                     x_forwarded_for = headers[b"x-forwarded-for"].decode("latin1")
-                    host = x_forwarded_for.split(",")[-1].strip()
+                    x_forwarded_for_hosts = [
+                        item.strip() for item in x_forwarded_for.split(",")
+                    ]
+                    host = self.get_trusted_client_host(x_forwarded_for_hosts)
                     port = 0
                     scope["client"] = (host, port)

{"golden_diff": "diff --git a/uvicorn/middleware/proxy_headers.py b/uvicorn/middleware/proxy_headers.py\n--- a/uvicorn/middleware/proxy_headers.py\n+++ b/uvicorn/middleware/proxy_headers.py\n@@ -8,17 +8,28 @@\n \n https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#Proxies\n \"\"\"\n+from typing import List\n \n \n class ProxyHeadersMiddleware:\n     def __init__(self, app, trusted_hosts=\"127.0.0.1\"):\n         self.app = app\n         if isinstance(trusted_hosts, str):\n-            self.trusted_hosts = [item.strip() for item in trusted_hosts.split(\",\")]\n+            self.trusted_hosts = {item.strip() for item in trusted_hosts.split(\",\")}\n         else:\n-            self.trusted_hosts = trusted_hosts\n+            self.trusted_hosts = set(trusted_hosts)\n         self.always_trust = \"*\" in self.trusted_hosts\n \n+    def get_trusted_client_host(\n+        self, x_forwarded_for_hosts\n+    ):  # type: (List[str]) -> str\n+        if self.always_trust:\n+            return x_forwarded_for_hosts[0]\n+\n+        for host in reversed(x_forwarded_for_hosts):\n+            if host not in self.trusted_hosts:\n+                return host\n+\n     async def __call__(self, scope, receive, send):\n         if scope[\"type\"] in (\"http\", \"websocket\"):\n             client_addr = scope.get(\"client\")\n@@ -38,7 +49,10 @@\n                     # X-Forwarded-For header. We've lost the connecting client's port\n                     # information by now, so only include the host.\n                     x_forwarded_for = headers[b\"x-forwarded-for\"].decode(\"latin1\")\n-                    host = x_forwarded_for.split(\",\")[-1].strip()\n+                    x_forwarded_for_hosts = [\n+                        item.strip() for item in x_forwarded_for.split(\",\")\n+                    ]\n+                    host = self.get_trusted_client_host(x_forwarded_for_hosts)\n                     port = 0\n                     scope[\"client\"] = (host, port)\n", "issue": "Proxy Middleware grabs the last IP in `x-forwarded-for`, not the first\nhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For says the first IP in is a client IP, but ProxyHeadersMiddleware grabs the last IP:\r\nhttps://github.com/encode/uvicorn/blob/9d9f8820a8155e36dcb5e4d4023f470e51aa4e03/uvicorn/middleware/proxy_headers.py#L41\n", "before_files": [{"content": "\"\"\"\nThis middleware can be used when a known proxy is fronting the application,\nand is trusted to be properly setting the `X-Forwarded-Proto` and\n`X-Forwarded-For` headers with the connecting client information.\n\nModifies the `client` and `scheme` information so that they reference\nthe connecting client, rather that the connecting proxy.\n\nhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#Proxies\n\"\"\"\n\n\nclass ProxyHeadersMiddleware:\n    def __init__(self, app, trusted_hosts=\"127.0.0.1\"):\n        self.app = app\n        if isinstance(trusted_hosts, str):\n            self.trusted_hosts = [item.strip() for item in trusted_hosts.split(\",\")]\n        else:\n            self.trusted_hosts = trusted_hosts\n        self.always_trust = \"*\" in self.trusted_hosts\n\n    async def __call__(self, scope, receive, send):\n        if scope[\"type\"] in (\"http\", \"websocket\"):\n            client_addr = scope.get(\"client\")\n            client_host = client_addr[0] if client_addr else None\n\n            if self.always_trust or client_host in self.trusted_hosts:\n                headers = dict(scope[\"headers\"])\n\n                if b\"x-forwarded-proto\" in headers:\n                    # Determine if the incoming request was http or https based on\n                    # the X-Forwarded-Proto header.\n                    x_forwarded_proto = headers[b\"x-forwarded-proto\"].decode(\"latin1\")\n                    scope[\"scheme\"] = x_forwarded_proto.strip()\n\n                if b\"x-forwarded-for\" in headers:\n                    # Determine the client address from the last trusted IP in the\n                    # X-Forwarded-For header. We've lost the connecting client's port\n                    # information by now, so only include the host.\n                    x_forwarded_for = headers[b\"x-forwarded-for\"].decode(\"latin1\")\n                    host = x_forwarded_for.split(\",\")[-1].strip()\n                    port = 0\n                    scope[\"client\"] = (host, port)\n\n        return await self.app(scope, receive, send)\n", "path": "uvicorn/middleware/proxy_headers.py"}], "after_files": [{"content": "\"\"\"\nThis middleware can be used when a known proxy is fronting the application,\nand is trusted to be properly setting the `X-Forwarded-Proto` and\n`X-Forwarded-For` headers with the connecting client information.\n\nModifies the `client` and `scheme` information so that they reference\nthe connecting client, rather that the connecting proxy.\n\nhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#Proxies\n\"\"\"\nfrom typing import List\n\n\nclass ProxyHeadersMiddleware:\n    def __init__(self, app, trusted_hosts=\"127.0.0.1\"):\n        self.app = app\n        if isinstance(trusted_hosts, str):\n            self.trusted_hosts = {item.strip() for item in trusted_hosts.split(\",\")}\n        else:\n            self.trusted_hosts = set(trusted_hosts)\n        self.always_trust = \"*\" in self.trusted_hosts\n\n    def get_trusted_client_host(\n        self, x_forwarded_for_hosts\n    ):  # type: (List[str]) -> str\n        if self.always_trust:\n            return x_forwarded_for_hosts[0]\n\n        for host in reversed(x_forwarded_for_hosts):\n            if host not in self.trusted_hosts:\n                return host\n\n    async def __call__(self, scope, receive, send):\n        if scope[\"type\"] in (\"http\", \"websocket\"):\n            client_addr = scope.get(\"client\")\n            client_host = client_addr[0] if client_addr else None\n\n            if self.always_trust or client_host in self.trusted_hosts:\n                headers = dict(scope[\"headers\"])\n\n                if b\"x-forwarded-proto\" in headers:\n                    # Determine if the incoming request was http or https based on\n                    # the X-Forwarded-Proto header.\n                    x_forwarded_proto = headers[b\"x-forwarded-proto\"].decode(\"latin1\")\n                    scope[\"scheme\"] = x_forwarded_proto.strip()\n\n                if b\"x-forwarded-for\" in headers:\n                    # Determine the client address from the last trusted IP in the\n                    # X-Forwarded-For header. We've lost the connecting client's port\n                    # information by now, so only include the host.\n                    x_forwarded_for = headers[b\"x-forwarded-for\"].decode(\"latin1\")\n                    x_forwarded_for_hosts = [\n                        item.strip() for item in x_forwarded_for.split(\",\")\n                    ]\n                    host = self.get_trusted_client_host(x_forwarded_for_hosts)\n                    port = 0\n                    scope[\"client\"] = (host, port)\n\n        return await self.app(scope, receive, send)\n", "path": "uvicorn/middleware/proxy_headers.py"}]}