@@ -6,123 +6,134 @@
SimpleGit middleware for handling git protocol request (push/clone etc.)
It's implemented with basic auth function
:created_on: Apr 28, 2010
:author: marcink
:copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
:license: GPLv3, see COPYING for more details.
"""
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import logging
import traceback
import time
from dulwich import server as dulserver
class SimpleGitUploadPackHandler(dulserver.UploadPackHandler):
def handle(self):
write = lambda x: self.proto.write_sideband(1, x)
graph_walker = dulserver.ProtocolGraphWalker(self,
self.repo.object_store,
self.repo.get_peeled)
objects_iter = self.repo.fetch_objects(
graph_walker.determine_wants, graph_walker, self.progress,
get_tagged=self.get_tagged)
# Do they want any objects?
if objects_iter is None or len(objects_iter) == 0:
return
self.progress("counting objects: %d, done.\n" % len(objects_iter))
dulserver.write_pack_objects(dulserver.ProtocolFile(None, write),
objects_iter, len(objects_iter))
messages = []
messages.append('thank you for using rhodecode')
for msg in messages:
self.progress(msg + "\n")
# we are done
self.proto.write("0000")
dulserver.DEFAULT_HANDLERS = {
'git-upload-pack': SimpleGitUploadPackHandler,
'git-receive-pack': dulserver.ReceivePackHandler,
}
from dulwich.repo import Repo
from dulwich.web import HTTPGitApplication
from paste.auth.basic import AuthBasicAuthenticator
from paste.httpheaders import REMOTE_USER, AUTH_TYPE
from rhodecode.lib import safe_str
from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware
from rhodecode.lib.utils import invalidate_cache, is_valid_repo
from rhodecode.model import meta
from rhodecode.model.db import User
from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
log = logging.getLogger(__name__)
def is_git(environ):
"""Returns True if request's target is git server.
``HTTP_USER_AGENT`` would then have git client version given.
:param environ:
http_user_agent = environ.get('HTTP_USER_AGENT')
if http_user_agent and http_user_agent.startswith('git'):
return True
return False
class SimpleGit(object):
def __init__(self, application, config):
self.application = application
self.config = config
# base path of repo locations
self.basepath = self.config['base_path']
#authenticate this mercurial request using authfunc
self.authenticate = AuthBasicAuthenticator('', authfunc)
def __call__(self, environ, start_response):
start = time.time()
try:
return self._handle_request(environ, start_response)
finally:
log = logging.getLogger(self.__class__.__name__)
log.debug('Request time: %.3fs' % (time.time() - start))
meta.Session.remove()
def _handle_request(self, environ, start_response):
if not is_git(environ):
return self.application(environ, start_response)
proxy_key = 'HTTP_X_REAL_IP'
def_key = 'REMOTE_ADDR'
ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
username = None
# skip passing error to error controller
environ['pylons.status_code_redirect'] = True
#======================================================================
# EXTRACT REPOSITORY NAME FROM ENV
repo_name = self.__get_repository(environ)
log.debug('Extracted repo name is %s' % repo_name)
except:
return HTTPInternalServerError()(environ, start_response)
# GET ACTION PULL or PUSH
action = self.__get_action(environ)
@@ -6,88 +6,99 @@
SimpleHG middleware for handling mercurial protocol request
(push/clone etc.). It's implemented with basic auth function
from mercurial.error import RepoError
from mercurial.hgweb import hgweb_mod
from rhodecode.lib.utils import make_ui, invalidate_cache, \
is_valid_repo, ui_sections
def is_mercurial(environ):
"""Returns True if request's target is mercurial server - header
``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
http_accept = environ.get('HTTP_ACCEPT')
if http_accept and http_accept.startswith('application/mercurial'):
class SimpleHg(object):
self.ipaddr = '0.0.0.0'
if not is_mercurial(environ):
repo_name = environ['REPO_NAME'] = self.__get_repository(environ)
Status change: