Blob Blame History Raw
From 18872bf5807c96e78dc25b420fac54ac7c09e4a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Harald=20Jens=C3=A5s?= <hjensas@redhat.com>
Date: Mon, 18 Oct 2021 20:09:29 +0200
Subject: [PATCH] ProxyFix supports IPv6

---
 src/werkzeug/middleware/proxy_fix.py | 14 +++++++-------
 tests/middleware/test_proxy_fix.py   | 18 ++++++++++++++++++
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/werkzeug/middleware/proxy_fix.py b/src/werkzeug/middleware/proxy_fix.py
index e90b1b34..4cef7cc8 100644
--- a/src/werkzeug/middleware/proxy_fix.py
+++ b/src/werkzeug/middleware/proxy_fix.py
@@ -163,18 +163,18 @@ class ProxyFix:
 
         x_host = self._get_real_value(self.x_host, environ_get("HTTP_X_FORWARDED_HOST"))
         if x_host:
-            environ["HTTP_HOST"] = x_host
-            parts = x_host.split(":", 1)
-            environ["SERVER_NAME"] = parts[0]
-            if len(parts) == 2:
-                environ["SERVER_PORT"] = parts[1]
+            environ["HTTP_HOST"] = environ["SERVER_NAME"] = x_host
+            # "]" to check for IPv6 address without port
+            if ":" in x_host and not x_host.endswith("]"):
+                environ["SERVER_NAME"], environ["SERVER_PORT"] = x_host.rsplit(":", 1)
 
         x_port = self._get_real_value(self.x_port, environ_get("HTTP_X_FORWARDED_PORT"))
         if x_port:
             host = environ.get("HTTP_HOST")
             if host:
-                parts = host.split(":", 1)
-                host = parts[0] if len(parts) == 2 else host
+                # "]" to check for IPv6 address without port
+                if ":" in host and not host.endswith("]"):
+                    host = host.rsplit(":", 1)[0]
                 environ["HTTP_HOST"] = f"{host}:{x_port}"
             environ["SERVER_PORT"] = x_port
 
diff --git a/tests/middleware/test_proxy_fix.py b/tests/middleware/test_proxy_fix.py
index 8fc1310d..abbc05c3 100644
--- a/tests/middleware/test_proxy_fix.py
+++ b/tests/middleware/test_proxy_fix.py
@@ -138,6 +138,24 @@ from werkzeug.wrappers import Request
             "http://spam/eggs/",
             id="prefix < for",
         ),
+        pytest.param(
+            {"x_host": 1},
+            {"HTTP_HOST": "spam", "HTTP_X_FORWARDED_HOST": "[2001:db8::a]"},
+            "http://[2001:db8::a]/",
+            id="ipv6 host",
+        ),
+        pytest.param(
+            {"x_port": 1},
+            {"HTTP_HOST": "[2001:db8::a]", "HTTP_X_FORWARDED_PORT": "8080"},
+            "http://[2001:db8::a]:8080/",
+            id="ipv6 port, host without port",
+        ),
+        pytest.param(
+            {"x_port": 1},
+            {"HTTP_HOST": "[2001:db8::a]:9000", "HTTP_X_FORWARDED_PORT": "8080"},
+            "http://[2001:db8::a]:8080/",
+            id="ipv6 - port, host with port",
+        ),
     ),
 )
 def test_proxy_fix(kwargs, base, url_root):
-- 
2.34.1