# HG changeset patch # User Mads Kiilerich # Date 1358208423 -3600 # Node ID e33b9b92a20043d648d2e244536fd045d7b8f1fd # Parent 3fbdbeab38cc1fec9df1d1b0ed4018db5a54cb2c hgweb: pass the actual response body to request.response, not just the length This makes it less likely to send a response that doesn't match Content-Length. diff -r 3fbdbeab38cc -r e33b9b92a200 mercurial/hgweb/common.py --- a/mercurial/hgweb/common.py Tue Jan 15 01:05:12 2013 +0100 +++ b/mercurial/hgweb/common.py Tue Jan 15 01:07:03 2013 +0100 @@ -140,11 +140,11 @@ try: os.stat(path) ct = mimetypes.guess_type(path)[0] or "text/plain" - req.respond(HTTP_OK, ct, length = os.path.getsize(path)) fp = open(path, 'rb') data = fp.read() fp.close() - return data + req.respond(HTTP_OK, ct, body=data) + return "" except TypeError: raise ErrorResponse(HTTP_SERVER_ERROR, 'illegal filename') except OSError, err: diff -r 3fbdbeab38cc -r e33b9b92a200 mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py Tue Jan 15 01:05:12 2013 +0100 +++ b/mercurial/hgweb/hgweb_mod.py Tue Jan 15 01:07:03 2013 +0100 @@ -158,8 +158,9 @@ '').lower() != '100-continue') or req.env.get('X-HgHttp2', '')): req.drain() - req.respond(inst, protocol.HGTYPE) - return '0\n%s\n' % inst.message + req.respond(inst, protocol.HGTYPE, + body='0\n%s\n' % inst.message) + return '' # translate user-visible url structure to internal structure diff -r 3fbdbeab38cc -r e33b9b92a200 mercurial/hgweb/protocol.py --- a/mercurial/hgweb/protocol.py Tue Jan 15 01:05:12 2013 +0100 +++ b/mercurial/hgweb/protocol.py Tue Jan 15 01:07:03 2013 +0100 @@ -75,24 +75,24 @@ p = webproto(req, repo.ui) rsp = wireproto.dispatch(repo, p, cmd) if isinstance(rsp, str): - req.respond(HTTP_OK, HGTYPE, length=len(rsp)) - return [rsp] + req.respond(HTTP_OK, HGTYPE, body=rsp) + return [] elif isinstance(rsp, wireproto.streamres): req.respond(HTTP_OK, HGTYPE) return rsp.gen elif isinstance(rsp, wireproto.pushres): val = p.restore() rsp = '%d\n%s' % (rsp.res, val) - req.respond(HTTP_OK, HGTYPE, length=len(rsp)) - return [rsp] + req.respond(HTTP_OK, HGTYPE, body=rsp) + return [] elif isinstance(rsp, wireproto.pusherr): # drain the incoming bundle req.drain() p.restore() rsp = '0\n%s\n' % rsp.res - req.respond(HTTP_OK, HGTYPE, length=len(rsp)) - return [rsp] + req.respond(HTTP_OK, HGTYPE, body=rsp) + return [] elif isinstance(rsp, wireproto.ooberror): rsp = rsp.message - req.respond(HTTP_OK, HGERRTYPE, length=len(rsp)) - return [rsp] + req.respond(HTTP_OK, HGERRTYPE, body=rsp) + return [] diff -r 3fbdbeab38cc -r e33b9b92a200 mercurial/hgweb/request.py --- a/mercurial/hgweb/request.py Tue Jan 15 01:05:12 2013 +0100 +++ b/mercurial/hgweb/request.py Tue Jan 15 01:07:03 2013 +0100 @@ -70,7 +70,7 @@ for s in util.filechunkiter(self.inp, limit=length): pass - def respond(self, status, type, filename=None, length=None): + def respond(self, status, type, filename=None, body=None): if self._start_response is not None: self.headers.append(('Content-Type', type)) if filename: @@ -78,8 +78,8 @@ .replace('\\', '\\\\').replace('"', '\\"')) self.headers.append(('Content-Disposition', 'inline; filename="%s"' % filename)) - if length is not None: - self.headers.append(('Content-Length', str(length))) + if body is not None: + self.headers.append(('Content-Length', str(len(body)))) for k, v in self.headers: if not isinstance(v, str): @@ -103,6 +103,9 @@ self.server_write = self._start_response(status, self.headers) self._start_response = None self.headers = [] + if body is not None: + self.write(body) + self.server_write = None def write(self, thing): if thing: diff -r 3fbdbeab38cc -r e33b9b92a200 mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py Tue Jan 15 01:05:12 2013 +0100 +++ b/mercurial/hgweb/webcommands.py Tue Jan 15 01:07:03 2013 +0100 @@ -61,8 +61,8 @@ if mt.startswith('text/'): mt += '; charset="%s"' % encoding.encoding - req.respond(HTTP_OK, mt, path, len(text)) - return [text] + req.respond(HTTP_OK, mt, path, body=text) + return [] def _filerevision(web, tmpl, fctx): f = fctx.path()