Skip to content

Commit

Permalink
Correctly handles site_root in Flask requests
Browse files Browse the repository at this point in the history
  • Loading branch information
smotornyuk committed Jun 27, 2019
1 parent e682fe5 commit d51c022
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
28 changes: 25 additions & 3 deletions ckan/lib/helpers.py
Expand Up @@ -306,7 +306,9 @@ def url_for(*args, **kw):
raise Exception('API URLs must specify the version (eg ver=3)')

_auto_flask_context = _get_auto_flask_context()

# If url generated by werkzeug, site_root will be prepended
# automatically.
is_url_generated_by_werkzeug = True
try:
if _auto_flask_context:
_auto_flask_context.push()
Expand All @@ -321,13 +323,15 @@ def url_for(*args, **kw):

# If it doesn't succeed, fallback to the Pylons router
my_url = _url_for_pylons(*args, **kw)
# Pylons does not add current site_root
is_url_generated_by_werkzeug = False
finally:
if _auto_flask_context:
_auto_flask_context.pop()

# Add back internal params
kw['__ckan_no_root'] = no_root

kw['__is_url_generated_by_werkzeug'] = is_url_generated_by_werkzeug
# Rewrite the URL to take the locale and root_path into account
return _local_url(my_url, locale=locale, **kw)

Expand Down Expand Up @@ -480,19 +484,38 @@ def _local_url(url_to_amend, **kw):
default_locale = False
locale = kw.pop('locale', None)
no_root = kw.pop('__ckan_no_root', False)

# Werkzeug adds generates url that includes enviroment variable
# SCRIPT_NAME. This means we have conflict with our custom logic
# that attaches site_root. Anyway, Werkzeug cannot handle current
# locale, so we are going to make some cleanup.
is_url_generated_by_werkzeug = kw.pop(
'__is_url_generated_by_werkzeug', False
)
is_script_name_added = False

allowed_locales = ['default'] + i18n.get_locales()
if locale and locale not in allowed_locales:
locale = None
if locale:
if locale == 'default':
default_locale = True
else:
# Test environment doesn't have request object configured
# in many cases, that's why next try/except block is required.
try:
locale = request.environ.get('CKAN_LANG')
default_locale = request.environ.get('CKAN_LANG_IS_DEFAULT', True)
script_name = request.environ.get('SCRIPT_NAME', None)
is_script_name_added = (
script_name and url_to_amend.startswith(script_name)
)
except TypeError:
default_locale = True

if is_url_generated_by_werkzeug and is_script_name_added:
url_to_amend = url_to_amend[len(script_name):]

root = ''
if kw.get('qualified', False) or kw.get('_external', False):
# if qualified is given we want the full url ie http://...
Expand Down Expand Up @@ -533,7 +556,6 @@ def _local_url(url_to_amend, **kw):
if url == '/packages':
error = 'There is a broken url being created %s' % kw
raise ckan.exceptions.CkanUrlException(error)

return url


Expand Down
10 changes: 10 additions & 0 deletions ckan/tests/lib/test_helpers.py
Expand Up @@ -206,6 +206,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):

Expand Down

0 comments on commit d51c022

Please sign in to comment.