changeset 6387:aaacb075c3f3

hg: return 400 Bad Request for hg commands that not are commands Avoid throwing bare Exceptions which requires framework specific testing. Instead, return a reasonable http error code and make the test more framework independent. The "helpful" message will just be a description of the http exception and not sent to the client.
author Mads Kiilerich <mads@kiilerich.com>
date Wed, 04 Jan 2017 23:16:08 +0100
parents 1341be63734a
children a04ff65be3f6
files kallithea/lib/middleware/simplehg.py kallithea/tests/functional/test_admin_repos.py
diffstat 2 files changed, 15 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/lib/middleware/simplehg.py	Mon Jan 02 21:43:53 2017 +0100
+++ b/kallithea/lib/middleware/simplehg.py	Wed Jan 04 23:16:08 2017 +0100
@@ -34,7 +34,7 @@
 
 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError, \
-    HTTPNotAcceptable
+    HTTPNotAcceptable, HTTPBadRequest
 from kallithea.model.db import User
 
 from kallithea.lib.utils2 import safe_str, safe_unicode, fix_PATH, get_server_url, \
@@ -65,7 +65,6 @@
     )
     return ishg_path
 
-
 class SimpleHg(BaseVCSController):
 
     def _handle_request(self, environ, start_response):
@@ -97,7 +96,10 @@
         #======================================================================
         # GET ACTION PULL or PUSH
         #======================================================================
-        action = self.__get_action(environ)
+        try:
+            action = self.__get_action(environ)
+        except HTTPBadRequest as e:
+            return e(environ, start_response)
 
         #======================================================================
         # CHECK ANONYMOUS PERMISSION
@@ -259,27 +261,19 @@
 
     def __get_action(self, environ):
         """
-        Maps mercurial request commands into a clone,pull or push command.
-        This should always return a valid command string
+        Maps mercurial request commands into a pull or push command.
 
-        :param environ:
+        Raises HTTPBadRequest if the request environment doesn't look like a hg client.
         """
-        mapping = {'changegroup': 'pull',
-                   'changegroupsubset': 'pull',
-                   'stream_out': 'pull',
-                   'listkeys': 'pull',
-                   'unbundle': 'push',
-                   'pushkey': 'push', }
+        mapping = {'unbundle': 'push',
+                   'pushkey': 'push'}
         for qry in environ['QUERY_STRING'].split('&'):
             if qry.startswith('cmd'):
                 cmd = qry.split('=')[-1]
-                if cmd in mapping:
-                    return mapping[cmd]
+                return mapping.get(cmd, 'pull')
 
-                return 'pull'
-
-        raise Exception('Unable to detect pull/push action !!'
-                        'Are you using non standard command or client ?')
+        # Note: the client doesn't get the helpful error message
+        raise HTTPBadRequest('Unable to detect pull/push action! Are you using non standard command or client?')
 
     def __inject_extras(self, repo_path, baseui, extras=None):
         """
--- a/kallithea/tests/functional/test_admin_repos.py	Mon Jan 02 21:43:53 2017 +0100
+++ b/kallithea/tests/functional/test_admin_repos.py	Wed Jan 04 23:16:08 2017 +0100
@@ -612,6 +612,6 @@
     OTHER_TYPE = 'git'
 
     def test_permanent_url_protocol_access(self):
-        with pytest.raises(Exception) as e:
-            self.app.get(url('summary_home', repo_name='_1'), extra_environ={'HTTP_ACCEPT': 'application/mercurial'})
-        assert 'Unable to detect pull/push action' in str(e)
+        # 400 Bad Request - Unable to detect pull/push action
+        self.app.get(url('summary_home', repo_name='_1'), extra_environ={'HTTP_ACCEPT': 'application/mercurial'},
+                     status=400)