changeset 1164:cf8185cf2a70

Merge with http://hannibal.lr-s.tudelft.nl/~vincent/fcgi/mercurial/fcgi/
author Thomas Arendsen Hein <thomas@intevation.de>
date Tue, 30 Aug 2005 18:10:20 +0200
parents 4650ec7ef690 (current diff) dacd3463ee3f (diff)
children 04be5eb73bb3
files
diffstat 1 files changed, 102 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/hgweb.py	Tue Aug 30 11:22:29 2005 +0200
+++ b/mercurial/hgweb.py	Tue Aug 30 18:10:20 2005 +0200
@@ -60,26 +60,40 @@
         return "/"
     return up + "/"
 
-def httphdr(type, file="", size=0):
-    sys.stdout.write('Content-type: %s\n' % type)
-    if file:
-        sys.stdout.write('Content-disposition: attachment; filename=%s\n'
-            % file)
-    if size > 0:
-        sys.stdout.write('Content-length: %d\n' % size)
-    sys.stdout.write('\n')
+class hgrequest:
+    def __init__(self, inp=None, out=None, env=None):
+        self.inp = inp or sys.stdin
+        self.out = out or sys.stdout
+        self.env = env or os.environ
+        self.form = cgi.parse(self.inp, self.env)
 
-def write(*things):
-    for thing in things:
-        if hasattr(thing, "__iter__"):
-            for part in thing:
-                write(part)
-        else:
-            try:
-                sys.stdout.write(str(thing))
-            except socket.error, x:
-                if x[0] != errno.ECONNRESET:
-                    raise
+    def write(self, *things):
+        for thing in things:
+            if hasattr(thing, "__iter__"):
+                for part in thing:
+                    self.write(part)
+            else:
+                try:
+                    self.out.write(thing)
+                except TypeError:
+                    self.out.write(str(thing))
+                except socket.error, x:
+                    if x[0] != errno.ECONNRESET:
+                        raise
+
+    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):
+
+        headers = [('Content-type', type)]
+        if file:
+            headers.append(('Content-disposition', 'attachment; filename=%s' % file))
+        if size > 0:
+            headers.append(('Content-length', str(size)))
+        self.header(headers)
 
 class templater:
     def __init__(self, mapfile, filters={}, defaults={}):
@@ -154,6 +168,8 @@
     "rfc822date": rfc822date,
     }
 
+
+
 class hgweb:
     def __init__(self, repo, name=None):
         if type(repo) == type(""):
@@ -635,7 +651,7 @@
                                          cl.parents(n), cl.rev),
                      diff=diff)
 
-    def archive(self, cnode, type):
+    def archive(self, req, cnode, type):
         cs = self.repo.changelog.read(cnode)
         mnode = cs[0]
         mf = self.repo.manifest.read(mnode)
@@ -658,9 +674,9 @@
                 zf.close()
 
                 f = open(tmp, 'r')
