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)