diff --git a/sirepo/http_util.py b/sirepo/http_util.py index bf09b34e38..08d1d9d210 100644 --- a/sirepo/http_util.py +++ b/sirepo/http_util.py @@ -46,3 +46,18 @@ def parse_auth_header(headers): if m := _AUTH_HEADER_RE.search(h): return m.group(1) return None + + +def remote_ip(request): + """IP address of client from request. + + Tornado covers 'X-Real-Ip' and 'X-Forwared-For'. This adds addition + headers to check. + + Args: + request (tornado.httputil.HTTPServerRequest): Incoming request + Returns: + str: IP address of client + + """ + return request.headers.get("proxy-for", request.remote_ip) diff --git a/sirepo/pkcli/job_supervisor.py b/sirepo/pkcli/job_supervisor.py index 76046be29c..e2a6762ad6 100644 --- a/sirepo/pkcli/job_supervisor.py +++ b/sirepo/pkcli/job_supervisor.py @@ -15,6 +15,7 @@ import sirepo.events import sirepo.feature_config import sirepo.global_resources.api +import sirepo.http_util import sirepo.job import sirepo.job_driver import sirepo.job_supervisor @@ -97,7 +98,7 @@ def open(self): pkdlog( "uri={} remote_ip={} ", self.request.uri, - self.request.remote_ip, + sirepo.http_util.remote_ip(self.request), ) def sr_close(self): diff --git a/sirepo/request.py b/sirepo/request.py index df03b1eed9..f2a02b8549 100644 --- a/sirepo/request.py +++ b/sirepo/request.py @@ -11,9 +11,9 @@ import pykern.pkcompat import pykern.pkjson import sirepo.const +import sirepo.http_util import sirepo.quest import sirepo.util -import urllib.parse import user_agents @@ -186,7 +186,7 @@ def _parse_authorization(value): http_method=r.method, http_request_uri=r.full_url(), http_server_uri=f"{r.protocol}://{r.host}/", - remote_addr=r.remote_ip, + remote_addr=sirepo.http_util.remote_ip(r), ) def body_as_bytes(self): diff --git a/sirepo/uri_router.py b/sirepo/uri_router.py index a51487518a..7d90090b50 100644 --- a/sirepo/uri_router.py +++ b/sirepo/uri_router.py @@ -7,25 +7,21 @@ from pykern import pkcollections from pykern import pkconfig from pykern import pkinspect -from pykern import pkjson from pykern.pkcollections import PKDict from pykern.pkdebug import pkdc, pkdexc, pkdlog, pkdp, pkdformat import asyncio -import contextlib import importlib import inspect -import os -import pkgutil import re import sirepo.api_auth import sirepo.auth import sirepo.const import sirepo.events import sirepo.feature_config +import sirepo.http_util import sirepo.spa_session import sirepo.uri import sirepo.util -import urllib.parse #: prefix for api functions _FUNC_PREFIX = "api_" @@ -225,7 +221,7 @@ def open(self): self.__headers = PKDict(r.headers) self.cookie_state = self.__headers.get("Cookie") self.http_server_uri = f"{r.protocol}://{r.host}/" - self.remote_addr = r.remote_ip + self.remote_addr = sirepo.http_util.remote_ip(r) self.ws_id = ws_count self.sr_log(None, "open", fmt=" ip={}", args=[_remote_peer(r)]) @@ -354,7 +350,7 @@ def _remote_peer(request): # socket is not set on stream for websockets. if hasattr(c, "stream") and hasattr(c.stream, "socket"): return "{}:{}".format(*c.stream.socket.getpeername()) - return f"{request.remote_ip}:0" + return f"{sirepo.http_util.remote_ip(request)}:0" sirepo.modules.import_and_init("sirepo.server").init_tornado() s = httpserver.HTTPServer(