diff libervia/server/proxy.py @ 1435:396d5606477f

server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
author Goffi <goffi@goffi.org>
date Mon, 14 Jun 2021 15:27:33 +0200
parents 822bd0139769
children fc91b78b71db
line wrap: on
line diff
--- a/libervia/server/proxy.py	Wed Jun 09 16:50:07 2021 +0200
+++ b/libervia/server/proxy.py	Mon Jun 14 15:27:33 2021 +0200
@@ -17,7 +17,9 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 from twisted.web import proxy
 from twisted.python.compat import urlquote
+from twisted.internet import address
 from sat.core.log import getLogger
+from libervia.server.constants import Const as C
 
 log = getLogger(__name__)
 
@@ -48,3 +50,29 @@
             self.path + b'/' + urlquote(path, safe=b"").encode('utf-8'),
             self.reactor
         )
+
+    def render(self, request):
+        # Forwarded and X-Forwarded-xxx headers can be set if we have behin an other proxy
+        if ((not request.getHeader(C.H_FORWARDED)
+             and not request.getHeader(C.H_X_FORWARDED_HOST))):
+            forwarded_data = []
+            addr = request.getClientAddress()
+            if ((isinstance(addr, address.IPv4Address)
+                 or isinstance(addr, address.IPv6Address))):
+                request.requestHeaders.setRawHeaders(C.H_X_FORWARDED_FOR, [addr.host])
+                forwarded_data.append(f"for={addr.host}")
+            host = request.getHeader("host")
+            if host is None:
+                port = request.getHost().port
+                hostname = request.getRequestHostname()
+                host = hostname if port in (80, 443) else f"{hostname}:{port}"
+            request.requestHeaders.setRawHeaders(C.H_X_FORWARDED_HOST, [host])
+            forwarded_data.append(f"host={host}")
+            proto = "https" if request.isSecure() else "http"
+            request.requestHeaders.setRawHeaders(C.H_X_FORWARDED_PROTO, [proto])
+            forwarded_data.append(f"proto={proto}")
+            request.requestHeaders.setRawHeaders(
+                C.H_FORWARDED, [";".join(forwarded_data)]
+            )
+
+        return super().render(request)