changeset 2514:419c42223bee

Really fix http headers for web UI and issue 254. This also arranges for static content to allow a keepalive connection.
author Eric Hopper <hopper@omnifarious.org>
date Tue, 27 Jun 2006 09:33:12 -0700
parents f22e3e8fd457
children a6700c222314 84655f721f39
files mercurial/hgweb/common.py mercurial/hgweb/hgweb_mod.py mercurial/hgweb/hgwebdir_mod.py mercurial/hgweb/request.py
diffstat 4 files changed, 25 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/hgweb/common.py	Tue Jun 27 09:30:50 2006 -0700
+++ b/mercurial/hgweb/common.py	Tue Jun 27 09:33:12 2006 -0700
@@ -17,7 +17,7 @@
     else:
         return os.stat(hg_path).st_mtime
 
-def staticfile(directory, fname):
+def staticfile(directory, fname, req):
     """return a file inside directory with guessed content-type header
 
     fname always uses '/' as directory separator and isn't allowed to
@@ -36,7 +36,9 @@
     try:
         os.stat(path)
         ct = mimetypes.guess_type(path)[0] or "text/plain"
-        return "Content-type: %s\n\n%s" % (ct, file(path).read())
+        req.header([('Content-type', ct),
+                    ('Content-length', os.path.getsize(path))])
+        return file(path).read()
     except (TypeError, OSError):
         # illegal fname or unreadable file
         return ""
--- a/mercurial/hgweb/hgweb_mod.py	Tue Jun 27 09:30:50 2006 -0700
+++ b/mercurial/hgweb/hgweb_mod.py	Tue Jun 27 09:33:12 2006 -0700
@@ -10,7 +10,7 @@
 import os.path
 import mimetypes
 from mercurial.demandload import demandload
-demandload(globals(), "re zlib ConfigParser cStringIO sys tempfile")
+demandload(globals(), "re zlib ConfigParser mimetools cStringIO sys tempfile")
 demandload(globals(), "mercurial:mdiff,ui,hg,util,archival,templater")
 demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile")
 from mercurial.node import *
@@ -652,7 +652,10 @@
 
     def run(self, req):
         def header(**map):
-            yield self.t("header", **map)
+            header_file = cStringIO.StringIO(''.join(self.t("header", **map)))
+            msg = mimetools.Message(header_file, 0)
+            req.header(msg.items())
+            yield header_file.read()
 
         def footer(**map):
             yield self.t("footer",
@@ -828,7 +831,7 @@
         static = self.repo.ui.config("web", "static",
                                      os.path.join(self.templatepath,
                                                   "static"))
-        req.write(staticfile(static, fname)
+        req.write(staticfile(static, fname, req)
                   or self.t("error", error="%r not found" % fname))
 
     def do_capabilities(self, req):
--- a/mercurial/hgweb/hgwebdir_mod.py	Tue Jun 27 09:30:50 2006 -0700
+++ b/mercurial/hgweb/hgwebdir_mod.py	Tue Jun 27 09:33:12 2006 -0700
@@ -8,7 +8,7 @@
 
 import os
 from mercurial.demandload import demandload
-demandload(globals(), "ConfigParser")
+demandload(globals(), "ConfigParser mimetools cStringIO")
 demandload(globals(), "mercurial:ui,hg,util,templater")
 demandload(globals(), "mercurial.hgweb.hgweb_mod:hgweb")
 demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile")
@@ -48,7 +48,10 @@
 
     def run(self, req):
         def header(**map):
-            yield tmpl("header", **map)
+            header_file = cStringIO.StringIO(''.join(tmpl("header", **map)))
+            msg = mimetools.Message(header_file, 0)
+            req.header(msg.items())
+            yield header_file.read()
 
         def footer(**map):
             yield tmpl("footer", motd=self.motd, **map)
@@ -132,7 +135,7 @@
             if req.form.has_key('static'):
                 static = os.path.join(templater.templatepath(), "static")
                 fname = req.form['static'][0]
-                req.write(staticfile(static, fname)
+                req.write(staticfile(static, fname, req)
                           or tmpl("error", error="%r not found" % fname))
             else:
                 sortable = ["name", "description", "contact", "lastchange"]
--- a/mercurial/hgweb/request.py	Tue Jun 27 09:30:50 2006 -0700
+++ b/mercurial/hgweb/request.py	Tue Jun 27 09:33:12 2006 -0700
@@ -57,20 +57,21 @@
         return self.inp.read(count)
 
     def write(self, *things):
-        if self.server_write is None:
-            if not self.headers:
-                self.header()
-            self.server_write = self.start_response('200 Script output follows',
-                                                    self.headers)
-            self.start_response = None
-            self.headers = None
         for thing in things:
             if hasattr(thing, "__iter__"):
                 for part in thing:
                     self.write(part)
             else:
+                thing = str(thing)
+                if self.server_write is None:
+                    if not self.headers:
+                        raise RuntimeError("request.write called before headers sent (%s)." % thing)
+                    self.server_write = self.start_response('200 Script output follows',
+                                                            self.headers)
+                    self.start_response = None
+                    self.headers = None
                 try:
-                    self.server_write(str(thing))
+                    self.server_write(thing)
                 except socket.error, inst:
                     if inst[0] != errno.ECONNRESET:
                         raise