Repository: ckan/ckan

Issue:
CKAN root path repeated in URL
### CKAN Version if known (or site URL)
2.8.0

### Please describe the expected behaviour

We have a CKAN site that should be accessed via http://192.168.183.128/data
The expected CKAN URL should be http://192.168.183.128/data/<ckan_page>

### Please describe the actual behaviour

When viewing some of the CKAN pages in a browser, the url root is repeated.
Therefore the site cannot be reached.

The browser tries to access http://192.168.183.128/data/data/<ckan_page>

Examples are the login, logout and admin pages
http://192.168.183.128/data/data/user/login
http://192.168.183.128/data/data/user/logged_out_redirect
http://192.168.183.128/data/data/user/ckan_admin

Once logged in, the URLs are correct for dataset, organization, group etc pages.

### What steps can be taken to reproduce the issue? 

production.ini:
ckan.site_url http://192.168.183.128
ckan.root_path = /data/{{LANG}}

ckan_default.conf:
WSGIScriptAlias /data /etc/ckan/default/apache.wsgi

datapusher.conf:
WSGIScriptAlias /data /etc/ckan/datapusher.wsgi



Discussion:

Resolving patch:
diff --git a/ckan/config/middleware/flask_app.py b/ckan/config/middleware/flask_app.py
--- a/ckan/config/middleware/flask_app.py
+++ b/ckan/config/middleware/flask_app.py
@@ -367,8 +367,8 @@ def can_handle_request(self, environ):
         `origin` can be either 'core' or 'extension' depending on where
         the route was defined.
         '''
-
         urls = self.url_map.bind_to_environ(environ)
+
         try:
             rule, args = urls.match(return_rule=True)
             origin = 'core'
@@ -376,6 +376,12 @@ def can_handle_request(self, environ):
                 origin = 'extension'
             log.debug('Flask route match, endpoint: {0}, args: {1}, '
                       'origin: {2}'.format(rule.endpoint, args, origin))
+
+            # Disable built-in flask's ability to prepend site root to
+            # generated url, as we are going to use locale and existing
+            # logic is not flexible enough for this purpose
+            environ['SCRIPT_NAME'] = ''
+
             return (True, self.app_name, origin)
         except HTTPException:
             return (False, self.app_name)


Test patch:
diff --git a/ckan/tests/lib/test_helpers.py b/ckan/tests/lib/test_helpers.py
--- a/ckan/tests/lib/test_helpers.py
+++ b/ckan/tests/lib/test_helpers.py
@@ -199,6 +199,16 @@ def test_url_for_qualified_with_root_path_locale_and_script_name_env(self):
                                   locale='de')
         eq_(generated_url, url)
 
+    @helpers.set_extra_environ('SCRIPT_NAME', '/my/custom/path')
+    @helpers.change_config('ckan.site_url', 'http://example.com')
+    @helpers.change_config('ckan.root_path', '/my/custom/path/{{LANG}}/foo')
+    def test_url_for_with_root_path_locale_and_script_name_env(self):
+        url = '/my/custom/path/de/foo/dataset/my_dataset'
+        generated_url = h.url_for('dataset.read',
+                                  id='my_dataset',
+                                  locale='de')
+        eq_(generated_url, url)
+
 
 class TestHelpersUrlForFlaskandPylons2(BaseUrlFor):