aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilo Casagrande <milo@ubuntu.com>2013-04-24 14:38:43 +0200
committerMilo Casagrande <milo@ubuntu.com>2013-04-24 14:38:43 +0200
commit1972750d264d61b1f7da4dccaadfb6a24a2f9d1f (patch)
tree55db2dd654d314cdd9325276375efc068305d25e
parentbe5dd6f02451ad548fb05a30db1414d59558bbf7 (diff)
Added caching mechanism.
-rw-r--r--rhodecode/lib/middleware/simplegit.py79
1 files changed, 44 insertions, 35 deletions
diff --git a/rhodecode/lib/middleware/simplegit.py b/rhodecode/lib/middleware/simplegit.py
index 94d763f4..03f8d2d7 100644
--- a/rhodecode/lib/middleware/simplegit.py
+++ b/rhodecode/lib/middleware/simplegit.py
@@ -33,6 +33,7 @@ from dulwich import server as dulserver
from dulwich.web import LimitedInputFilter, GunzipFilter
from rhodecode.lib.exceptions import HTTPLockedRC
from rhodecode.lib.hooks import pre_pull
+from rhodecode.lib.cache import Cache
class SimpleGitUploadPackHandler(dulserver.UploadPackHandler):
@@ -65,10 +66,10 @@ class SimpleGitUploadPackHandler(dulserver.UploadPackHandler):
dulserver.DEFAULT_HANDLERS = {
- #git-ls-remote, git-clone, git-fetch and git-pull
- 'git-upload-pack': SimpleGitUploadPackHandler,
- #git-push
- 'git-receive-pack': dulserver.ReceivePackHandler,
+ #git-ls-remote, git-clone, git-fetch and git-pull
+ 'git-upload-pack': SimpleGitUploadPackHandler,
+ #git-push
+ 'git-receive-pack': dulserver.ReceivePackHandler,
}
# not used for now until dulwich get's fixed
@@ -77,7 +78,7 @@ dulserver.DEFAULT_HANDLERS = {
from paste.httpheaders import REMOTE_USER, AUTH_TYPE
from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError, \
- HTTPBadRequest, HTTPNotAcceptable
+ HTTPNotAcceptable
from rhodecode.lib.utils2 import safe_str, fix_PATH, get_server_url
from rhodecode.lib.base import BaseVCSController
@@ -92,41 +93,44 @@ log = logging.getLogger(__name__)
GIT_PROTO_PAT = re.compile(r'^/(.+)/(info/refs|git-upload-pack|git-receive-pack|HEAD|objects)')
-def is_git(environ):
- path_info = environ['PATH_INFO']
+def is_git(path_info):
isgit_path = GIT_PROTO_PAT.match(path_info)
- log.debug('pathinfo: %s detected as GIT %s' % (
- path_info, isgit_path != None)
- )
+ log.debug('pathinfo: %s detected as GIT %s' % (path_info,
+ isgit_path is not None))
return isgit_path
class SimpleGit(BaseVCSController):
+ # Cache to store apps created, in order to reuse the same one.
+ # Introduced by Linaro.
+ app_cache = Cache()
+
def _handle_request(self, environ, start_response):
- if not is_git(environ):
+ git_path = environ['PATH_INFO']
+
+ if not is_git(git_path):
return self.application(environ, start_response)
if not self._check_ssl(environ, start_response):
- return HTTPNotAcceptable('SSL REQUIRED !')(environ, start_response)
-
- ip_addr = self._get_ip_addr(environ)
- username = None
- self._git_first_op = False
- # skip passing error to error controller
- environ['pylons.status_code_redirect'] = True
+ return HTTPNotAcceptable('SSL REQUIRED!')(environ, start_response)
#======================================================================
# EXTRACT REPOSITORY NAME FROM ENV
#======================================================================
try:
- repo_name = self.__get_repository(environ)
+ repo_name = self.__get_repository(environ, git_path)
log.debug('Extracted repo name is %s' % repo_name)
+ # quick check if that dir exists...
+ if not is_valid_repo(repo_name, self.basepath, 'git'):
+ return HTTPNotFound()(environ, start_response)
except:
return HTTPInternalServerError()(environ, start_response)
- # quick check if that dir exists...
- if is_valid_repo(repo_name, self.basepath, 'git') is False:
- return HTTPNotFound()(environ, start_response)
+ ip_addr = self._get_ip_addr(environ)
+ username = None
+ self._git_first_op = False
+ # skip passing error to error controller
+ environ['pylons.status_code_redirect'] = True
#======================================================================
# GET ACTION PULL or PUSH
@@ -174,7 +178,7 @@ class SimpleGit(BaseVCSController):
#==============================================================
try:
user = self.__get_user(username)
- if user is None or not user.active:
+ if not user or not user.active:
return HTTPForbidden()(environ, start_response)
username = user.username
except:
@@ -183,7 +187,7 @@ class SimpleGit(BaseVCSController):
#check permissions for this repository
perm = self._check_permission(action, user, repo_name, ip_addr)
- if perm is not True:
+ if not perm:
return HTTPForbidden()(environ, start_response)
# extras are injected into UI object and later available
@@ -251,25 +255,30 @@ class SimpleGit(BaseVCSController):
:param repo_name: name of the repository
:param repo_path: full path to the repository
"""
-
- from rhodecode.lib.middleware.pygrack import make_wsgi_app
- app = make_wsgi_app(
- repo_root=safe_str(self.basepath),
- repo_name=repo_name,
- extras=extras,
- )
- app = GunzipFilter(LimitedInputFilter(app))
+ key = self.app_cache.key(repo_name, repo_path, extras)
+ app = self.app_cache[key]
+
+ if not app:
+ from rhodecode.lib.middleware.pygrack import make_wsgi_app
+ app = make_wsgi_app(
+ repo_root=safe_str(self.basepath),
+ repo_name=repo_name,
+ extras=extras,
+ )
+ app = GunzipFilter(LimitedInputFilter(app))
+ self.app_cache[key] = app
return app
- def __get_repository(self, environ):
+ def __get_repository(self, environ, path_info):
"""
Get's repository name out of PATH_INFO header
:param environ: environ where PATH_INFO is stored
"""
try:
- environ['PATH_INFO'] = self._get_by_id(environ['PATH_INFO'])
- repo_name = GIT_PROTO_PAT.match(environ['PATH_INFO']).group(1)
+ path_info = self._get_by_id(path_info)
+ environ['PATH_INFO'] = path_info
+ repo_name = GIT_PROTO_PAT.match(path_info).group(1)
except:
log.error(traceback.format_exc())
raise