diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index 96db4741..294ee110 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -280,8 +280,10 @@ class Server(): app.wsgi_app, settings().get(["server", "reverseProxy", "prefixHeader"]), settings().get(["server", "reverseProxy", "schemeHeader"]), + settings().get(["server", "reverseProxy", "hostHeader"]), settings().get(["server", "reverseProxy", "prefixFallback"]), - settings().get(["server", "reverseProxy", "prefixScheme"]) + settings().get(["server", "reverseProxy", "schemeFallback"]), + settings().get(["server", "reverseProxy", "hostFallback"]) ) secret_key = settings().get(["server", "secretKey"]) diff --git a/src/octoprint/server/util/__init__.py b/src/octoprint/server/util/__init__.py index 83c246cc..b6902269 100644 --- a/src/octoprint/server/util/__init__.py +++ b/src/octoprint/server/util/__init__.py @@ -147,20 +147,25 @@ class ReverseProxied(object): :param app: the WSGI application :param header_script_name: the HTTP header in the wsgi environment from which to determine the prefix :param header_scheme: the HTTP header in the wsgi environment from which to determine the scheme + :param header_host: the HTTP header in the wsgi environment from which to determine the host for which to generate external URLs :param base_url: the prefix to use as fallback if headers are not set + :param scheme: the scheme to use as fallback if headers are not set + :param host: the host to use as fallback if headers are not set """ - def __init__(self, app, header_prefix="x-script-name", header_scheme="x-scheme", base_url="", scheme=""): + def __init__(self, app, header_prefix="x-script-name", header_scheme="x-scheme", header_host="x-forwarded-host", base_url="", scheme="", host=""): self.app = app - # headers for prefix & scheme, converted to conform to WSGI format + # headers for prefix & scheme & host, converted to conform to WSGI format to_wsgi_format = lambda header: "HTTP_" + header.upper().replace("-", "_") self._header_prefix = to_wsgi_format(header_prefix) self._header_scheme = to_wsgi_format(header_scheme) + self._header_host = to_wsgi_format(header_host) - # fallback prefix & scheme from config + # fallback prefix & scheme & host from config self._fallback_prefix = base_url self._fallback_scheme = scheme + self._fallback_host = host def __call__(self, environ, start_response): # determine prefix @@ -184,6 +189,15 @@ class ReverseProxied(object): if scheme: environ["wsgi.url_scheme"] = scheme + # determine host + host = environ.get(self._header_host, "") + if not host: + host = self._fallback_host + + # rewrite host header based on host + if host: + environ["HTTP_HOST"] = host + # call wrapped app with rewritten environment return self.app(environ, start_response)