2007-12-03 14:27:11 +03:00
|
|
|
#
|
|
|
|
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
|
|
|
|
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
|
|
|
|
#
|
2009-04-26 03:08:54 +04:00
|
|
|
# This software may be used and distributed according to the terms of the
|
2010-01-20 07:20:08 +03:00
|
|
|
# GNU General Public License version 2 or any later version.
|
2007-12-03 14:27:11 +03:00
|
|
|
|
2015-10-31 16:07:40 +03:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
|
|
|
import cgi
|
|
|
|
import zlib
|
|
|
|
|
|
|
|
from .common import (
|
|
|
|
HTTP_OK,
|
|
|
|
)
|
|
|
|
|
|
|
|
from .. import (
|
|
|
|
util,
|
|
|
|
wireproto,
|
|
|
|
)
|
2016-04-10 23:55:37 +03:00
|
|
|
stringio = util.stringio
|
2007-12-03 14:27:11 +03:00
|
|
|
|
2016-04-07 02:22:12 +03:00
|
|
|
urlerr = util.urlerr
|
|
|
|
urlreq = util.urlreq
|
|
|
|
|
2010-07-16 00:05:04 +04:00
|
|
|
HGTYPE = 'application/mercurial-0.1'
|
2011-08-02 23:21:10 +04:00
|
|
|
HGERRTYPE = 'application/hg-error'
|
2008-01-28 16:58:03 +03:00
|
|
|
|
2014-03-28 22:10:33 +04:00
|
|
|
class webproto(wireproto.abstractserverproto):
|
2011-06-08 02:39:20 +04:00
|
|
|
def __init__(self, req, ui):
|
2010-07-16 00:05:04 +04:00
|
|
|
self.req = req
|
|
|
|
self.response = ''
|
2011-06-08 02:39:20 +04:00
|
|
|
self.ui = ui
|
2010-07-16 00:05:04 +04:00
|
|
|
def getargs(self, args):
|
2011-04-30 21:04:37 +04:00
|
|
|
knownargs = self._args()
|
2010-07-16 00:05:04 +04:00
|
|
|
data = {}
|
|
|
|
keys = args.split()
|
|
|
|
for k in keys:
|
|
|
|
if k == '*':
|
|
|
|
star = {}
|
2011-04-30 21:04:37 +04:00
|
|
|
for key in knownargs.keys():
|
2011-03-22 09:38:32 +03:00
|
|
|
if key != 'cmd' and key not in keys:
|
2011-04-30 21:04:37 +04:00
|
|
|
star[key] = knownargs[key][0]
|
2010-07-16 00:05:04 +04:00
|
|
|
data['*'] = star
|
|
|
|
else:
|
2011-04-30 21:04:37 +04:00
|
|
|
data[k] = knownargs[k][0]
|
2010-07-16 00:05:04 +04:00
|
|
|
return [data[k] for k in keys]
|
2011-04-30 21:04:37 +04:00
|
|
|
def _args(self):
|
|
|
|
args = self.req.form.copy()
|
2016-03-11 19:37:00 +03:00
|
|
|
postlen = int(self.req.env.get('HTTP_X_HGARGS_POST', 0))
|
|
|
|
if postlen:
|
|
|
|
args.update(cgi.parse_qs(
|
|
|
|
self.req.read(postlen), keep_blank_values=True))
|
|
|
|
return args
|
2011-04-30 21:04:37 +04:00
|
|
|
chunks = []
|
2011-05-01 12:51:04 +04:00
|
|
|
i = 1
|
2011-06-01 14:38:46 +04:00
|
|
|
while True:
|
2011-05-01 12:51:04 +04:00
|
|
|
h = self.req.env.get('HTTP_X_HGARG_' + str(i))
|
2011-04-30 21:04:37 +04:00
|
|
|
if h is None:
|
|
|
|
break
|
|
|
|
chunks += [h]
|
2011-05-01 12:51:04 +04:00
|
|
|
i += 1
|
2011-04-30 21:04:37 +04:00
|
|
|
args.update(cgi.parse_qs(''.join(chunks), keep_blank_values=True))
|
|
|
|
return args
|
2010-07-16 20:16:15 +04:00
|
|
|
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):
|
2011-06-08 02:39:20 +04:00
|
|
|
self.oldio = self.ui.fout, self.ui.ferr
|
2016-04-10 23:55:37 +03:00
|
|
|
self.ui.ferr = self.ui.fout = stringio()
|
2011-06-08 02:39:20 +04:00
|
|
|
def restore(self):
|
|
|
|
val = self.ui.fout.getvalue()
|
|
|
|
self.ui.ferr, self.ui.fout = self.oldio
|
|
|
|
return val
|
2010-07-17 00:20:10 +04:00
|
|
|
def groupchunks(self, cg):
|
2016-08-08 04:09:58 +03:00
|
|
|
z = zlib.compressobj(self.ui.configint('server', 'zliblevel', -1))
|
2011-06-01 14:38:46 +04:00
|
|
|
while True:
|
2010-07-16 00:05:04 +04:00
|
|
|
chunk = cg.read(4096)
|
|
|
|
if not chunk:
|
|
|
|
break
|
2010-07-17 00:20:10 +04:00
|
|
|
yield z.compress(chunk)
|
|
|
|
yield z.flush()
|
2010-07-16 00:05:04 +04:00
|
|
|
def _client(self):
|
|
|
|
return 'remote:%s:%s:%s' % (
|
|
|
|
self.req.env.get('wsgi.url_scheme') or 'http',
|
2016-04-07 02:22:12 +03:00
|
|
|
urlreq.quote(self.req.env.get('REMOTE_HOST', '')),
|
|
|
|
urlreq.quote(self.req.env.get('REMOTE_USER', '')))
|
2008-01-28 16:58:03 +03:00
|
|
|
|
2010-07-16 00:05:04 +04:00
|
|
|
def iscmd(cmd):
|
|
|
|
return cmd in wireproto.commands
|
|
|
|
|
|
|
|
def call(repo, req, cmd):
|
2011-06-08 02:39:20 +04:00
|
|
|
p = webproto(req, repo.ui)
|
2010-07-20 22:53:33 +04:00
|
|
|
rsp = wireproto.dispatch(repo, p, cmd)
|
2010-07-20 11:56:37 +04:00
|
|
|
if isinstance(rsp, str):
|
2013-01-15 04:07:03 +04:00
|
|
|
req.respond(HTTP_OK, HGTYPE, body=rsp)
|
|
|
|
return []
|
2010-07-20 11:56:37 +04:00
|
|
|
elif isinstance(rsp, wireproto.streamres):
|
|
|
|
req.respond(HTTP_OK, HGTYPE)
|
|
|
|
return rsp.gen
|
|
|
|
elif isinstance(rsp, wireproto.pushres):
|
2011-06-08 02:39:20 +04:00
|
|
|
val = p.restore()
|
2013-01-15 04:05:12 +04:00
|
|
|
rsp = '%d\n%s' % (rsp.res, val)
|
2013-01-15 04:07:03 +04:00
|
|
|
req.respond(HTTP_OK, HGTYPE, body=rsp)
|
|
|
|
return []
|
2010-10-11 21:45:36 +04:00
|
|
|
elif isinstance(rsp, wireproto.pusherr):
|
2010-10-11 21:47:11 +04:00
|
|
|
# drain the incoming bundle
|
|
|
|
req.drain()
|
2011-06-08 02:39:20 +04:00
|
|
|
p.restore()
|
2010-10-11 21:45:36 +04:00
|
|
|
rsp = '0\n%s\n' % rsp.res
|
2013-01-15 04:07:03 +04:00
|
|
|
req.respond(HTTP_OK, HGTYPE, body=rsp)
|
|
|
|
return []
|
2011-08-02 23:21:10 +04:00
|
|
|
elif isinstance(rsp, wireproto.ooberror):
|
|
|
|
rsp = rsp.message
|
2013-01-15 04:07:03 +04:00
|
|
|
req.respond(HTTP_OK, HGERRTYPE, body=rsp)
|
|
|
|
return []
|