comparison mercurial/hgweb.py @ 1793:83c6d8355909

Allow serving static files from hgwebdir to fix CSS and favicon.
author Thomas Arendsen Hein <thomas@intevation.de>
date Wed, 22 Feb 2006 09:14:46 +0100
parents a161c61ba8ed
children 36e19e3da12d
comparison
equal deleted inserted replaced
1792:a161c61ba8ed 1793:83c6d8355909
69 cl_path = os.path.join(hg_path, "00changelog.i") 69 cl_path = os.path.join(hg_path, "00changelog.i")
70 if os.path.exists(os.path.join(cl_path)): 70 if os.path.exists(os.path.join(cl_path)):
71 return os.stat(cl_path).st_mtime 71 return os.stat(cl_path).st_mtime
72 else: 72 else:
73 return os.stat(hg_path).st_mtime 73 return os.stat(hg_path).st_mtime
74
75 def staticfile(directory, fname):
76 fname = os.path.realpath(os.path.join(directory, fname))
77
78 try:
79 # the static dir should be a substring in the real
80 # file path, if it is not, we have something strange
81 # going on => security breach attempt?
82 #
83 # This will either:
84 # 1) find the `static' path at index 0 = success
85 # 2) find the `static' path at other index = error
86 # 3) not find the `static' path = ValueError generated
87 if fname.index(directory) != 0:
88 # generate ValueError manually
89 raise ValueError()
90
91 os.stat(fname)
92
93 ct = mimetypes.guess_type(fname)[0] or "text/plain"
94 return "Content-type: %s\n\n%s" % (ct, file(fname).read())
95 except ValueError:
96 # security breach attempt
97 return ""
98 except OSError, e:
99 if e.errno == errno.ENOENT:
100 return ""
74 101
75 class hgrequest(object): 102 class hgrequest(object):
76 def __init__(self, inp=None, out=None, env=None): 103 def __init__(self, inp=None, out=None, env=None):
77 self.inp = inp or sys.stdin 104 self.inp = inp or sys.stdin
78 self.out = out or sys.stdout 105 self.out = out or sys.stdout
986 1013
987 req.write(self.t("error")) 1014 req.write(self.t("error"))
988 1015
989 elif req.form['cmd'][0] == 'static': 1016 elif req.form['cmd'][0] == 'static':
990 fname = req.form['file'][0] 1017 fname = req.form['file'][0]
991 1018 req.write(staticfile(static, fname)
992 fname = os.path.realpath(os.path.join(static, fname)) 1019 or tmpl("error", error="%r not found" % fname))
993
994 try:
995 # the static dir should be a substring in the real
996 # file path, if it is not, we have something strange
997 # going on => security breach attempt?
998 #
999 # This will either:
1000 # 1) find the `static' path at index 0 = success
1001 # 2) find the `static' path at other index = error
1002 # 3) not find the `static' path = ValueError generated
1003 if fname.index(static) != 0:
1004 # generate ValueError manually
1005 raise ValueError()
1006
1007 os.stat(fname)
1008
1009 ct = mimetypes.guess_type(fname)[0] or "text/plain"
1010 req.write("Content-type: %s\n\n" % ct, file(fname).read())
1011 except ValueError:
1012 # security breach attempt
1013 req.write(self.t("error"))
1014 except OSError, e:
1015 if e.errno == errno.ENOENT:
1016 req.write(self.t("error"))
1017 1020
1018 else: 1021 else:
1019 req.write(self.t("error")) 1022 req.write(self.t("error"))
1020 1023
1021 def create_server(repo): 1024 def create_server(repo):
1174 except hg.RepoError, inst: 1177 except hg.RepoError, inst:
1175 req.write(tmpl("error", error=str(inst))) 1178 req.write(tmpl("error", error=str(inst)))
1176 else: 1179 else:
1177 req.write(tmpl("notfound", repo=virtual)) 1180 req.write(tmpl("notfound", repo=virtual))
1178 else: 1181 else:
1179 req.write(tmpl("index", entries=entries)) 1182 if req.form.has_key('static'):
1183 static = os.path.join(templatepath(), "static")
1184 fname = req.form['static'][0]
1185 req.write(staticfile(static, fname)
1186 or tmpl("error", error="%r not found" % fname))
1187 else:
1188 req.write(tmpl("index", entries=entries))