comparison mercurial/hgweb.py @ 1777:a2316878f19d

[hgweb] Static content serving
author Josef "Jeff" Sipek <jeffpc@optonline.net>
date Sat, 18 Feb 2006 21:53:41 -0500
parents 41d884f741ca
children a1e6e02e9d05
comparison
equal deleted inserted replaced
1776:686bf56c17d0 1777:a2316878f19d
5 # 5 #
6 # This software may be used and distributed according to the terms 6 # This software may be used and distributed according to the terms
7 # of the GNU General Public License, incorporated herein by reference. 7 # of the GNU General Public License, incorporated herein by reference.
8 8
9 import os, cgi, sys, urllib 9 import os, cgi, sys, urllib
10 import mimetypes
10 from demandload import demandload 11 from demandload import demandload
11 demandload(globals(), "mdiff time re socket zlib errno ui hg ConfigParser") 12 demandload(globals(), "mdiff time re socket zlib errno ui hg ConfigParser")
12 demandload(globals(), "zipfile tempfile StringIO tarfile BaseHTTPServer util") 13 demandload(globals(), "zipfile tempfile StringIO tarfile BaseHTTPServer util")
13 demandload(globals(), "mimetypes") 14 demandload(globals(), "mimetypes")
14 from node import * 15 from node import *
841 'fa': [('cmd', ['annotate']), ('filenode', None)], 842 'fa': [('cmd', ['annotate']), ('filenode', None)],
842 'mf': [('cmd', ['manifest']), ('manifest', None)], 843 'mf': [('cmd', ['manifest']), ('manifest', None)],
843 'ca': [('cmd', ['archive']), ('node', None)], 844 'ca': [('cmd', ['archive']), ('node', None)],
844 'tags': [('cmd', ['tags'])], 845 'tags': [('cmd', ['tags'])],
845 'tip': [('cmd', ['changeset']), ('node', ['tip'])], 846 'tip': [('cmd', ['changeset']), ('node', ['tip'])],
847 'static': [('cmd', ['static']), ('file', None)]
846 } 848 }
847 849
848 for k in shortcuts.iterkeys(): 850 for k in shortcuts.iterkeys():
849 if form.has_key(k): 851 if form.has_key(k):
850 for name, value in shortcuts[k]: 852 for name, value in shortcuts[k]:
856 self.refresh() 858 self.refresh()
857 859
858 expand_form(req.form) 860 expand_form(req.form)
859 861
860 t = self.repo.ui.config("web", "templates", templatepath()) 862 t = self.repo.ui.config("web", "templates", templatepath())
863 static = self.repo.ui.config("web", "static", os.path.join(t,"static"))
861 m = os.path.join(t, "map") 864 m = os.path.join(t, "map")
862 style = self.repo.ui.config("web", "style", "") 865 style = self.repo.ui.config("web", "style", "")
863 if req.form.has_key('style'): 866 if req.form.has_key('style'):
864 style = req.form['style'][0] 867 style = req.form['style'][0]
865 if style: 868 if style:
978 self.repo.ui.configbool("web", "allow" + type, False)): 981 self.repo.ui.configbool("web", "allow" + type, False)):
979 self.archive(req, changeset, type) 982 self.archive(req, changeset, type)
980 return 983 return
981 984
982 req.write(self.t("error")) 985 req.write(self.t("error"))
986
987 elif req.form['cmd'][0] == 'static':
988 fname = req.form['file'][0]
989
990 fname = os.path.realpath(os.path.join(static, fname))
991
992 try:
993 # the static dir should be a substring in the real
994 # file path, if it is not, we have something strange
995 # going on => security breach attempt?
996 #
997 # This will either:
998 # 1) find the `static' path at index 0 = success
999 # 2) find the `static' path at other index = error
1000 # 3) not find the `static' path = ValueError generated
1001 if fname.index(static) != 0:
1002 # generate ValueError manually
1003 raise ValueError()
1004
1005 os.stat(fname)
1006
1007 ct = mimetypes.guess_type(fname)[0]
1008 if ct == None:
1009 ct = "text/plain"
1010
1011 req.write("Content-type: " + ct + "\n\n" + file(fname).read())
1012 except ValueError:
1013 # security breach attempt
1014 req.write(self.t("error"))
1015 except OSError, e:
1016 if e.errno == errno.ENOENT:
1017 req.write(self.t("error"))
983 1018
984 else: 1019 else:
985 req.write(self.t("error")) 1020 req.write(self.t("error"))
986 1021
987 def create_server(repo): 1022 def create_server(repo):