[PATCH 05 of 12] hgweb: pass the actual response body to request.response, not just the length

Mads Kiilerich mads at kiilerich.com
Fri Jan 11 17:32:49 CST 2013


# HG changeset patch
# User Mads Kiilerich <madski at unity3d.com>
# Date 1357947109 -3600
# Node ID 0b68f70d936fb309243f0c42ec5131cd1e11ae60
# Parent  eb88facfdf98896c759734bb0bafd31371e76611
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 --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py
--- a/mercurial/hgweb/common.py
+++ b/mercurial/hgweb/common.py
@@ -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 --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -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 --git a/mercurial/hgweb/protocol.py b/mercurial/hgweb/protocol.py
--- a/mercurial/hgweb/protocol.py
+++ b/mercurial/hgweb/protocol.py
@@ -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 --git a/mercurial/hgweb/request.py b/mercurial/hgweb/request.py
--- a/mercurial/hgweb/request.py
+++ b/mercurial/hgweb/request.py
@@ -70,7 +70,7 @@
         for s in util.filechunkiter(self.inp, limit=length):
             pass
 
-    def respond(self, status, type=None, filename=None, length=None):
+    def respond(self, status, type=None, filename=None, body=None):
         if self._start_response is not None:
             if type is not None:
                 self.headers.append(('Content-Type', type))
@@ -79,8 +79,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):
@@ -104,6 +104,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 util.safehasattr(thing, "__iter__"):
diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -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()


More information about the Mercurial-devel mailing list