diff --git a/docs/setup.rst b/docs/setup.rst --- a/docs/setup.rst +++ b/docs/setup.rst @@ -514,13 +514,15 @@ In order to start using celery run:: HTTPS support ------------- -There are two ways to enable https: +Kallithea will by default generate URLs based on the WSGI environment. + +Alternatively, you can use some special configuration settings to control +directly which scheme/protocol Kallithea will use when generating URLs: -- Set HTTP_X_URL_SCHEME in your http server headers, than Kallithea will - recognize this headers and make proper https redirections -- Alternatively, change the `force_https = true` flag in the ini configuration - to force using https, no headers are needed than to enable https - +- With `https_fixup = true`, the scheme will be taken from the HTTP_X_URL_SCHEME, + HTTP_X_FORWARDED_SCHEME or HTTP_X_FORWARDED_PROTO HTTP header (default 'http'). +- With `force_https = true` the default will be 'https'. +- With `use_htsts = true`, it will set Strict-Transport-Security when using https. Nginx virtual host example -------------------------- diff --git a/kallithea/config/middleware.py b/kallithea/config/middleware.py --- a/kallithea/config/middleware.py +++ b/kallithea/config/middleware.py @@ -92,7 +92,8 @@ def make_app(global_conf, full_stack=Tru app = StatusCodeRedirect(app, [400, 401, 403, 404, 500]) #enable https redirets based on HTTP_X_URL_SCHEME set by proxy - app = HttpsFixup(app, config) + if any(asbool(config.get(x)) for x in ['https_fixup', 'force_ssl', 'use_htsts']): + app = HttpsFixup(app, config) # Establish the Registry for this application app = RegistryManager(app) diff --git a/kallithea/lib/base.py b/kallithea/lib/base.py --- a/kallithea/lib/base.py +++ b/kallithea/lib/base.py @@ -213,18 +213,18 @@ class BaseVCSController(object): def _get_ip_addr(self, environ): return _get_ip_addr(environ) - def _check_ssl(self, environ, start_response): + def _check_ssl(self, environ): """ Checks the SSL check flag and returns False if SSL is not present and required True otherwise """ - org_proto = environ['wsgi._org_proto'] #check if we have SSL required ! if not it's a bad request ! - require_ssl = str2bool(Ui.get_by_key('push_ssl').ui_value) - if require_ssl and org_proto == 'http': - log.debug('proto is %s and SSL is required BAD REQUEST !' - % org_proto) - return False + if str2bool(Ui.get_by_key('push_ssl').ui_value): + org_proto = environ.get('wsgi._org_proto', environ['wsgi.url_scheme']) + if org_proto != 'https': + log.debug('proto is %s and SSL is required BAD REQUEST !' + % org_proto) + return False return True def _check_locking_state(self, environ, action, repo, user_id): diff --git a/kallithea/lib/middleware/simplegit.py b/kallithea/lib/middleware/simplegit.py --- a/kallithea/lib/middleware/simplegit.py +++ b/kallithea/lib/middleware/simplegit.py @@ -66,7 +66,7 @@ class SimpleGit(BaseVCSController): def _handle_request(self, environ, start_response): if not is_git(environ): return self.application(environ, start_response) - if not self._check_ssl(environ, start_response): + if not self._check_ssl(environ): return HTTPNotAcceptable('SSL REQUIRED !')(environ, start_response) ip_addr = self._get_ip_addr(environ) diff --git a/kallithea/lib/middleware/simplehg.py b/kallithea/lib/middleware/simplehg.py --- a/kallithea/lib/middleware/simplehg.py +++ b/kallithea/lib/middleware/simplehg.py @@ -71,7 +71,7 @@ class SimpleHg(BaseVCSController): def _handle_request(self, environ, start_response): if not is_mercurial(environ): return self.application(environ, start_response) - if not self._check_ssl(environ, start_response): + if not self._check_ssl(environ): return HTTPNotAcceptable('SSL REQUIRED !')(environ, start_response) ip_addr = self._get_ip_addr(environ)