From 18e3f8405a7b9d724f76ffcd07bbc56d194ccd9a Mon Sep 17 00:00:00 2001
From: Xavier Morel <xmo@odoo.com>
Date: Thu, 29 Aug 2019 07:06:03 +0000
Subject: [PATCH] [FIX] core: compatibility with Werkzeug 0.15 ProxyFix

Werkzeug 0.15 modified ProxyFix such that by default it only forwards
the REMOTE_ADDR when enabled, whereas before 0.15 it would also
forward scheme and host. This breaks proxied odoo as the base url
becomes incorrect (cf #34412).

Use properly configured ProxyFix when running with werkzeug 0.15, old
configuration otherwise.

Backport of 4057227def164f3c29c6d5546f1e8572dc0db573 which was merged
in master, because many people apparently run 0.15 now.

Closes #35085
closes odoo/odoo#36212

closes odoo/odoo#37708

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
---
 odoo/service/wsgi_server.py | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/odoo/service/wsgi_server.py b/odoo/service/wsgi_server.py
index 23acfefad03a..c29d91a2fbc4 100644
--- a/odoo/service/wsgi_server.py
+++ b/odoo/service/wsgi_server.py
@@ -121,8 +121,22 @@ def application_unproxied(environ, start_response):
     # We never returned from the loop.
     return werkzeug.exceptions.NotFound("No handler found.\n")(environ, start_response)
 
+try:
+    # werkzeug >= 0.15
+    from werkzeug.middleware.proxy_fix import ProxyFix as ProxyFix_
+    # 0.15 also supports port and prefix, but 0.14 only forwarded for, proto
+    # and host so replicate that
+    ProxyFix = lambda app: ProxyFix_(app, x_for=1, x_proto=1, x_host=1)
+except ImportError:
+    # werkzeug < 0.15
+    from werkzeug.contrib.fixers import ProxyFix
+
 def application(environ, start_response):
+    # FIXME: is checking for the presence of HTTP_X_FORWARDED_HOST really useful?
+    #        we're ignoring the user configuration, and that means we won't
+    #        support the standardised Forwarded header once werkzeug supports
+    #        it
     if config['proxy_mode'] and 'HTTP_X_FORWARDED_HOST' in environ:
-        return werkzeug.contrib.fixers.ProxyFix(application_unproxied)(environ, start_response)
+        return ProxyFix(application_unproxied)(environ, start_response)
     else:
         return application_unproxied(environ, start_response)
-- 
GitLab