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
@@ -10,7 +10,7 @@ import os
 import os.path
 import mimetypes
 from mercurial.demandload import demandload
-demandload(globals(), "re zlib ConfigParser")
+demandload(globals(), "re zlib ConfigParser cStringIO")
 demandload(globals(), "mercurial:mdiff,ui,hg,util,archival,templater")
 demandload(globals(), "mercurial.hgweb.request:hgrequest")
 demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile")
@@ -761,26 +761,32 @@ class hgweb(object):
                                    req.form['filenode'][0]))
 
         elif cmd == 'heads':
-            req.httphdr("application/mercurial-0.1")
-            h = self.repo.heads()
-            req.write(" ".join(map(hex, h)) + "\n")
+            resp = " ".join(map(hex, self.repo.heads())) + "\n"
+            req.httphdr("application/mercurial-0.1", length=len(resp))
+            req.write(resp)
 
         elif cmd == 'branches':
-            req.httphdr("application/mercurial-0.1")
             nodes = []
             if req.form.has_key('nodes'):
                 nodes = map(bin, req.form['nodes'][0].split(" "))
+            resp = cStringIO.StringIO()
             for b in self.repo.branches(nodes):
-                req.write(" ".join(map(hex, b)) + "\n")
+                resp.write(" ".join(map(hex, b)) + "\n")
+            resp = resp.getvalue()
+            req.httphdr("application/mercurial-0.1", length=len(resp))
+            req.write(resp)
 
         elif cmd == 'between':
-            req.httphdr("application/mercurial-0.1")
             nodes = []
             if req.form.has_key('pairs'):
                 pairs = [map(bin, p.split("-"))
                          for p in req.form['pairs'][0].split(" ")]
+            resp = cStringIO.StringIO()
             for b in self.repo.between(pairs):
-                req.write(" ".join(map(hex, b)) + "\n")
+                resp.write(" ".join(map(hex, b)) + "\n")
+            resp = resp.getvalue()
+            req.httphdr("application/mercurial-0.1", length=len(resp))
+            req.write(resp)
 
         elif cmd == 'changegroup':
             req.httphdr("application/mercurial-0.1")
@@ -819,3 +825,4 @@ class hgweb(object):
 
         else:
             req.write(self.t("error"))
+        req.done()
diff --git a/mercurial/hgweb/request.py b/mercurial/hgweb/request.py
--- a/mercurial/hgweb/request.py
+++ b/mercurial/hgweb/request.py
@@ -16,6 +16,7 @@ class hgrequest(object):
         self.out = out or sys.stdout
         self.env = env or os.environ
         self.form = cgi.parse(self.inp, self.env, keep_blank_values=1)
+        self.will_close = True
 
     def write(self, *things):
         for thing in things:
@@ -29,16 +30,30 @@ class hgrequest(object):
                     if inst[0] != errno.ECONNRESET:
                         raise
 
+    def done(self):
+        if self.will_close:
+            self.inp.close()
+            self.out.close()
+        else:
+            self.out.flush()
+
     def header(self, headers=[('Content-type','text/html')]):
         for header in headers:
             self.out.write("%s: %s\r\n" % header)
         self.out.write("\r\n")
 
-    def httphdr(self, type, file="", size=0):
+    def httphdr(self, type, filename=None, length=0):
 
         headers = [('Content-type', type)]
-        if file:
-            headers.append(('Content-disposition', 'attachment; filename=%s' % file))
-        if size > 0:
-            headers.append(('Content-length', str(size)))
+        if filename:
+            headers.append(('Content-disposition', 'attachment; filename=%s' %
+                            filename))
+        # we do not yet support http 1.1 chunked transfer, so we have
+        # to force connection to close if content-length not known
+        if length:
+            headers.append(('Content-length', str(length)))
+            self.will_close = False
+        else:
+            headers.append(('Connection', 'close'))
+            self.will_close = True
         self.header(headers)
diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py
--- a/mercurial/hgweb/server.py
+++ b/mercurial/hgweb/server.py
@@ -27,6 +27,7 @@ def _splitURI(uri):
 
 class _hgwebhandler(object, BaseHTTPServer.BaseHTTPRequestHandler):
     def __init__(self, *args, **kargs):
+        self.protocol_version = 'HTTP/1.1'
         BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kargs)
 
     def log_error(self, format, *args):
@@ -85,7 +86,7 @@ class _hgwebhandler(object, BaseHTTPServ
 
         req = hgrequest(self.rfile, self.wfile, env)
         self.send_response(200, "Script output follows")
-        self.server.make_and_run_handler(req)
+        self.close_connection = self.server.make_and_run_handler(req)
 
 def create_server(ui, repo):
     use_threads = True
@@ -135,6 +136,7 @@ def create_server(ui, repo):
             else:
                 raise hg.RepoError(_('no repo found'))
             hgwebobj.run(req)
+            return req.will_close
 
     class IPv6HTTPServer(MercurialHTTPServer):
         address_family = getattr(socket, 'AF_INET6', None)