##// END OF EJS Templates
protocol: move hgweb protocol support back into protocol.py...
Matt Mackall -
r11595:368cd532 default
parent child Browse files
Show More
@@ -6,8 +6,8 b''
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 import os, zlib, sys, cStringIO, urllib
9 import os, sys, urllib
10 from mercurial import ui, hg, hook, error, encoding, templater, wireproto, util
10 from mercurial import ui, hg, hook, error, encoding, templater, util
11 from common import get_mtime, ErrorResponse, permhooks
11 from common import get_mtime, ErrorResponse, permhooks
12 from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
12 from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
13 from request import wsgirequest
13 from request import wsgirequest
@@ -22,63 +22,6 b' perms = {'
22 'pushkey': 'push',
22 'pushkey': 'push',
23 }
23 }
24
24
25 HGTYPE = 'application/mercurial-0.1'
26 class webproto(object):
27 def __init__(self, req):
28 self.req = req
29 self.response = ''
30 def getargs(self, args):
31 data = {}
32 keys = args.split()
33 for k in keys:
34 if k == '*':
35 star = {}
36 for key in self.req.form.keys():
37 if key not in keys:
38 star[key] = self.req.form[key][0]
39 data['*'] = star
40 else:
41 data[k] = self.req.form[k][0]
42 return [data[k] for k in keys]
43 def sendchangegroup(self, cg):
44 self.req.respond(HTTP_OK, HGTYPE)
45 z = zlib.compressobj()
46 while 1:
47 chunk = cg.read(4096)
48 if not chunk:
49 break
50 self.req.write(z.compress(chunk))
51 self.req.write(z.flush())
52 def sendstream(self, source):
53 self.req.respond(HTTP_OK, HGTYPE)
54 for chunk in source:
55 self.req.write(chunk)
56 def respond(self, s):
57 self.req.respond(HTTP_OK, HGTYPE, length=len(s))
58 self.response = s
59 def getfile(self, fp):
60 length = int(self.req.env['CONTENT_LENGTH'])
61 for s in util.filechunkiter(self.req, limit=length):
62 fp.write(s)
63 def redirect(self):
64 self.oldio = sys.stdout, sys.stderr
65 sys.stderr = sys.stdout = cStringIO.StringIO()
66 def respondpush(self, ret):
67 val = sys.stdout.getvalue()
68 sys.stdout, sys.stderr = self.oldio
69 self.req.respond(HTTP_OK, HGTYPE)
70 self.response = '%d\n%s' % (ret, val)
71 def _client(self):
72 return 'remote:%s:%s:%s' % (
73 self.req.env.get('wsgi.url_scheme') or 'http',
74 urllib.quote(self.req.env.get('REMOTE_HOST', '')),
75 urllib.quote(self.req.env.get('REMOTE_USER', '')))
76
77 def callproto(repo, req, cmd):
78 p = webproto(req)
79 r = wireproto.dispatch(repo, p, cmd)
80 yield p.response
81
82 class hgweb(object):
25 class hgweb(object):
83 def __init__(self, repo, name=None, baseui=None):
26 def __init__(self, repo, name=None, baseui=None):
84 if isinstance(repo, str):
27 if isinstance(repo, str):
@@ -169,26 +112,18 b' class hgweb(object):'
169 # and the clients always use the old URL structure
112 # and the clients always use the old URL structure
170
113
171 cmd = req.form.get('cmd', [''])[0]
114 cmd = req.form.get('cmd', [''])[0]
172 if cmd and cmd in protocol.__all__:
115 if protocol.iscmd(cmd):
173 if query:
116 if query:
174 raise ErrorResponse(HTTP_NOT_FOUND)
117 raise ErrorResponse(HTTP_NOT_FOUND)
175 try:
118 if cmd in perms:
176 if cmd in perms:
119 try:
177 try:
120 self.check_perm(req, perms[cmd])
178 self.check_perm(req, perms[cmd])
121 except ErrorResponse, inst:
179 except ErrorResponse, inst:
122 if cmd == 'unbundle':
180 if cmd == 'unbundle':
123 req.drain()
181 req.drain()
124 req.respond(inst, protocol.HGTYPE)
182 raise
125 return '0\n%s\n' % inst.message
183 if cmd in wireproto.commands:
126 return protocol.call(self.repo, req, cmd)
184 return callproto(self.repo, req, cmd)
185 method = getattr(protocol, cmd)
186 return method(self.repo, req)
187 except ErrorResponse, inst:
188 req.respond(inst, protocol.HGTYPE)
189 if not inst.message:
190 return []
191 return '0\n%s\n' % inst.message,
192
127
193 # translate user-visible url structure to internal structure
128 # translate user-visible url structure to internal structure
194
129
@@ -5,19 +5,67 b''
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 cStringIO, zlib, tempfile, errno, os, sys, urllib, copy
8 import cStringIO, zlib, sys, urllib
9 from mercurial import util, streamclone, pushkey
9 from mercurial import util, wireproto
10 from mercurial.node import bin, hex
10 from common import HTTP_OK
11 from mercurial import changegroup as changegroupmod
12 from common import ErrorResponse, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
13
14 # __all__ is populated with the allowed commands. Be sure to add to it if
15 # you're adding a new command, or the new command won't work.
16
17 __all__ = [
18 'lookup', 'heads', 'branches', 'between', 'changegroup',
19 'changegroupsubset', 'capabilities', 'unbundle', 'stream_out',
20 'branchmap', 'pushkey', 'listkeys'
21 ]
22
11
23 HGTYPE = 'application/mercurial-0.1'
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 sendchangegroup(self, cg):
32 self.req.respond(HTTP_OK, HGTYPE)
33 z = zlib.compressobj()
34 while 1:
35 chunk = cg.read(4096)
36 if not chunk:
37 break
38 self.req.write(z.compress(chunk))
39 self.req.write(z.flush())
40 def sendstream(self, source):
41 self.req.respond(HTTP_OK, HGTYPE)
42 for chunk in source:
43 self.req.write(chunk)
44 def respond(self, s):
45 self.req.respond(HTTP_OK, HGTYPE, length=len(s))
46 self.response = s
47 def getfile(self, fp):
48 length = int(self.req.env['CONTENT_LENGTH'])
49 for s in util.filechunkiter(self.req, limit=length):
50 fp.write(s)
51 def redirect(self):
52 self.oldio = sys.stdout, sys.stderr
53 sys.stderr = sys.stdout = cStringIO.StringIO()
54 def respondpush(self, ret):
55 val = sys.stdout.getvalue()
56 sys.stdout, sys.stderr = self.oldio
57 self.req.respond(HTTP_OK, HGTYPE)
58 self.response = '%d\n%s' % (ret, val)
59 def _client(self):
60 return 'remote:%s:%s:%s' % (
61 self.req.env.get('wsgi.url_scheme') or 'http',
62 urllib.quote(self.req.env.get('REMOTE_HOST', '')),
63 urllib.quote(self.req.env.get('REMOTE_USER', '')))
64
65 def iscmd(cmd):
66 return cmd in wireproto.commands
67
68 def call(repo, req, cmd):
69 p = webproto(req)
70 r = wireproto.dispatch(repo, p, cmd)
71 yield p.response
General Comments 0
You need to be logged in to leave comments. Login now