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.
--- 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:
--- 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
--- 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 []
--- 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:
--- 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()