Mercurial > public > mercurial-scm > hg-stable
diff mercurial/hgweb/protocol.py @ 11595:368cd5325348
protocol: move hgweb protocol support back into protocol.py
- introduce iscmd
- simplify error handling
- remove unneeded imports
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 15 Jul 2010 15:05:04 -0500 |
parents | 67863f9d805f |
children | 83070a9cd526 |
line wrap: on
line diff
--- a/mercurial/hgweb/protocol.py Thu Jul 15 13:56:52 2010 -0500 +++ b/mercurial/hgweb/protocol.py Thu Jul 15 15:05:04 2010 -0500 @@ -5,19 +5,67 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -import cStringIO, zlib, tempfile, errno, os, sys, urllib, copy -from mercurial import util, streamclone, pushkey -from mercurial.node import bin, hex -from mercurial import changegroup as changegroupmod -from common import ErrorResponse, 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', - 'branchmap', 'pushkey', 'listkeys' -] +import cStringIO, zlib, sys, urllib +from mercurial import util, wireproto +from common import HTTP_OK HGTYPE = 'application/mercurial-0.1' + +class webproto(object): + def __init__(self, req): + self.req = req + self.response = '' + def getargs(self, args): + data = {} + keys = args.split() + for k in keys: + if k == '*': + star = {} + for key in self.req.form.keys(): + if key not in keys: + star[key] = self.req.form[key][0] + data['*'] = star + else: + data[k] = self.req.form[k][0] + return [data[k] for k in keys] + def sendchangegroup(self, cg): + self.req.respond(HTTP_OK, HGTYPE) + z = zlib.compressobj() + while 1: + chunk = cg.read(4096) + if not chunk: + break + self.req.write(z.compress(chunk)) + self.req.write(z.flush()) + def sendstream(self, source): + self.req.respond(HTTP_OK, HGTYPE) + for chunk in source: + self.req.write(chunk) + def respond(self, s): + self.req.respond(HTTP_OK, HGTYPE, length=len(s)) + self.response = s + def getfile(self, fp): + length = int(self.req.env['CONTENT_LENGTH']) + for s in util.filechunkiter(self.req, limit=length): + fp.write(s) + def redirect(self): + self.oldio = sys.stdout, sys.stderr + sys.stderr = sys.stdout = cStringIO.StringIO() + def respondpush(self, ret): + val = sys.stdout.getvalue() + sys.stdout, sys.stderr = self.oldio + self.req.respond(HTTP_OK, HGTYPE) + self.response = '%d\n%s' % (ret, val) + def _client(self): + return 'remote:%s:%s:%s' % ( + self.req.env.get('wsgi.url_scheme') or 'http', + urllib.quote(self.req.env.get('REMOTE_HOST', '')), + urllib.quote(self.req.env.get('REMOTE_USER', ''))) + +def iscmd(cmd): + return cmd in wireproto.commands + +def call(repo, req, cmd): + p = webproto(req) + r = wireproto.dispatch(repo, p, cmd) + yield p.response