Add request.client_ip (#2790)

Co-authored-by: L. Kärkkäinen <Tronic@users.noreply.github.com>
This commit is contained in:
L. Kärkkäinen 2023-07-13 21:01:02 +01:00 committed by GitHub
parent dc3c4d1393
commit 31d7ba8f8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 6 deletions

View File

@ -838,19 +838,31 @@ class Request(Generic[sanic_type, ctx_type]):
@property @property
def remote_addr(self) -> str: def remote_addr(self) -> str:
""" """
Client IP address, if available. Client IP address, if available from proxy.
1. proxied remote address `self.forwarded['for']`
2. local remote address `self.ip`
:return: IPv4, bracketed IPv6, UNIX socket name or arbitrary string :return: IPv4, bracketed IPv6, UNIX socket name or arbitrary string
:rtype: str :rtype: str
""" """
if not hasattr(self, "_remote_addr"): if not hasattr(self, "_remote_addr"):
self._remote_addr = str( self._remote_addr = str(self.forwarded.get("for", ""))
self.forwarded.get("for", "")
) # or self.ip
return self._remote_addr return self._remote_addr
@property
def client_ip(self) -> str:
"""
Client IP address.
1. proxied remote address `self.forwarded['for']`
2. local peer address `self.ip`
New in Sanic 23.6. Prefer this over `remote_addr` for determining the
client address regardless of whether the service runs behind a proxy
or not (proxy deployment needs separate configuration).
:return: IPv4, bracketed IPv6, UNIX socket name or arbitrary string
:rtype: str
"""
return self.remote_addr or self.ip
@property @property
def scheme(self) -> str: def scheme(self) -> str:
""" """

View File

@ -513,6 +513,7 @@ def test_standard_forwarded(app):
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert response.json == {"for": "127.0.0.2", "proto": "ws"} assert response.json == {"for": "127.0.0.2", "proto": "ws"}
assert request.remote_addr == "127.0.0.2" assert request.remote_addr == "127.0.0.2"
assert request.client_ip == "127.0.0.2"
assert request.scheme == "ws" assert request.scheme == "ws"
assert request.server_name == "local.site" assert request.server_name == "local.site"
assert request.server_port == 80 assert request.server_port == 80
@ -737,6 +738,7 @@ def test_remote_addr_with_two_proxies(app):
headers = {"X-Forwarded-For": "127.0.1.1"} headers = {"X-Forwarded-For": "127.0.1.1"}
request, response = app.test_client.get("/", headers=headers) request, response = app.test_client.get("/", headers=headers)
assert request.remote_addr == "" assert request.remote_addr == ""
assert request.client_ip == "127.0.0.1"
assert response.body == b"" assert response.body == b""
headers = {"X-Forwarded-For": "127.0.0.1, 127.0.1.2"} headers = {"X-Forwarded-For": "127.0.0.1, 127.0.1.2"}