|
1 # |
|
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
|
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
|
4 # |
|
5 # This software may be used and distributed according to the terms of the |
|
6 # GNU General Public License version 2 or any later version. |
|
7 |
|
8 import cStringIO, zlib, sys, urllib |
|
9 from mercurial import util, wireproto |
|
10 from common import HTTP_OK |
|
11 |
|
12 HGTYPE = 'application/mercurial-0.1' |
|
13 |
|
14 class webproto(object): |
|
15 def __init__(self, req): |
|
16 self.req = req |
|
17 self.response = '' |
|
18 def getargs(self, args): |
|
19 data = {} |
|
20 keys = args.split() |
|
21 for k in keys: |
|
22 if k == '*': |
|
23 star = {} |
|
24 for key in self.req.form.keys(): |
|
25 if key not in keys: |
|
26 star[key] = self.req.form[key][0] |
|
27 data['*'] = star |
|
28 else: |
|
29 data[k] = self.req.form[k][0] |
|
30 return [data[k] for k in keys] |
|
31 def getfile(self, fp): |
|
32 length = int(self.req.env['CONTENT_LENGTH']) |
|
33 for s in util.filechunkiter(self.req, limit=length): |
|
34 fp.write(s) |
|
35 def redirect(self): |
|
36 self.oldio = sys.stdout, sys.stderr |
|
37 sys.stderr = sys.stdout = cStringIO.StringIO() |
|
38 def groupchunks(self, cg): |
|
39 z = zlib.compressobj() |
|
40 while 1: |
|
41 chunk = cg.read(4096) |
|
42 if not chunk: |
|
43 break |
|
44 yield z.compress(chunk) |
|
45 yield z.flush() |
|
46 def _client(self): |
|
47 return 'remote:%s:%s:%s' % ( |
|
48 self.req.env.get('wsgi.url_scheme') or 'http', |
|
49 urllib.quote(self.req.env.get('REMOTE_HOST', '')), |
|
50 urllib.quote(self.req.env.get('REMOTE_USER', ''))) |
|
51 |
|
52 def iscmd(cmd): |
|
53 return cmd in wireproto.commands |
|
54 |
|
55 def call(repo, req, cmd): |
|
56 p = webproto(req) |
|
57 rsp = wireproto.dispatch(repo, p, cmd) |
|
58 if isinstance(rsp, str): |
|
59 req.respond(HTTP_OK, HGTYPE, length=len(rsp)) |
|
60 return [rsp] |
|
61 elif isinstance(rsp, wireproto.streamres): |
|
62 req.respond(HTTP_OK, HGTYPE) |
|
63 return rsp.gen |
|
64 elif isinstance(rsp, wireproto.pushres): |
|
65 val = sys.stdout.getvalue() |
|
66 sys.stdout, sys.stderr = p.oldio |
|
67 req.respond(HTTP_OK, HGTYPE) |
|
68 return ['%d\n%s' % (rsp.res, val)] |
|
69 elif isinstance(rsp, wireproto.pusherr): |
|
70 # drain the incoming bundle |
|
71 req.drain() |
|
72 sys.stdout, sys.stderr = p.oldio |
|
73 rsp = '0\n%s\n' % rsp.res |
|
74 req.respond(HTTP_OK, HGTYPE, length=len(rsp)) |
|
75 return [rsp] |