Mercurial > libervia-web
changeset 1467:d6062cccd4c0
server: better reverse proxy headers handling:
reverse proxy header were not used if `X-Forwarded-Host` was not set, with this patch
`X-Forwarded-Host` and `X-Forwarded-Proto` are check independently. Furthermore, the new
standardised `Forwarded` header is not checked too.
fix 396
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 30 Sep 2021 18:40:49 +0200 (2021-09-30) |
parents | cff720e26089 |
children | e85ef5f3515e |
files | libervia/server/server.py |
diffstat | 1 files changed, 27 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/libervia/server/server.py Thu Sep 30 17:04:22 2021 +0200 +++ b/libervia/server/server.py Thu Sep 30 18:40:49 2021 +0200 @@ -1656,41 +1656,36 @@ """ ext_data = self.base_url_ext_data url_path = request.URLPath() - if not ext_data.scheme or not ext_data.netloc: - # ext_data is not specified, we check headers - if request.requestHeaders.hasHeader("x-forwarded-host"): - # we are behing a proxy - # we fill proxy_scheme and proxy_netloc value - proxy_host = request.requestHeaders.getRawHeaders("x-forwarded-host")[0] - try: - proxy_server = request.requestHeaders.getRawHeaders( - "x-forwarded-server" - )[0] - except TypeError: - # no x-forwarded-server found, we use proxy_host - proxy_netloc = proxy_host - else: - # if the proxy host has a port, we use it with server name - proxy_port = urllib.parse.urlsplit("//{}".format(proxy_host)).port - proxy_netloc = ( - "{}:{}".format(proxy_server, proxy_port) - if proxy_port is not None - else proxy_server - ) - try: - proxy_scheme = request.requestHeaders.getRawHeaders( - "x-forwarded-proto" - )[0] - except TypeError: - proxy_scheme = None - else: - proxy_scheme, proxy_netloc = None, None + + try: + forwarded = request.requestHeaders.getRawHeaders( + "forwarded" + )[0] + except TypeError: + # we try deprecated headers + try: + proxy_netloc = request.requestHeaders.getRawHeaders( + "x-forwarded-host" + )[0] + except TypeError: + proxy_netloc = None + try: + proxy_scheme = request.requestHeaders.getRawHeaders( + "x-forwarded-proto" + )[0] + except TypeError: + proxy_scheme = None else: - proxy_scheme, proxy_netloc = None, None + fwd_data = { + k.strip(): v.strip() + for k,v in (d.split("=") for d in forwarded.split(";")) + } + proxy_netloc = fwd_data.get("host") + proxy_scheme = fwd_data.get("proto") return urllib.parse.SplitResult( - ext_data.scheme or proxy_scheme or url_path.scheme.decode("utf-8"), - ext_data.netloc or proxy_netloc or url_path.netloc.decode("utf-8"), + ext_data.scheme or proxy_scheme or url_path.scheme.decode(), + ext_data.netloc or proxy_netloc or url_path.netloc.decode(), ext_data.path or "/", "", "",