Mercurial > hg
view mercurial/hgweb/protocol.py @ 6914:95f35b553ae6
hgweb: removed unnecessary del before function return
Deleting tmpl just before the return statement should have no effect
since tmpl goes out of scope anyway. But it confuses pyflakes who
thinks tmpl is undefined when it is used in the except blocks below.
author | Martin Geisler <mg@daimi.au.dk> |
---|---|
date | Sat, 16 Aug 2008 16:32:57 +0200 |
parents | c228ae4bc89c |
children | 87abfefafe02 |
line wrap: on
line source
# # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> # # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. import cStringIO, zlib, tempfile, errno, os, sys from mercurial import util, streamclone from mercurial.node import bin, hex from mercurial import changegroup as changegroupmod from common import HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR # __all__ is populated with the allowed commands. Be sure to add to it if # you're adding a new command, or the new command won't work. __all__ = [ 'lookup', 'heads', 'branches', 'between', 'changegroup', 'changegroupsubset', 'capabilities', 'unbundle', 'stream_out', ] HGTYPE = 'application/mercurial-0.1' def lookup(repo, req): try: r = hex(repo.lookup(req.form['key'][0])) success = 1 except Exception,inst: r = str(inst) success = 0 resp = "%s %s\n" % (success, r) req.respond(HTTP_OK, HGTYPE, length=len(resp)) yield resp def heads(repo, req): resp = " ".join(map(hex, repo.heads())) + "\n" req.respond(HTTP_OK, HGTYPE, length=len(resp)) yield resp def branches(repo, req): nodes = [] if 'nodes' in req.form: nodes = map(bin, req.form['nodes'][0].split(" ")) resp = cStringIO.StringIO() for b in repo.branches(nodes): resp.write(" ".join(map(hex, b)) + "\n") resp = resp.getvalue() req.respond(HTTP_OK, HGTYPE, length=len(resp)) yield resp def between(repo, req): if 'pairs' in req.form: pairs = [map(bin, p.split("-")) for p in req.form['pairs'][0].split(" ")] resp = cStringIO.StringIO() for b in repo.between(pairs): resp.write(" ".join(map(hex, b)) + "\n") resp = resp.getvalue() req.respond(HTTP_OK, HGTYPE, length=len(resp)) yield resp def changegroup(repo, req): req.respond(HTTP_OK, HGTYPE) nodes = [] if 'roots' in req.form: nodes = map(bin, req.form['roots'][0].split(" ")) z = zlib.compressobj() f = repo.changegroup(nodes, 'serve') while 1: chunk = f.read(4096) if not chunk: break yield z.compress(chunk) yield z.flush() def changegroupsubset(repo, req): req.respond(HTTP_OK, HGTYPE) bases = [] heads = [] if 'bases' in req.form: bases = [bin(x) for x in req.form['bases'][0].split(' ')] if 'heads' in req.form: heads = [bin(x) for x in req.form['heads'][0].split(' ')] z = zlib.compressobj() f = repo.changegroupsubset(bases, heads, 'serve') while 1: chunk = f.read(4096) if not chunk: break yield z.compress(chunk) yield z.flush() def capabilities(repo, req): caps = ['lookup', 'changegroupsubset'] if repo.ui.configbool('server', 'uncompressed', untrusted=True): caps.append('stream=%d' % repo.changelog.version) if changegroupmod.bundlepriority: caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority)) rsp = ' '.join(caps) req.respond(HTTP_OK, HGTYPE, length=len(rsp)) yield rsp def unbundle(repo, req): errorfmt = '0\n%s\n' proto = req.env.get('wsgi.url_scheme') or 'http' their_heads = req.form['heads'][0].split(' ') def check_heads(): heads = map(hex, repo.heads()) return their_heads == [hex('force')] or their_heads == heads # fail early if possible if not check_heads(): length = int(req.env.get('CONTENT_LENGTH', 0)) for s in util.filechunkiter(req, limit=length): # drain incoming bundle, else client will not see # response when run outside cgi script pass req.respond(HTTP_OK, HGTYPE) return errorfmt % 'unsynced changes', req.respond(HTTP_OK, HGTYPE) # do not lock repo until all changegroup data is # streamed. save to temporary file. fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') fp = os.fdopen(fd, 'wb+') try: length = int(req.env['CONTENT_LENGTH']) for s in util.filechunkiter(req, limit=length): fp.write(s) try: lock = repo.lock() try: if not check_heads(): return errorfmt % 'unsynced changes', fp.seek(0) header = fp.read(6) if header.startswith('HG') and not header.startswith('HG10'): raise ValueError('unknown bundle version') elif header not in changegroupmod.bundletypes: raise ValueError('unknown bundle compression type') gen = changegroupmod.unbundle(header, fp) # send addchangegroup output to client oldio = sys.stdout, sys.stderr sys.stderr = sys.stdout = cStringIO.StringIO() try: url = 'remote:%s:%s' % (proto, req.env.get('REMOTE_HOST', '')) try: ret = repo.addchangegroup(gen, 'serve', url) except util.Abort, inst: sys.stdout.write("abort: %s\n" % inst) ret = 0 finally: val = sys.stdout.getvalue() sys.stdout, sys.stderr = oldio return '%d\n%s' % (ret, val), finally: del lock except ValueError, inst: return errorfmt % inst, except (OSError, IOError), inst: filename = getattr(inst, 'filename', '') # Don't send our filesystem layout to the client if filename.startswith(repo.root): filename = filename[len(repo.root)+1:] else: filename = '' error = getattr(inst, 'strerror', 'Unknown error') if inst.errno == errno.ENOENT: code = HTTP_NOT_FOUND else: code = HTTP_SERVER_ERROR req.respond(code) return '0\n%s: %s\n' % (error, filename), finally: fp.close() os.unlink(tempname) def stream_out(repo, req): req.respond(HTTP_OK, HGTYPE) streamclone.stream_out(repo, req, untrusted=True) return []