##// END OF EJS Templates
Merge with http://hannibal.lr-s.tudelft.nl/~vincent/fcgi/mercurial/fcgi/
Thomas Arendsen Hein -
r1164:cf8185cf merge default
parent child Browse files
Show More
@@ -60,26 +60,40 b' def up(p):'
60 return "/"
60 return "/"
61 return up + "/"
61 return up + "/"
62
62
63 def httphdr(type, file="", size=0):
63 class hgrequest:
64 sys.stdout.write('Content-type: %s\n' % type)
64 def __init__(self, inp=None, out=None, env=None):
65 if file:
65 self.inp = inp or sys.stdin
66 sys.stdout.write('Content-disposition: attachment; filename=%s\n'
66 self.out = out or sys.stdout
67 % file)
67 self.env = env or os.environ
68 if size > 0:
68 self.form = cgi.parse(self.inp, self.env)
69 sys.stdout.write('Content-length: %d\n' % size)
70 sys.stdout.write('\n')
71
69
72 def write(*things):
70 def write(self, *things):
73 for thing in things:
71 for thing in things:
74 if hasattr(thing, "__iter__"):
72 if hasattr(thing, "__iter__"):
75 for part in thing:
73 for part in thing:
76 write(part)
74 self.write(part)
77 else:
75 else:
78 try:
76 try:
79 sys.stdout.write(str(thing))
77 self.out.write(thing)
80 except socket.error, x:
78 except TypeError:
81 if x[0] != errno.ECONNRESET:
79 self.out.write(str(thing))
82 raise
80 except socket.error, x:
81 if x[0] != errno.ECONNRESET:
82 raise
83
84 def header(self, headers=[('Content-type','text/html')]):
85 for header in headers:
86 self.out.write("%s: %s\r\n" % header)
87 self.out.write("\r\n")
88
89 def httphdr(self, type, file="", size=0):
90
91 headers = [('Content-type', type)]
92 if file:
93 headers.append(('Content-disposition', 'attachment; filename=%s' % file))
94 if size > 0:
95 headers.append(('Content-length', str(size)))
96 self.header(headers)
83
97
84 class templater:
98 class templater:
85 def __init__(self, mapfile, filters={}, defaults={}):
99 def __init__(self, mapfile, filters={}, defaults={}):
@@ -154,6 +168,8 b' common_filters = {'
154 "rfc822date": rfc822date,
168 "rfc822date": rfc822date,
155 }
169 }
156
170
171
172
157 class hgweb:
173 class hgweb:
158 def __init__(self, repo, name=None):
174 def __init__(self, repo, name=None):
159 if type(repo) == type(""):
175 if type(repo) == type(""):
@@ -635,7 +651,7 b' class hgweb:'
635 cl.parents(n), cl.rev),
651 cl.parents(n), cl.rev),
636 diff=diff)
652 diff=diff)
637
653
638 def archive(self, cnode, type):
654 def archive(self, req, cnode, type):
639 cs = self.repo.changelog.read(cnode)
655 cs = self.repo.changelog.read(cnode)
640 mnode = cs[0]
656 mnode = cs[0]
641 mf = self.repo.manifest.read(mnode)
657 mf = self.repo.manifest.read(mnode)
@@ -658,9 +674,9 b' class hgweb:'
658 zf.close()
674 zf.close()
659
675
660 f = open(tmp, 'r')
676 f = open(tmp, 'r')
661 httphdr('application/zip', name[:-1] + '.zip',
677 req.httphdr('application/zip', name[:-1] + '.zip',
662 os.path.getsize(tmp))
678 os.path.getsize(tmp))
663 sys.stdout.write(f.read())
679 req.write(f.read())
664 f.close()
680 f.close()
665 finally:
681 finally:
666 os.unlink(tmp)
682 os.unlink(tmp)
@@ -670,11 +686,11 b' class hgweb:'
670 import time
686 import time
671 import tarfile
687 import tarfile
672
688
673 tf = tarfile.TarFile.open(mode='w|' + type, fileobj=sys.stdout)
689 tf = tarfile.TarFile.open(mode='w|' + type, fileobj=req.out)
674 mff = self.repo.manifest.readflags(mnode)
690 mff = self.repo.manifest.readflags(mnode)
675 mtime = int(time.time())
691 mtime = int(time.time())
676
692
677 httphdr('application/octet-stream', name[:-1] + '.tar.' + type)
693 req.httphdr('application/octet-stream', name[:-1] + '.tar.' + type)
678 for fname in files:
694 for fname in files:
679 rcont = self.repo.file(fname).read(mf[fname])
695 rcont = self.repo.file(fname).read(mf[fname])
680 finfo = tarfile.TarInfo(name + fname)
696 finfo = tarfile.TarInfo(name + fname)
@@ -688,7 +704,7 b' class hgweb:'
688 # tags -> list of changesets corresponding to tags
704 # tags -> list of changesets corresponding to tags
689 # find tag, changeset, file
705 # find tag, changeset, file
690
706
691 def run(self):
707 def run(self, req=hgrequest()):
692 def header(**map):
708 def header(**map):
693 yield self.t("header", **map)
709 yield self.t("header", **map)
694
710
@@ -696,25 +712,24 b' class hgweb:'
696 yield self.t("footer", **map)
712 yield self.t("footer", **map)
697
713
698 self.refresh()
714 self.refresh()
699 args = cgi.parse()
700
715
701 t = self.repo.ui.config("web", "templates", templatepath())
716 t = self.repo.ui.config("web", "templates", templatepath())
702 m = os.path.join(t, "map")
717 m = os.path.join(t, "map")
703 style = self.repo.ui.config("web", "style", "")
718 style = self.repo.ui.config("web", "style", "")
704 if args.has_key('style'):
719 if req.form.has_key('style'):
705 style = args['style'][0]
720 style = req.form['style'][0]
706 if style:
721 if style:
707 b = os.path.basename("map-" + style)
722 b = os.path.basename("map-" + style)
708 p = os.path.join(t, b)
723 p = os.path.join(t, b)
709 if os.path.isfile(p):
724 if os.path.isfile(p):
710 m = p
725 m = p
711
726
712 port = os.environ["SERVER_PORT"]
727 port = req.env["SERVER_PORT"]
713 port = port != "80" and (":" + port) or ""
728 port = port != "80" and (":" + port) or ""
714 uri = os.environ["REQUEST_URI"]
729 uri = req.env["REQUEST_URI"]
715 if "?" in uri:
730 if "?" in uri:
716 uri = uri.split("?")[0]
731 uri = uri.split("?")[0]
717 url = "http://%s%s%s" % (os.environ["SERVER_NAME"], port, uri)
732 url = "http://%s%s%s" % (req.env["SERVER_NAME"], port, uri)
718
733
719 self.t = templater(m, common_filters,
734 self.t = templater(m, common_filters,
720 {"url": url,
735 {"url": url,
@@ -723,73 +738,73 b' class hgweb:'
723 "footer": footer,
738 "footer": footer,
724 })
739 })
725
740
726 if not args.has_key('cmd'):
741 if not req.form.has_key('cmd'):
727 args['cmd'] = [self.t.cache['default'],]
742 req.form['cmd'] = [self.t.cache['default'],]
728
743
729 if args['cmd'][0] == 'changelog':
744 if req.form['cmd'][0] == 'changelog':
730 c = self.repo.changelog.count() - 1
745 c = self.repo.changelog.count() - 1
731 hi = c
746 hi = c
732 if args.has_key('rev'):
747 if req.form.has_key('rev'):
733 hi = args['rev'][0]
748 hi = req.form['rev'][0]
734 try:
749 try:
735 hi = self.repo.changelog.rev(self.repo.lookup(hi))
750 hi = self.repo.changelog.rev(self.repo.lookup(hi))
736 except RepoError:
751 except RepoError:
737 write(self.search(hi))
752 req.write(self.search(hi))
738 return
753 return
739
754
740 write(self.changelog(hi))
755 req.write(self.changelog(hi))
741
756
742 elif args['cmd'][0] == 'changeset':
757 elif req.form['cmd'][0] == 'changeset':
743 write(self.changeset(args['node'][0]))
758 req.write(self.changeset(req.form['node'][0]))
744
759
745 elif args['cmd'][0] == 'manifest':
760 elif req.form['cmd'][0] == 'manifest':
746 write(self.manifest(args['manifest'][0], args['path'][0]))
761 req.write(self.manifest(req.form['manifest'][0], req.form['path'][0]))
747
762
748 elif args['cmd'][0] == 'tags':
763 elif req.form['cmd'][0] == 'tags':
749 write(self.tags())
764 req.write(self.tags())
750
765
751 elif args['cmd'][0] == 'filediff':
766 elif req.form['cmd'][0] == 'filediff':
752 write(self.filediff(args['file'][0], args['node'][0]))
767 req.write(self.filediff(req.form['file'][0], req.form['node'][0]))
753
768
754 elif args['cmd'][0] == 'file':
769 elif req.form['cmd'][0] == 'file':
755 write(self.filerevision(args['file'][0], args['filenode'][0]))
770 req.write(self.filerevision(req.form['file'][0], req.form['filenode'][0]))
756
771
757 elif args['cmd'][0] == 'annotate':
772 elif req.form['cmd'][0] == 'annotate':
758 write(self.fileannotate(args['file'][0], args['filenode'][0]))
773 req.write(self.fileannotate(req.form['file'][0], req.form['filenode'][0]))
759
774
760 elif args['cmd'][0] == 'filelog':
775 elif req.form['cmd'][0] == 'filelog':
761 write(self.filelog(args['file'][0], args['filenode'][0]))
776 req.write(self.filelog(req.form['file'][0], req.form['filenode'][0]))
762
777
763 elif args['cmd'][0] == 'heads':
778 elif req.form['cmd'][0] == 'heads':
764 httphdr("application/mercurial-0.1")
779 req.httphdr("application/mercurial-0.1")
765 h = self.repo.heads()
780 h = self.repo.heads()
766 sys.stdout.write(" ".join(map(hex, h)) + "\n")
781 req.write(" ".join(map(hex, h)) + "\n")
767
782
768 elif args['cmd'][0] == 'branches':
783 elif req.form['cmd'][0] == 'branches':
769 httphdr("application/mercurial-0.1")
784 req.httphdr("application/mercurial-0.1")
770 nodes = []
785 nodes = []
771 if args.has_key('nodes'):
786 if req.form.has_key('nodes'):
772 nodes = map(bin, args['nodes'][0].split(" "))
787 nodes = map(bin, req.form['nodes'][0].split(" "))
773 for b in self.repo.branches(nodes):
788 for b in self.repo.branches(nodes):
774 sys.stdout.write(" ".join(map(hex, b)) + "\n")
789 req.write(" ".join(map(hex, b)) + "\n")
775
790
776 elif args['cmd'][0] == 'between':
791 elif req.form['cmd'][0] == 'between':
777 httphdr("application/mercurial-0.1")
792 req.httphdr("application/mercurial-0.1")
778 nodes = []
793 nodes = []
779 if args.has_key('pairs'):
794 if req.form.has_key('pairs'):
780 pairs = [map(bin, p.split("-"))
795 pairs = [map(bin, p.split("-"))
781 for p in args['pairs'][0].split(" ")]
796 for p in req.form['pairs'][0].split(" ")]
782 for b in self.repo.between(pairs):
797 for b in self.repo.between(pairs):
783 sys.stdout.write(" ".join(map(hex, b)) + "\n")
798 req.write(" ".join(map(hex, b)) + "\n")
784
799
785 elif args['cmd'][0] == 'changegroup':
800 elif req.form['cmd'][0] == 'changegroup':
786 httphdr("application/mercurial-0.1")
801 req.httphdr("application/mercurial-0.1")
787 nodes = []
802 nodes = []
788 if not self.allowpull:
803 if not self.allowpull:
789 return
804 return
790
805
791 if args.has_key('roots'):
806 if req.form.has_key('roots'):
792 nodes = map(bin, args['roots'][0].split(" "))
807 nodes = map(bin, req.form['roots'][0].split(" "))
793
808
794 z = zlib.compressobj()
809 z = zlib.compressobj()
795 f = self.repo.changegroup(nodes)
810 f = self.repo.changegroup(nodes)
@@ -797,22 +812,22 b' class hgweb:'
797 chunk = f.read(4096)
812 chunk = f.read(4096)
798 if not chunk:
813 if not chunk:
799 break
814 break
800 sys.stdout.write(z.compress(chunk))
815 req.write(z.compress(chunk))
801
816
802 sys.stdout.write(z.flush())
817 req.write(z.flush())
803
818
804 elif args['cmd'][0] == 'archive':
819 elif req.form['cmd'][0] == 'archive':
805 changeset = bin(args['node'][0])
820 changeset = bin(req.form['node'][0])
806 type = args['type'][0]
821 type = req.form['type'][0]
807 if (type in self.archives and
822 if (type in self.archives and
808 self.repo.ui.configbool("web", "allow" + type, False)):
823 self.repo.ui.configbool("web", "allow" + type, False)):
809 self.archive(changeset, type)
824 self.archive(req, changeset, type)
810 return
825 return
811
826
812 write(self.t("error"))
827 req.write(self.t("error"))
813
828
814 else:
829 else:
815 write(self.t("error"))
830 req.write(self.t("error"))
816
831
817 def create_server(repo):
832 def create_server(repo):
818
833
@@ -893,19 +908,16 b' def create_server(repo):'
893 accept = accept + line[7:].split(',')
908 accept = accept + line[7:].split(',')
894 env['HTTP_ACCEPT'] = ','.join(accept)
909 env['HTTP_ACCEPT'] = ','.join(accept)
895
910
896 os.environ.update(env)
911 save = sys.argv, sys.stderr
897
898 save = sys.argv, sys.stdin, sys.stdout, sys.stderr
899 try:
912 try:
900 sys.stdin = self.rfile
913 req = hgrequest(self.rfile, self.wfile, env)
901 sys.stdout = self.wfile
902 sys.argv = ["hgweb.py"]
914 sys.argv = ["hgweb.py"]
903 if '=' not in query:
915 if '=' not in query:
904 sys.argv.append(query)
916 sys.argv.append(query)
905 self.send_response(200, "Script output follows")
917 self.send_response(200, "Script output follows")
906 hg.run()
918 hg.run(req)
907 finally:
919 finally:
908 sys.argv, sys.stdin, sys.stdout, sys.stderr = save
920 sys.argv, sys.stderr = save
909
921
910 hg = hgweb(repo)
922 hg = hgweb(repo)
911 if use_ipv6:
923 if use_ipv6:
@@ -933,7 +945,7 b' class hgwebdir:'
933 self.repos = cp.items("paths")
945 self.repos = cp.items("paths")
934 self.repos.sort()
946 self.repos.sort()
935
947
936 def run(self):
948 def run(self, req=hgrequest()):
937 def header(**map):
949 def header(**map):
938 yield tmpl("header", **map)
950 yield tmpl("header", **map)
939
951
@@ -951,7 +963,7 b' class hgwebdir:'
951 u.readconfig(file(os.path.join(path, '.hg', 'hgrc')))
963 u.readconfig(file(os.path.join(path, '.hg', 'hgrc')))
952 get = u.config
964 get = u.config
953
965
954 url = ('/'.join([os.environ["REQUEST_URI"], name])
966 url = ('/'.join([req.env["REQUEST_URI"], name])
955 .replace("//", "/"))
967 .replace("//", "/"))
956
968
957 yield dict(contact=get("web", "contact") or
969 yield dict(contact=get("web", "contact") or
@@ -965,12 +977,12 b' class hgwebdir:'
965
977
966 parity = 1 - parity
978 parity = 1 - parity
967
979
968 virtual = os.environ.get("PATH_INFO", "").strip('/')
980 virtual = req.env.get("PATH_INFO", "").strip('/')
969 if virtual:
981 if virtual:
970 real = dict(self.repos).get(virtual)
982 real = dict(self.repos).get(virtual)
971 if real:
983 if real:
972 hgweb(real).run()
984 hgweb(real).run(req)
973 else:
985 else:
974 write(tmpl("notfound", repo=virtual))
986 req.write(tmpl("notfound", repo=virtual))
975 else:
987 else:
976 write(tmpl("index", entries=entries))
988 req.write(tmpl("index", entries=entries))
General Comments 0
You need to be logged in to leave comments. Login now