hgweb: pass the actual response body to request.response, not just the length
authorMads Kiilerich <mads@kiilerich.com>
Tue, 15 Jan 2013 01:07:03 +0100
changeset 18352 e33b9b92a200
parent 18351 3fbdbeab38cc
child 18353 a9fd11ffa13f
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.
mercurial/hgweb/common.py
mercurial/hgweb/hgweb_mod.py
mercurial/hgweb/protocol.py
mercurial/hgweb/request.py
mercurial/hgweb/webcommands.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:
--- 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()