3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
4 # |
4 # |
5 # This software may be used and distributed according to the terms of the |
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. |
6 # GNU General Public License version 2 or any later version. |
7 |
7 |
8 import cgi, cStringIO, zlib, sys, urllib |
8 import cgi, cStringIO, zlib, urllib |
9 from mercurial import util, wireproto |
9 from mercurial import util, wireproto |
10 from common import HTTP_OK |
10 from common import HTTP_OK |
11 |
11 |
12 HGTYPE = 'application/mercurial-0.1' |
12 HGTYPE = 'application/mercurial-0.1' |
13 |
13 |
14 class webproto(object): |
14 class webproto(object): |
15 def __init__(self, req): |
15 def __init__(self, req, ui): |
16 self.req = req |
16 self.req = req |
17 self.response = '' |
17 self.response = '' |
|
18 self.ui = ui |
18 def getargs(self, args): |
19 def getargs(self, args): |
19 knownargs = self._args() |
20 knownargs = self._args() |
20 data = {} |
21 data = {} |
21 keys = args.split() |
22 keys = args.split() |
22 for k in keys: |
23 for k in keys: |
44 def getfile(self, fp): |
45 def getfile(self, fp): |
45 length = int(self.req.env['CONTENT_LENGTH']) |
46 length = int(self.req.env['CONTENT_LENGTH']) |
46 for s in util.filechunkiter(self.req, limit=length): |
47 for s in util.filechunkiter(self.req, limit=length): |
47 fp.write(s) |
48 fp.write(s) |
48 def redirect(self): |
49 def redirect(self): |
49 self.oldio = sys.stdout, sys.stderr |
50 self.oldio = self.ui.fout, self.ui.ferr |
50 sys.stderr = sys.stdout = cStringIO.StringIO() |
51 self.ui.ferr = self.ui.fout = cStringIO.StringIO() |
|
52 def restore(self): |
|
53 val = self.ui.fout.getvalue() |
|
54 self.ui.ferr, self.ui.fout = self.oldio |
|
55 return val |
51 def groupchunks(self, cg): |
56 def groupchunks(self, cg): |
52 z = zlib.compressobj() |
57 z = zlib.compressobj() |
53 while True: |
58 while True: |
54 chunk = cg.read(4096) |
59 chunk = cg.read(4096) |
55 if not chunk: |
60 if not chunk: |
64 |
69 |
65 def iscmd(cmd): |
70 def iscmd(cmd): |
66 return cmd in wireproto.commands |
71 return cmd in wireproto.commands |
67 |
72 |
68 def call(repo, req, cmd): |
73 def call(repo, req, cmd): |
69 p = webproto(req) |
74 p = webproto(req, repo.ui) |
70 rsp = wireproto.dispatch(repo, p, cmd) |
75 rsp = wireproto.dispatch(repo, p, cmd) |
71 if isinstance(rsp, str): |
76 if isinstance(rsp, str): |
72 req.respond(HTTP_OK, HGTYPE, length=len(rsp)) |
77 req.respond(HTTP_OK, HGTYPE, length=len(rsp)) |
73 return [rsp] |
78 return [rsp] |
74 elif isinstance(rsp, wireproto.streamres): |
79 elif isinstance(rsp, wireproto.streamres): |
75 req.respond(HTTP_OK, HGTYPE) |
80 req.respond(HTTP_OK, HGTYPE) |
76 return rsp.gen |
81 return rsp.gen |
77 elif isinstance(rsp, wireproto.pushres): |
82 elif isinstance(rsp, wireproto.pushres): |
78 val = sys.stdout.getvalue() |
83 val = p.restore() |
79 sys.stdout, sys.stderr = p.oldio |
|
80 req.respond(HTTP_OK, HGTYPE) |
84 req.respond(HTTP_OK, HGTYPE) |
81 return ['%d\n%s' % (rsp.res, val)] |
85 return ['%d\n%s' % (rsp.res, val)] |
82 elif isinstance(rsp, wireproto.pusherr): |
86 elif isinstance(rsp, wireproto.pusherr): |
83 # drain the incoming bundle |
87 # drain the incoming bundle |
84 req.drain() |
88 req.drain() |
85 sys.stdout, sys.stderr = p.oldio |
89 p.restore() |
86 rsp = '0\n%s\n' % rsp.res |
90 rsp = '0\n%s\n' % rsp.res |
87 req.respond(HTTP_OK, HGTYPE, length=len(rsp)) |
91 req.respond(HTTP_OK, HGTYPE, length=len(rsp)) |
88 return [rsp] |
92 return [rsp] |