-                httphdr('application/zip', name[:-1] + '.zip',
+                req.httphdr('application/zip', name[:-1] + '.zip',
                         os.path.getsize(tmp))
-                sys.stdout.write(f.read())
+                req.write(f.read())
                 f.close()
             finally:
                 os.unlink(tmp)
@@ -670,11 +686,11 @@
             import time
             import tarfile
 
-            tf = tarfile.TarFile.open(mode='w|' + type, fileobj=sys.stdout)
+            tf = tarfile.TarFile.open(mode='w|' + type, fileobj=req.out)
             mff = self.repo.manifest.readflags(mnode)
             mtime = int(time.time())
 
-            httphdr('application/octet-stream', name[:-1] + '.tar.' + type)
+            req.httphdr('application/octet-stream', name[:-1] + '.tar.' + type)
             for fname in files:
                 rcont = self.repo.file(fname).read(mf[fname])
                 finfo = tarfile.TarInfo(name + fname)
@@ -688,7 +704,7 @@
     # tags -> list of changesets corresponding to tags
     # find tag, changeset, file
 
-    def run(self):
+    def run(self, req=hgrequest()):
         def header(**map):
             yield self.t("header", **map)
 
@@ -696,25 +712,24 @@
             yield self.t("footer", **map)
 
         self.refresh()
-        args = cgi.parse()
 
         t = self.repo.ui.config("web", "templates", templatepath())
         m = os.path.join(t, "map")
         style = self.repo.ui.config("web", "style", "")
-        if args.has_key('style'):
-            style = args['style'][0]
+        if req.form.has_key('style'):
+            style = req.form['style'][0]
         if style:
             b = os.path.basename("map-" + style)
             p = os.path.join(t, b)
             if os.path.isfile(p):
                 m = p
 
-        port = os.environ["SERVER_PORT"]
+        port = req.env["SERVER_PORT"]
         port = port != "80" and (":" + port) or ""
-        uri = os.environ["REQUEST_URI"]
+        uri = req.env["REQUEST_URI"]
         if "?" in uri:
             uri = uri.split("?")[0]
-        url = "http://%s%s%s" % (os.environ["SERVER_NAME"], port, uri)
+        url = "http://%s%s%s" % (req.env["SERVER_NAME"], port, uri)
 
         self.t = templater(m, common_filters,
                            {"url": url,
@@ -723,73 +738,73 @@
                             "footer": footer,
                            })
 
-        if not args.has_key('cmd'):
-            args['cmd'] = [self.t.cache['default'],]
+        if not req.form.has_key('cmd'):
+            req.form['cmd'] = [self.t.cache['default'],]
 
-        if args['cmd'][0] == 'changelog':
+        if req.form['cmd'][0] == 'changelog':
             c = self.repo.changelog.count() - 1
             hi = c
-            if args.has_key('rev'):
-                hi = args['rev'][0]
+            if req.form.has_key('rev'):
+                hi = req.form['rev'][0]
                 try:
                     hi = self.repo.changelog.rev(self.repo.lookup(hi))
                 except RepoError:
-                    write(self.search(hi))
+                    req.write(self.search(hi))
                     return
 
-            write(self.changelog(hi))
+            req.write(self.changelog(hi))
 
-        elif args['cmd'][0] == 'changeset':
-            write(self.changeset(args['node'][0]))
+        elif req.form['cmd'][0] == 'changeset':
+            req.write(self.changeset(req.form['node'][0]))
 
-        elif args['cmd'][0] == 'manifest':
-            write(self.manifest(args['manifest'][0], args['path'][0]))
+        elif req.form['cmd'][0] == 'manifest':
+            req.write(self.manifest(req.form['manifest'][0], req.form['path'][0]))
 
-        elif args['cmd'][0] == 'tags':
-            write(self.tags())
+        elif req.form['cmd'][0] == 'tags':
+            req.write(self.tags())
 
-        elif args['cmd'][0] == 'filediff':
-            write(self.filediff(args['file'][0], args['node'][0]))
+        elif req.form['cmd'][0] == 'filediff':
+            req.write(self.filediff(req.form['file'][0], req.form['node'][0]))
 
-        elif args['cmd'][0] == 'file':
-            write(self.filerevision(args['file'][0], args['filenode'][0]))
+        elif req.form['cmd'][0] == 'file':
+            req.write(self.filerevision(req.form['file'][0], req.form['filenode'][0]))
 
-        elif args['cmd'][0] == 'annotate':
-            write(self.fileannotate(args['file'][0], args['filenode'][0]))
+        elif req.form['cmd'][0] == 'annotate':
+            req.write(self.fileannotate(req.form['file'][0], req.form['filenode'][0]))
 
-        elif args['cmd'][0] == 'filelog':
-            write(self.filelog(args['file'][0], args['filenode'][0]))
+        elif req.form['cmd'][0] == 'filelog':
+            req.write(self.filelog(req.form['file'][0], req.form['filenode'][0]))
 
-        elif args['cmd'][0] == 'heads':
-            httphdr("application/mercurial-0.1")
+        elif req.form['cmd'][0] == 'heads':
+            req.httphdr("application/mercurial-0.1")
             h = self.repo.heads()
-            sys.stdout.write(" ".join(map(hex, h)) + "\n")
+            req.write(" ".join(map(hex, h)) + "\n")
 
-        elif args['cmd'][0] == 'branches':
-            httphdr("application/mercurial-0.1")
+        elif req.form['cmd'][0] == 'branches':
+            req.httphdr("application/mercurial-0.1")
             nodes = []
-            if args.has_key('nodes'):
-                nodes = map(bin, args['nodes'][0].split(" "))
+            if req.form.has_key('nodes'):
+                nodes = map(bin, req.form['nodes'][0].split(" "))
             for b in self.repo.branches(nodes):
-                sys.stdout.write(" ".join(map(hex, b)) + "\n")
+                req.write(" ".join(map(hex, b)) + "\n")
 
-        elif args['cmd'][0] == 'between':
-            httphdr("application/mercurial-0.1")
+        elif req.form['cmd'][0] == 'between':
+            req.httphdr("application/mercurial-0.1")
             nodes = []
-            if args.has_key('pairs'):
+            if req.form.has_key('pairs'):
                 pairs = [map(bin, p.split("-"))
-                         for p in args['pairs'][0].split(" ")]
+                         for p in req.form['pairs'][0].split(" ")]
             for b in self.repo.between(pairs):
