Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/hgweb/hgweb_mod.py @ 2471:6904e1ef8ad1
merge with crew.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Tue, 20 Jun 2006 23:58:45 -0700 |
parents | e10665147d26 |
children | 76ff5efe8181 d0db3462d568 |
comparison
equal
deleted
inserted
replaced
2470:fe1689273f84 | 2471:6904e1ef8ad1 |
---|---|
8 | 8 |
9 import os | 9 import os |
10 import os.path | 10 import os.path |
11 import mimetypes | 11 import mimetypes |
12 from mercurial.demandload import demandload | 12 from mercurial.demandload import demandload |
13 demandload(globals(), "re zlib ConfigParser cStringIO") | 13 demandload(globals(), "re zlib ConfigParser cStringIO sys tempfile") |
14 demandload(globals(), "mercurial:mdiff,ui,hg,util,archival,templater") | 14 demandload(globals(), "mercurial:mdiff,ui,hg,util,archival,templater") |
15 demandload(globals(), "mercurial.hgweb.request:hgrequest") | 15 demandload(globals(), "mercurial.hgweb.request:hgrequest") |
16 demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile") | 16 demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile") |
17 from mercurial.node import * | 17 from mercurial.node import * |
18 from mercurial.i18n import gettext as _ | 18 from mercurial.i18n import gettext as _ |
833 "static")) | 833 "static")) |
834 req.write(staticfile(static, fname) | 834 req.write(staticfile(static, fname) |
835 or self.t("error", error="%r not found" % fname)) | 835 or self.t("error", error="%r not found" % fname)) |
836 | 836 |
837 def do_capabilities(self, req): | 837 def do_capabilities(self, req): |
838 resp = '' | 838 resp = 'unbundle' |
839 req.httphdr("application/mercurial-0.1", length=len(resp)) | 839 req.httphdr("application/mercurial-0.1", length=len(resp)) |
840 req.write(resp) | 840 req.write(resp) |
841 | 841 |
842 def check_perm(self, req, op, default): | |
843 '''check permission for operation based on user auth. | |
844 return true if op allowed, else false. | |
845 default is policy to use if no config given.''' | |
846 | |
847 user = req.env.get('REMOTE_USER') | |
848 | |
849 deny = self.repo.ui.config('web', 'deny_' + op, '') | |
850 deny = deny.replace(',', ' ').split() | |
851 | |
852 if deny and (not user or deny == ['*'] or user in deny): | |
853 return False | |
854 | |
855 allow = self.repo.ui.config('web', 'allow_' + op, '') | |
856 allow = allow.replace(',', ' ').split() | |
857 | |
858 return (allow and (allow == ['*'] or user in allow)) or default | |
859 | |
860 def do_unbundle(self, req): | |
861 def bail(response, headers={}): | |
862 length = int(req.env['CONTENT_LENGTH']) | |
863 for s in util.filechunkiter(req, limit=length): | |
864 # drain incoming bundle, else client will not see | |
865 # response when run outside cgi script | |
866 pass | |
867 req.httphdr("application/mercurial-0.1", headers=headers) | |
868 req.write('0\n') | |
869 req.write(response) | |
870 | |
871 # require ssl by default, auth info cannot be sniffed and | |
872 # replayed | |
873 ssl_req = self.repo.ui.configbool('web', 'push_ssl', True) | |
874 if ssl_req and not req.env.get('HTTPS'): | |
875 bail(_('ssl required\n')) | |
876 return | |
877 | |
878 # do not allow push unless explicitly allowed | |
879 if not self.check_perm(req, 'push', False): | |
880 bail(_('push not authorized\n'), | |
881 headers={'status': '401 Unauthorized'}) | |
882 return | |
883 | |
884 req.httphdr("application/mercurial-0.1") | |
885 | |
886 their_heads = req.form['heads'][0].split(' ') | |
887 | |
888 def check_heads(): | |
889 heads = map(hex, self.repo.heads()) | |
890 return their_heads == [hex('force')] or their_heads == heads | |
891 | |
892 # fail early if possible | |
893 if not check_heads(): | |
894 bail(_('unsynced changes\n')) | |
895 return | |
896 | |
897 # do not lock repo until all changegroup data is | |
898 # streamed. save to temporary file. | |
899 | |
900 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') | |
901 fp = os.fdopen(fd, 'wb+') | |
902 try: | |
903 length = int(req.env['CONTENT_LENGTH']) | |
904 for s in util.filechunkiter(req, limit=length): | |
905 fp.write(s) | |
906 | |
907 lock = self.repo.lock() | |
908 try: | |
909 if not check_heads(): | |
910 req.write('0\n') | |
911 req.write(_('unsynced changes\n')) | |
912 return | |
913 | |
914 fp.seek(0) | |
915 | |
916 # send addchangegroup output to client | |
917 | |
918 old_stdout = sys.stdout | |
919 sys.stdout = cStringIO.StringIO() | |
920 | |
921 try: | |
922 ret = self.repo.addchangegroup(fp, 'serve') | |
923 req.write('%d\n' % ret) | |
924 req.write(sys.stdout.getvalue()) | |
925 finally: | |
926 sys.stdout = old_stdout | |
927 finally: | |
928 lock.release() | |
929 finally: | |
930 fp.close() | |
931 os.unlink(tempname) |