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