##// END OF EJS Templates
hgweb: document why we don't allow untrusted settings to control zlib...
Gregory Szorc -
r29788:b1809f5d default
parent child Browse files
Show More
@@ -1,117 +1,120 b''
1 #
1 #
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
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 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import cgi
10 import cgi
11 import zlib
11 import zlib
12
12
13 from .common import (
13 from .common import (
14 HTTP_OK,
14 HTTP_OK,
15 )
15 )
16
16
17 from .. import (
17 from .. import (
18 util,
18 util,
19 wireproto,
19 wireproto,
20 )
20 )
21 stringio = util.stringio
21 stringio = util.stringio
22
22
23 urlerr = util.urlerr
23 urlerr = util.urlerr
24 urlreq = util.urlreq
24 urlreq = util.urlreq
25
25
26 HGTYPE = 'application/mercurial-0.1'
26 HGTYPE = 'application/mercurial-0.1'
27 HGERRTYPE = 'application/hg-error'
27 HGERRTYPE = 'application/hg-error'
28
28
29 class webproto(wireproto.abstractserverproto):
29 class webproto(wireproto.abstractserverproto):
30 def __init__(self, req, ui):
30 def __init__(self, req, ui):
31 self.req = req
31 self.req = req
32 self.response = ''
32 self.response = ''
33 self.ui = ui
33 self.ui = ui
34 def getargs(self, args):
34 def getargs(self, args):
35 knownargs = self._args()
35 knownargs = self._args()
36 data = {}
36 data = {}
37 keys = args.split()
37 keys = args.split()
38 for k in keys:
38 for k in keys:
39 if k == '*':
39 if k == '*':
40 star = {}
40 star = {}
41 for key in knownargs.keys():
41 for key in knownargs.keys():
42 if key != 'cmd' and key not in keys:
42 if key != 'cmd' and key not in keys:
43 star[key] = knownargs[key][0]
43 star[key] = knownargs[key][0]
44 data['*'] = star
44 data['*'] = star
45 else:
45 else:
46 data[k] = knownargs[k][0]
46 data[k] = knownargs[k][0]
47 return [data[k] for k in keys]
47 return [data[k] for k in keys]
48 def _args(self):
48 def _args(self):
49 args = self.req.form.copy()
49 args = self.req.form.copy()
50 postlen = int(self.req.env.get('HTTP_X_HGARGS_POST', 0))
50 postlen = int(self.req.env.get('HTTP_X_HGARGS_POST', 0))
51 if postlen:
51 if postlen:
52 args.update(cgi.parse_qs(
52 args.update(cgi.parse_qs(
53 self.req.read(postlen), keep_blank_values=True))
53 self.req.read(postlen), keep_blank_values=True))
54 return args
54 return args
55 chunks = []
55 chunks = []
56 i = 1
56 i = 1
57 while True:
57 while True:
58 h = self.req.env.get('HTTP_X_HGARG_' + str(i))
58 h = self.req.env.get('HTTP_X_HGARG_' + str(i))
59 if h is None:
59 if h is None:
60 break
60 break
61 chunks += [h]
61 chunks += [h]
62 i += 1
62 i += 1
63 args.update(cgi.parse_qs(''.join(chunks), keep_blank_values=True))
63 args.update(cgi.parse_qs(''.join(chunks), keep_blank_values=True))
64 return args
64 return args
65 def getfile(self, fp):
65 def getfile(self, fp):
66 length = int(self.req.env['CONTENT_LENGTH'])
66 length = int(self.req.env['CONTENT_LENGTH'])
67 for s in util.filechunkiter(self.req, limit=length):
67 for s in util.filechunkiter(self.req, limit=length):
68 fp.write(s)
68 fp.write(s)
69 def redirect(self):
69 def redirect(self):
70 self.oldio = self.ui.fout, self.ui.ferr
70 self.oldio = self.ui.fout, self.ui.ferr
71 self.ui.ferr = self.ui.fout = stringio()
71 self.ui.ferr = self.ui.fout = stringio()
72 def restore(self):
72 def restore(self):
73 val = self.ui.fout.getvalue()
73 val = self.ui.fout.getvalue()
74 self.ui.ferr, self.ui.fout = self.oldio
74 self.ui.ferr, self.ui.fout = self.oldio
75 return val
75 return val
76 def groupchunks(self, cg):
76 def groupchunks(self, cg):
77 # Don't allow untrusted settings because disabling compression or
78 # setting a very high compression level could lead to flooding
79 # the server's network or CPU.
77 z = zlib.compressobj(self.ui.configint('server', 'zliblevel', -1))
80 z = zlib.compressobj(self.ui.configint('server', 'zliblevel', -1))
78 while True:
81 while True:
79 chunk = cg.read(4096)
82 chunk = cg.read(4096)
80 if not chunk:
83 if not chunk:
81 break
84 break
82 yield z.compress(chunk)
85 yield z.compress(chunk)
83 yield z.flush()
86 yield z.flush()
84 def _client(self):
87 def _client(self):
85 return 'remote:%s:%s:%s' % (
88 return 'remote:%s:%s:%s' % (
86 self.req.env.get('wsgi.url_scheme') or 'http',
89 self.req.env.get('wsgi.url_scheme') or 'http',
87 urlreq.quote(self.req.env.get('REMOTE_HOST', '')),
90 urlreq.quote(self.req.env.get('REMOTE_HOST', '')),
88 urlreq.quote(self.req.env.get('REMOTE_USER', '')))
91 urlreq.quote(self.req.env.get('REMOTE_USER', '')))
89
92
90 def iscmd(cmd):
93 def iscmd(cmd):
91 return cmd in wireproto.commands
94 return cmd in wireproto.commands
92
95
93 def call(repo, req, cmd):
96 def call(repo, req, cmd):
94 p = webproto(req, repo.ui)
97 p = webproto(req, repo.ui)
95 rsp = wireproto.dispatch(repo, p, cmd)
98 rsp = wireproto.dispatch(repo, p, cmd)
96 if isinstance(rsp, str):
99 if isinstance(rsp, str):
97 req.respond(HTTP_OK, HGTYPE, body=rsp)
100 req.respond(HTTP_OK, HGTYPE, body=rsp)
98 return []
101 return []
99 elif isinstance(rsp, wireproto.streamres):
102 elif isinstance(rsp, wireproto.streamres):
100 req.respond(HTTP_OK, HGTYPE)
103 req.respond(HTTP_OK, HGTYPE)
101 return rsp.gen
104 return rsp.gen
102 elif isinstance(rsp, wireproto.pushres):
105 elif isinstance(rsp, wireproto.pushres):
103 val = p.restore()
106 val = p.restore()
104 rsp = '%d\n%s' % (rsp.res, val)
107 rsp = '%d\n%s' % (rsp.res, val)
105 req.respond(HTTP_OK, HGTYPE, body=rsp)
108 req.respond(HTTP_OK, HGTYPE, body=rsp)
106 return []
109 return []
107 elif isinstance(rsp, wireproto.pusherr):
110 elif isinstance(rsp, wireproto.pusherr):
108 # drain the incoming bundle
111 # drain the incoming bundle
109 req.drain()
112 req.drain()
110 p.restore()
113 p.restore()
111 rsp = '0\n%s\n' % rsp.res
114 rsp = '0\n%s\n' % rsp.res
112 req.respond(HTTP_OK, HGTYPE, body=rsp)
115 req.respond(HTTP_OK, HGTYPE, body=rsp)
113 return []
116 return []
114 elif isinstance(rsp, wireproto.ooberror):
117 elif isinstance(rsp, wireproto.ooberror):
115 rsp = rsp.message
118 rsp = rsp.message
116 req.respond(HTTP_OK, HGERRTYPE, body=rsp)
119 req.respond(HTTP_OK, HGERRTYPE, body=rsp)
117 return []
120 return []
General Comments 0
You need to be logged in to leave comments. Login now