diff --git a/rhodecode/lib/hooks_daemon.py b/rhodecode/lib/hooks_daemon.py --- a/rhodecode/lib/hooks_daemon.py +++ b/rhodecode/lib/hooks_daemon.py @@ -31,7 +31,8 @@ import pylons import rhodecode from rhodecode.lib import hooks_base -from rhodecode.lib.utils2 import AttributeDict +from rhodecode.lib.utils2 import ( + AttributeDict, safe_str, get_routes_generator_for_server_url) log = logging.getLogger(__name__) @@ -240,16 +241,7 @@ class Hooks(object): def _call_hook(self, hook, extras): extras = AttributeDict(extras) - netloc = urlparse.urlparse(extras.server_url).netloc - environ = { - 'SERVER_NAME': netloc.split(':')[0], - 'SERVER_PORT': ':' in netloc and netloc.split(':')[1] or '80', - 'SCRIPT_NAME': '', - 'PATH_INFO': '/', - 'HTTP_HOST': 'localhost', - 'REQUEST_METHOD': 'GET', - } - pylons_router = URLGenerator(rhodecode.CONFIG['routes.map'], environ) + pylons_router = get_routes_generator_for_server_url(extras.server_url) pylons.url._push_object(pylons_router) try: diff --git a/rhodecode/lib/utils2.py b/rhodecode/lib/utils2.py --- a/rhodecode/lib/utils2.py +++ b/rhodecode/lib/utils2.py @@ -41,6 +41,7 @@ import pygments.lexers import sqlalchemy import sqlalchemy.engine.url import webob +import routes.util import rhodecode @@ -858,3 +859,28 @@ class Optional(object): if isinstance(val, cls): return val.getval() return val + + +def get_routes_generator_for_server_url(server_url): + parsed_url = urlobject.URLObject(server_url) + netloc = safe_str(parsed_url.netloc) + script_name = safe_str(parsed_url.path) + + if ':' in netloc: + server_name, server_port = netloc.split(':') + else: + server_name = netloc + server_port = (parsed_url.scheme == 'https' and '443' or '80') + + environ = { + 'REQUEST_METHOD': 'GET', + 'PATH_INFO': '/', + 'SERVER_NAME': server_name, + 'SERVER_PORT': server_port, + 'SCRIPT_NAME': script_name, + } + if parsed_url.scheme == 'https': + environ['HTTPS'] = 'on' + environ['wsgi.url_scheme'] = 'https' + + return routes.util.URLGenerator(rhodecode.CONFIG['routes.map'], environ) diff --git a/rhodecode/model/pull_request.py b/rhodecode/model/pull_request.py --- a/rhodecode/model/pull_request.py +++ b/rhodecode/model/pull_request.py @@ -750,7 +750,7 @@ class PullRequestModel(BaseModel): def get_url(self, pull_request): return h.url('pullrequest_show', - repo_name=pull_request.target_repo.repo_name, + repo_name=safe_str(pull_request.target_repo.repo_name), pull_request_id=pull_request.pull_request_id, qualified=True) diff --git a/rhodecode/model/repo.py b/rhodecode/model/repo.py --- a/rhodecode/model/repo.py +++ b/rhodecode/model/repo.py @@ -142,7 +142,8 @@ class RepoModel(BaseModel): return None def get_url(self, repo): - return h.url('summary_home', repo_name=repo.repo_name, qualified=True) + return h.url('summary_home', repo_name=safe_str(repo.repo_name), + qualified=True) def get_users(self, name_contains=None, limit=20, only_active=True): # TODO: mikhail: move this method to the UserModel. diff --git a/rhodecode/tests/lib/test_utils2.py b/rhodecode/tests/lib/test_utils2.py --- a/rhodecode/tests/lib/test_utils2.py +++ b/rhodecode/tests/lib/test_utils2.py @@ -18,9 +18,41 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ -from rhodecode.lib.utils2 import obfuscate_url_pw +import pytest + +from rhodecode.lib.utils2 import ( + obfuscate_url_pw, get_routes_generator_for_server_url) def test_obfuscate_url_pw(): engine = u'/home/repos/malmö' assert obfuscate_url_pw(engine) + + +@pytest.mark.parametrize('scheme', ['https', 'http']) +@pytest.mark.parametrize('domain', [ + 'www.test.com', 'test.com', 'test.co.uk', '192.168.1.3']) +@pytest.mark.parametrize('port', [None, '80', '443', '999']) +@pytest.mark.parametrize('script_path', [None, '/', '/prefix', '/prefix/more']) +def test_routes_generator(pylonsapp, scheme, domain, port, script_path): + server_url = '%s://%s' % (scheme, domain) + if port is not None: + server_url += ':' + port + if script_path: + server_url += script_path + + + expected_url = '%s://%s' % (scheme, domain) + if scheme == 'https': + if port not in (None, '443'): + expected_url += ':' + port + elif scheme == 'http': + if port not in ('80', None): + expected_url += ':' + port + + if script_path: + expected_url = (expected_url + script_path).rstrip('/') + + url_generator = get_routes_generator_for_server_url(server_url) + assert url_generator( + '/a_test_path', qualified=True) == expected_url + '/a_test_path'