diff options
author | Milo Casagrande <milo@ubuntu.com> | 2013-04-03 14:22:54 +0200 |
---|---|---|
committer | Milo Casagrande <milo@ubuntu.com> | 2013-04-03 14:22:54 +0200 |
commit | aed8a0dcade421c51f14d9bf9368fe0f87fc0c7f (patch) | |
tree | af95623f88b17e3d4f447456b93f218f654b6463 | |
parent | 6a1d0b93a23f7a43335957fc880eee32f3566567 (diff) | |
parent | d8e9daf300e4508e4cfb852bbbc14a63b1caceb3 (diff) |
Merge branch 'dumb_http' of git://git.linaro.org/people/gesha/rhodecode into linaro
-rw-r--r-- | rhodecode/controllers/admin/settings.py | 10 | ||||
-rw-r--r-- | rhodecode/lib/db_manage.py | 18 | ||||
-rw-r--r-- | rhodecode/lib/middleware/pygrack.py | 158 | ||||
-rw-r--r-- | rhodecode/lib/middleware/simplegit.py | 2 | ||||
-rw-r--r-- | rhodecode/model/forms.py | 2 | ||||
-rw-r--r-- | rhodecode/templates/admin/settings/settings.html | 32 |
6 files changed, 156 insertions, 66 deletions
diff --git a/rhodecode/controllers/admin/settings.py b/rhodecode/controllers/admin/settings.py index 30181d62..712d6534 100644 --- a/rhodecode/controllers/admin/settings.py +++ b/rhodecode/controllers/admin/settings.py @@ -292,6 +292,16 @@ class SettingsController(BaseController): # sett.ui_active = form_result[_f('extensions_hggit')] # Session().add(sett) + sett = RhodeCodeUi.get_by_key('dumbgit') + if not sett: + #make one if it's not there ! + sett = RhodeCodeUi() + sett.ui_key = 'dumbgit' + sett.ui_section = 'extensions' + + sett.ui_active = form_result[_f('extensions_dumbgit')] + Session().add(sett) + Session().commit() h.flash(_('Updated VCS settings'), category='success') diff --git a/rhodecode/lib/db_manage.py b/rhodecode/lib/db_manage.py index 2a0df345..7b7c0224 100644 --- a/rhodecode/lib/db_manage.py +++ b/rhodecode/lib/db_manage.py @@ -253,6 +253,16 @@ class DbManage(object): hggit.ui_active = False Session().add(hggit) + notify('installing dumbgit option') + # enable a dumb git protocol behavior for clone/pull operations + dumbgit = RhodeCodeUi() + dumbgit.ui_section = 'extensions' + dumbgit.ui_key = 'dumbgit' + dumbgit.ui_value = '' + dumbgit.ui_active = False + Session().ad(dumbgit) + RhodeCodeSetting('dumbgit', False) + notify('re-check default permissions') default_user = User.get_by_username(User.DEFAULT_USER) perm = Permission.get_by_key('hg.fork.repository') @@ -479,6 +489,14 @@ class DbManage(object): hggit.ui_active = False self.sa.add(hggit) + # enable a dumb git protocol behavior for clone/pull operations + dumbgit = RhodeCodeUi() + dumbgit.ui_section = 'extensions' + dumbgit.ui_key = 'dumbgit' + dumbgit.ui_value = '' + dumbgit.ui_active = False + self.sa.add(dumbgit) + def create_ldap_options(self, skip_existing=False): """Creates ldap settings""" diff --git a/rhodecode/lib/middleware/pygrack.py b/rhodecode/lib/middleware/pygrack.py index 22384eed..af0fa247 100644 --- a/rhodecode/lib/middleware/pygrack.py +++ b/rhodecode/lib/middleware/pygrack.py @@ -7,6 +7,8 @@ import traceback from webob import Request, Response, exc from rhodecode.lib import subprocessio +from rhodecode.model.db import RhodeCodeSetting +from rhodecode.lib.utils2 import str2bool log = logging.getLogger(__name__) @@ -48,10 +50,12 @@ class GitRepository(object): == self.git_folder_signature): raise OSError('%s missing git signature' % content_path) self.content_path = content_path - self.valid_accepts = ['application/x-%s-result' % + self.accepts = ['text/plain'] + self.valid_accepts = self.accepts + ['application/x-%s-result' % c for c in self.commands] self.repo_name = repo_name self.extras = extras + self.dumb = str2bool(RhodeCodeSetting.get_by_name(key='extensions_dumbgit')) def _get_fixedpath(self, path): """ @@ -68,33 +72,54 @@ class GitRepository(object): HTTP /info/refs request. """ - git_command = request.GET.get('service') - if git_command not in self.commands: - log.debug('command %s not allowed' % git_command) - return exc.HTTPMethodNotAllowed() - - # note to self: - # please, resist the urge to add '\n' to git capture and increment - # line count by 1. - # The code in Git client not only does NOT need '\n', but actually - # blows up if you sprinkle "flush" (0000) as "0001\n". - # It reads binary, per number of bytes specified. - # if you do add '\n' as part of data, count it. - server_advert = '# service=%s' % git_command - packet_len = str(hex(len(server_advert) + 4)[2:].rjust(4, '0')).lower() - try: - out = subprocessio.SubprocessIOChunker( - r'git %s --stateless-rpc --advertise-refs "%s"' % ( - git_command[4:], self.content_path), - starting_values=[ - packet_len + server_advert + '0000' - ] - ) - except EnvironmentError, e: - log.error(traceback.format_exc()) - raise exc.HTTPExpectationFailed() + if self.dumb: + git_path = self._get_fixedpath(request.path_info) + filename = os.path.join(self.content_path, git_path) + if os.path.isfile(filename): + out = open(filename) + content_type = 'text/plain' + content_length = os.path.getsize(filename) + status = 200 + else: + log.info("File not found: %s" % git_path) + content_type = 'text/html' + status = 404 + out = ['', ] + else: + git_command = request.GET.get('service') + if git_command not in self.commands: + log.debug('command %s not allowed' % git_command) + return exc.HTTPMethodNotAllowed() + # note to self: + # please, resist the urge to add '\n' to git capture and increment + # line count by 1. + # The code in Git client not only does NOT need '\n', but actually + # blows up if you sprinkle "flush" (0000) as "0001\n". + # It reads binary, per number of bytes specified. + # if you do add '\n' as part of data, count it. + server_advert = '# service=%s' % git_command + packet_len = str(hex(len(server_advert) + 4)[2:].rjust(4, '0')).lower() + try: + out = subprocessio.SubprocessIOChunker( + r'git %s --stateless-rpc --advertise-refs "%s"' % ( + git_command[4:], self.content_path), + starting_values=[ + packet_len + server_advert + '0000' + ] + ) + except EnvironmentError, e: + log.error(traceback.format_exc()) + raise exc.HTTPExpectationFailed() + + content_type = 'application/x-%s-advertisement' % str(git_command) + content_length = 0 + status = 200 + resp = Response() - resp.content_type = 'application/x-%s-advertisement' % str(git_command) + resp.content_type = content_type + if content_length > 0: + resp.content_length = content_length + resp.status = status resp.charset = None resp.app_iter = out return resp @@ -107,37 +132,57 @@ class GitRepository(object): response to stdout """ git_command = self._get_fixedpath(request.path_info) - if git_command not in self.commands: - log.debug('command %s not allowed' % git_command) - return exc.HTTPMethodNotAllowed() + if self.dumb: + filename = os.path.join(self.content_path, git_command) + + if os.path.isfile(filename): + out = open(filename) + content_type = 'text/plain' + content_length = os.path.getsize(filename) + status = 200 + else: + log.info("File not found: %s" % git_command) + content_type = 'text/html' + content_length = 0 + status = 404 + out = ['', ] + #raise exc.HTTPExpectationFailed() + else: + if git_command not in self.commands: + log.debug('command %s not allowed' % git_command) + return exc.HTTPMethodNotAllowed() - if 'CONTENT_LENGTH' in environ: - inputstream = FileWrapper(environ['wsgi.input'], + if 'CONTENT_LENGTH' in environ: + inputstream = FileWrapper(environ['wsgi.input'], request.content_length) - else: - inputstream = environ['wsgi.input'] + else: + inputstream = environ['wsgi.input'] - try: - gitenv = os.environ - from rhodecode.lib.compat import json - gitenv['RHODECODE_EXTRAS'] = json.dumps(self.extras) - # forget all configs - gitenv['GIT_CONFIG_NOGLOBAL'] = '1' - opts = dict( - env=gitenv, - cwd=os.getcwd() - ) - cmd = r'git %s --stateless-rpc "%s"' % (git_command[4:], + try: + gitenv = os.environ + from rhodecode.lib.compat import json + gitenv['RHODECODE_EXTRAS'] = json.dumps(self.extras) + # forget all configs + gitenv['GIT_CONFIG_NOGLOBAL'] = '1' + opts = dict( + env=gitenv, + cwd=os.getcwd() + ) + cmd = r'git %s --stateless-rpc "%s"' % (git_command[4:], self.content_path), - log.debug('handling cmd %s' % cmd) - out = subprocessio.SubprocessIOChunker( - cmd, - inputstream=inputstream, - **opts - ) - except EnvironmentError, e: - log.error(traceback.format_exc()) - raise exc.HTTPExpectationFailed() + log.debug('handling cmd %s' % cmd) + out = subprocessio.SubprocessIOChunker( + cmd, + inputstream=inputstream, + **opts + ) + except EnvironmentError, e: + log.error(traceback.format_exc()) + raise exc.HTTPExpectationFailed() + + content_type = 'application/x-%s-result' % git_command.encode('utf8') + content_length = 0 + status = 200 if git_command in [u'git-receive-pack']: # updating refs manually after each push. @@ -148,7 +193,10 @@ class GitRepository(object): subprocess.call(cmd, shell=True) resp = Response() - resp.content_type = 'application/x-%s-result' % git_command.encode('utf8') + resp.content_type = content_type + if content_length > 0: + resp.content_length = content_length + resp.status = status resp.charset = None resp.app_iter = out return resp diff --git a/rhodecode/lib/middleware/simplegit.py b/rhodecode/lib/middleware/simplegit.py index 63a6543c..94d763f4 100644 --- a/rhodecode/lib/middleware/simplegit.py +++ b/rhodecode/lib/middleware/simplegit.py @@ -89,7 +89,7 @@ from rhodecode.model.db import User, RhodeCodeUi log = logging.getLogger(__name__) -GIT_PROTO_PAT = re.compile(r'^/(.+)/(info/refs|git-upload-pack|git-receive-pack)') +GIT_PROTO_PAT = re.compile(r'^/(.+)/(info/refs|git-upload-pack|git-receive-pack|HEAD|objects)') def is_git(environ): diff --git a/rhodecode/model/forms.py b/rhodecode/model/forms.py index 75eda30f..19a12c56 100644 --- a/rhodecode/model/forms.py +++ b/rhodecode/model/forms.py @@ -283,6 +283,8 @@ def ApplicationUiSettingsForm(): extensions_hgsubversion = v.StringBoolean(if_missing=False) extensions_hggit = v.StringBoolean(if_missing=False) + extensions_dumbgit = v.StringBoolean(if_missing=False) + return _ApplicationUiSettingsForm diff --git a/rhodecode/templates/admin/settings/settings.html b/rhodecode/templates/admin/settings/settings.html index 9b98894b..30d3b497 100644 --- a/rhodecode/templates/admin/settings/settings.html +++ b/rhodecode/templates/admin/settings/settings.html @@ -209,14 +209,14 @@ <label>${_('Hooks')}:</label> </div> <div class="checkboxes"> - <div class="checkbox"> - ${h.checkbox('hooks_changegroup_update','True')} - <label for="hooks_changegroup_update">${_('Update repository after push (hg update)')}</label> - </div> - <div class="checkbox"> - ${h.checkbox('hooks_changegroup_repo_size','True')} - <label for="hooks_changegroup_repo_size">${_('Show repository size after push')}</label> - </div> + <div class="checkbox"> + ${h.checkbox('hooks_changegroup_update','True')} + <label for="hooks_changegroup_update">${_('Update repository after push (hg update)')}</label> + </div> + <div class="checkbox"> + ${h.checkbox('hooks_changegroup_repo_size','True')} + <label for="hooks_changegroup_repo_size">${_('Show repository size after push')}</label> + </div> <div class="checkbox"> ${h.checkbox('hooks_changegroup_push_logger','True')} <label for="hooks_changegroup_push_logger">${_('Log user push commands')}</label> @@ -225,7 +225,7 @@ ${h.checkbox('hooks_outgoing_pull_logger','True')} <label for="hooks_outgoing_pull_logger">${_('Log user pull commands')}</label> </div> - </div> + </div> <div class="input" style="margin-top:10px"> ${h.link_to(_('advanced setup'),url('admin_edit_setting',setting_id='hooks'),class_="ui-btn")} </div> @@ -237,7 +237,7 @@ <div class="checkboxes"> <div class="checkbox"> ${h.checkbox('extensions_largefiles','True')} - <label for="extensions_hgsubversion">${_('largefiles extensions')}</label> + <label for="extensions_largfiles">${_('largefiles extensions')}</label> </div> <div class="checkbox"> ${h.checkbox('extensions_hgsubversion','True')} @@ -251,6 +251,18 @@ ##<span class="help-block">${_('Requires hg-git library installed. Allows clonning from git remote locations')}</span> </div> </div> + <div class="field"> + <div class="label label-checkbox"> + <label>${_('Git Extensions')}:</label> + </div> + <div class="checkboxes"> + <div class="checkbox"> + ${h.checkbox('extensions_dumbgit', 'False')} + <label for="extensions_dumbgit">${_('dumb protocol')}</label> + </div> + <span class="help-block">${_('Serves files through a normal HTTP connection')}</span> + </div> + </div> <div class="field"> <div class="label"> <label for="paths_root_path">${_('Repositories location')}:</label> |