mercurial/hgweb.py
changeset 1780 8a1f2eae2832
parent 1769 982fb022a16a
parent 1779 a1e6e02e9d05
child 1792 a161c61ba8ed
equal deleted inserted replaced
1775:0762feff3043 1780:8a1f2eae2832
     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 *
   843                 'fa': [('cmd', ['annotate']), ('filenode', None)],
   844                 'fa': [('cmd', ['annotate']), ('filenode', None)],
   844                 'mf': [('cmd', ['manifest']), ('manifest', None)],
   845                 'mf': [('cmd', ['manifest']), ('manifest', None)],
   845                 'ca': [('cmd', ['archive']), ('node', None)],
   846                 'ca': [('cmd', ['archive']), ('node', None)],
   846                 'tags': [('cmd', ['tags'])],
   847                 'tags': [('cmd', ['tags'])],
   847                 'tip': [('cmd', ['changeset']), ('node', ['tip'])],
   848                 'tip': [('cmd', ['changeset']), ('node', ['tip'])],
       
   849                 'static': [('cmd', ['static']), ('file', None)]
   848             }
   850             }
   849 
   851 
   850             for k in shortcuts.iterkeys():
   852             for k in shortcuts.iterkeys():
   851                 if form.has_key(k):
   853                 if form.has_key(k):
   852                     for name, value in shortcuts[k]:
   854                     for name, value in shortcuts[k]:
   858         self.refresh()
   860         self.refresh()
   859 
   861 
   860         expand_form(req.form)
   862         expand_form(req.form)
   861 
   863 
   862         t = self.repo.ui.config("web", "templates", templatepath())
   864         t = self.repo.ui.config("web", "templates", templatepath())
       
   865         static = self.repo.ui.config("web", "static", os.path.join(t,"static"))
   863         m = os.path.join(t, "map")
   866         m = os.path.join(t, "map")
   864         style = self.repo.ui.config("web", "style", "")
   867         style = self.repo.ui.config("web", "style", "")
   865         if req.form.has_key('style'):
   868         if req.form.has_key('style'):
   866             style = req.form['style'][0]
   869             style = req.form['style'][0]
   867         if style:
   870         if style:
   980                 self.repo.ui.configbool("web", "allow" + type, False)):
   983                 self.repo.ui.configbool("web", "allow" + type, False)):
   981                 self.archive(req, changeset, type)
   984                 self.archive(req, changeset, type)
   982                 return
   985                 return
   983 
   986 
   984             req.write(self.t("error"))
   987             req.write(self.t("error"))
       
   988 
       
   989         elif req.form['cmd'][0] == 'static':
       
   990             fname = req.form['file'][0]
       
   991 
       
   992             fname = os.path.realpath(os.path.join(static, 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]
       
  1010 		if ct == None:
       
  1011 			ct = "text/plain"
       
  1012 
       
  1013                 req.write("Content-type: " + ct + "\n\n" + file(fname).read())
       
  1014             except ValueError:
       
  1015                 # security breach attempt
       
  1016                 req.write(self.t("error"))
       
  1017             except OSError, e:
       
  1018                 if e.errno == errno.ENOENT:
       
  1019                     req.write(self.t("error"))
   985 
  1020 
   986         else:
  1021         else:
   987             req.write(self.t("error"))
  1022             req.write(self.t("error"))
   988 
  1023 
   989 def create_server(repo):
  1024 def create_server(repo):