-                sys.stdout.write(" ".join(map(hex, b)) + "\n")
+                req.write(" ".join(map(hex, b)) + "\n")
 
-        elif args['cmd'][0] == 'changegroup':
-            httphdr("application/mercurial-0.1")
+        elif req.form['cmd'][0] == 'changegroup':
+            req.httphdr("application/mercurial-0.1")
             nodes = []
             if not self.allowpull:
                 return
 
-            if args.has_key('roots'):
-                nodes = map(bin, args['roots'][0].split(" "))
+            if req.form.has_key('roots'):
+                nodes = map(bin, req.form['roots'][0].split(" "))
 
             z = zlib.compressobj()
             f = self.repo.changegroup(nodes)
@@ -797,22 +812,22 @@
                 chunk = f.read(4096)
                 if not chunk:
                     break
-                sys.stdout.write(z.compress(chunk))
+                req.write(z.compress(chunk))
 
-            sys.stdout.write(z.flush())
+            req.write(z.flush())
 
-        elif args['cmd'][0] == 'archive':
-            changeset = bin(args['node'][0])
-            type = args['type'][0]
+        elif req.form['cmd'][0] == 'archive':
+            changeset = bin(req.form['node'][0])
+            type = req.form['type'][0]
             if (type in self.archives and
                 self.repo.ui.configbool("web", "allow" + type, False)):
-                self.archive(changeset, type)
+                self.archive(req, changeset, type)
                 return
 
-            write(self.t("error"))
+            req.write(self.t("error"))
 
         else:
-            write(self.t("error"))
+            req.write(self.t("error"))
 
 def create_server(repo):
 
@@ -893,19 +908,16 @@
                     accept = accept + line[7:].split(',')
             env['HTTP_ACCEPT'] = ','.join(accept)
 
-            os.environ.update(env)
-
-            save = sys.argv, sys.stdin, sys.stdout, sys.stderr
+            save = sys.argv, sys.stderr
             try:
-                sys.stdin = self.rfile
-                sys.stdout = self.wfile
+                req = hgrequest(self.rfile, self.wfile, env)
                 sys.argv = ["hgweb.py"]
                 if '=' not in query:
                     sys.argv.append(query)
                 self.send_response(200, "Script output follows")
-                hg.run()
+                hg.run(req)
             finally:
-                sys.argv, sys.stdin, sys.stdout, sys.stderr = save
+                sys.argv, sys.stderr = save
 
     hg = hgweb(repo)
     if use_ipv6:
@@ -933,7 +945,7 @@
             self.repos = cp.items("paths")
             self.repos.sort()
 
-    def run(self):
+    def run(self, req=hgrequest()):
         def header(**map):
             yield tmpl("header", **map)
 
@@ -951,7 +963,7 @@
                 u.readconfig(file(os.path.join(path, '.hg', 'hgrc')))
                 get = u.config
 
-                url = ('/'.join([os.environ["REQUEST_URI"], name])
+                url = ('/'.join([req.env["REQUEST_URI"], name])
                        .replace("//", "/"))
 
                 yield dict(contact=get("web", "contact") or
@@ -965,12 +977,12 @@
 
                 parity = 1 - parity
 
-        virtual = os.environ.get("PATH_INFO", "").strip('/')
+        virtual = req.env.get("PATH_INFO", "").strip('/')
         if virtual:
             real = dict(self.repos).get(virtual)
             if real:
-                hgweb(real).run()
+                hgweb(real).run(req)
             else:
-                write(tmpl("notfound", repo=virtual))
+                req.write(tmpl("notfound", repo=virtual))
         else:
-            write(tmpl("index", entries=entries))
+            req.write(tmpl("index", entries=entries))