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 |
|
|
77 | self.out.write(thing) | |
80 |
except |
|
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 |
|
|
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= |
|
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 |
|
719 | if req.form.has_key('style'): | |
705 |
style = |
|
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 = |
|
727 | port = req.env["SERVER_PORT"] | |
713 | port = port != "80" and (":" + port) or "" |
|
728 | port = port != "80" and (":" + port) or "" | |
714 |
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" % ( |
|
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 |
|
741 | if not req.form.has_key('cmd'): | |
727 |
|
|
742 | req.form['cmd'] = [self.t.cache['default'],] | |
728 |
|
743 | |||
729 |
if |
|
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 |
|
747 | if req.form.has_key('rev'): | |
733 |
hi = |
|
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 |
|
757 | elif req.form['cmd'][0] == 'changeset': | |
743 |
write(self.changeset( |
|
758 | req.write(self.changeset(req.form['node'][0])) | |
744 |
|
759 | |||
745 |
elif |
|
760 | elif req.form['cmd'][0] == 'manifest': | |
746 |
write(self.manifest( |
|
761 | req.write(self.manifest(req.form['manifest'][0], req.form['path'][0])) | |
747 |
|
762 | |||
748 |
elif |
|
763 | elif req.form['cmd'][0] == 'tags': | |
749 | write(self.tags()) |
|
764 | req.write(self.tags()) | |
750 |
|
765 | |||
751 |
elif |
|
766 | elif req.form['cmd'][0] == 'filediff': | |
752 |
write(self.filediff( |
|
767 | req.write(self.filediff(req.form['file'][0], req.form['node'][0])) | |
753 |
|
768 | |||
754 |
elif |
|
769 | elif req.form['cmd'][0] == 'file': | |
755 |
write(self.filerevision( |
|
770 | req.write(self.filerevision(req.form['file'][0], req.form['filenode'][0])) | |
756 |
|
771 | |||
757 |
elif |
|
772 | elif req.form['cmd'][0] == 'annotate': | |
758 |
write(self.fileannotate( |
|
773 | req.write(self.fileannotate(req.form['file'][0], req.form['filenode'][0])) | |
759 |
|
774 | |||
760 |
elif |
|
775 | elif req.form['cmd'][0] == 'filelog': | |
761 |
write(self.filelog( |
|
776 | req.write(self.filelog(req.form['file'][0], req.form['filenode'][0])) | |
762 |
|
777 | |||
763 |
elif |
|
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 |
|
|
781 | req.write(" ".join(map(hex, h)) + "\n") | |
767 |
|
782 | |||
768 |
elif |
|
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 |
|
786 | if req.form.has_key('nodes'): | |
772 |
nodes = map(bin, |
|
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 |
|
|
789 | req.write(" ".join(map(hex, b)) + "\n") | |
775 |
|
790 | |||
776 |
elif |
|
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 |
|
794 | if req.form.has_key('pairs'): | |
780 | pairs = [map(bin, p.split("-")) |
|
795 | pairs = [map(bin, p.split("-")) | |
781 |
for p in |
|
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 |
|
|
798 | req.write(" ".join(map(hex, b)) + "\n") | |
784 |
|
799 | |||
785 |
elif |
|
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 |
|
806 | if req.form.has_key('roots'): | |
792 |
nodes = map(bin, |
|
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 |
|
|
815 | req.write(z.compress(chunk)) | |
801 |
|
816 | |||
802 |
|
|
817 | req.write(z.flush()) | |
803 |
|
818 | |||
804 |
elif |
|
819 | elif req.form['cmd'][0] == 'archive': | |
805 |
changeset = bin( |
|
820 | changeset = bin(req.form['node'][0]) | |
806 |
type = |
|
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 |
|
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([ |
|
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 = |
|
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