changeset 7716:a4a4bcc09ac5

middleware: remove access fallback to reuse previous access - drop _git_stored_op Before, the previous action was kept in the global controller instance. That was conceptually wrong. The previous request might be entirely unrelated, coming from another user. It was mainly used for 'info/refs' commands ... but even more, that will be the first command that is sent, giving nothing relevant to reuse. Fortunately, with handling of 'info/refs', we no longer seem to need it. The fallback for unknown commands with unknown 'action' is now to return a HTTP failure, like we do for Mercurial.
author Mads Kiilerich <mads@kiilerich.com>
date Mon, 07 Jan 2019 02:08:35 +0100
parents a444c46a0649
children 8d0362047e29
files kallithea/lib/middleware/simplegit.py
diffstat 1 files changed, 15 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/lib/middleware/simplegit.py	Mon Jan 07 01:58:16 2019 +0100
+++ b/kallithea/lib/middleware/simplegit.py	Mon Jan 07 02:08:35 2019 +0100
@@ -34,7 +34,7 @@
 import traceback
 
 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError, \
-    HTTPNotAcceptable
+    HTTPNotAcceptable, HTTPBadRequest
 from kallithea.model.db import Ui
 
 from kallithea.lib.utils2 import safe_str, safe_unicode, get_server_url, \
@@ -60,8 +60,6 @@
 
 class SimpleGit(BaseVCSController):
 
-    _git_stored_op = 'pull' # most recent kind of command
-
     def _handle_request(self, environ, start_response):
         if not is_git(environ):
             return self.application(environ, start_response)
@@ -149,6 +147,8 @@
     def __get_action(self, environ):
         """
         Maps Git request commands into 'pull' or 'push'.
+
+        Raises HTTPBadRequest if the request environment doesn't look like a git client.
         """
         mapping = {
             'git-receive-pack': 'push',
@@ -156,18 +156,19 @@
         }
         path_info = environ.get('PATH_INFO', '')
         m = GIT_PROTO_PAT.match(path_info)
-        if m is not None:
+        if m is None:
+            action = None
+        else:
             cmd = m.group(2)
-            if cmd == 'info/refs':
-                service = environ['QUERY_STRING'].split('=')
-                cmd = service[1] if len(service) > 1 else None
-                if cmd in mapping:
-                    self._git_stored_op = mapping[cmd]
-            elif cmd in mapping:
-                self._git_stored_op = mapping[cmd]
-        # fallback to stored variable as we don't know if the last
-        # operation is pull/push
-        return self._git_stored_op
+            query_string = environ['QUERY_STRING']
+            if cmd == 'info/refs' and query_string.startswith('service='):
+                service = query_string.split('=', 1)[1]
+                action = mapping.get(service)
+            else:
+                action = mapping.get(cmd)
+        if action is None:
+            raise HTTPBadRequest('Unable to detect pull/push action for %r! Are you using a nonstandard command or client?' % path_info)
+        return action
 
     def _handle_githooks(self, repo_name, action, baseui, environ):
         """