mercurial/hgweb/hgweb_mod.py
changeset 5561 22713dce19f6
parent 5486 48c22c719f8c
child 5563 d61fea133f2d
equal deleted inserted replaced
5560:e78c24011001 5561:22713dce19f6
     4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
     4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
     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, mimetypes, re, zlib, mimetools, cStringIO, sys
     9 import errno, os, mimetypes, re, zlib, mimetools, cStringIO, sys
    10 import tempfile, urllib, bz2
    10 import tempfile, urllib, bz2
    11 from mercurial.node import *
    11 from mercurial.node import *
    12 from mercurial.i18n import gettext as _
    12 from mercurial.i18n import gettext as _
    13 from mercurial import mdiff, ui, hg, util, archival, streamclone, patch
    13 from mercurial import mdiff, ui, hg, util, archival, streamclone, patch
    14 from mercurial import revlog, templater
    14 from mercurial import revlog, templater
    15 from common import get_mtime, staticfile, style_map, paritygen
    15 from common import ErrorResponse, get_mtime, staticfile, style_map, paritygen
    16 
    16 
    17 def _up(p):
    17 def _up(p):
    18     if p[0] != "/":
    18     if p[0] != "/":
    19         p = "/" + p
    19         p = "/" + p
    20     if p[-1] == "/":
    20     if p[-1] == "/":
   476                 files[short] = (f, None)
   476                 files[short] = (f, None)
   477             else:
   477             else:
   478                 short = os.path.basename(remain)
   478                 short = os.path.basename(remain)
   479                 files[short] = (f, n)
   479                 files[short] = (f, n)
   480 
   480 
       
   481         if not files:
       
   482             raise ErrorResponse(404, 'Path not found: ' + path)
       
   483 
   481         def filelist(**map):
   484         def filelist(**map):
   482             fl = files.keys()
   485             fl = files.keys()
   483             fl.sort()
   486             fl.sort()
   484             for f in fl:
   487             for f in fl:
   485                 full, fnode = files[f]
   488                 full, fnode = files[f]
   843             if not req.form.has_key('cmd'):
   846             if not req.form.has_key('cmd'):
   844                 req.form['cmd'] = [self.t.cache['default']]
   847                 req.form['cmd'] = [self.t.cache['default']]
   845 
   848 
   846             cmd = req.form['cmd'][0]
   849             cmd = req.form['cmd'][0]
   847 
   850 
   848             method = getattr(self, 'do_' + cmd, None)
   851             try:
   849             if method:
   852                 method = getattr(self, 'do_' + cmd)
   850                 try:
   853                 method(req)
   851                     method(req)
   854             except revlog.LookupError, err:
   852                 except (hg.RepoError, revlog.RevlogError), inst:
   855                 req.respond(404, self.t(
   853                     req.write(self.t("error", error=str(inst)))
   856                     'error', error='revision not found: %s' % err.name))
   854             else:
   857             except (hg.RepoError, revlog.RevlogError), inst:
   855                 req.write(self.t("error", error='No such method: ' + cmd))
   858                 req.respond('500 Internal Server Error',
       
   859                             self.t('error', error=str(inst)))
       
   860             except ErrorResponse, inst:
       
   861                 req.respond(inst.code, self.t('error', error=inst.message))
       
   862             except AttributeError:
       
   863                 req.respond(400,
       
   864                             self.t('error', error='No such method: ' + cmd))
   856         finally:
   865         finally:
   857             self.t = None
   866             self.t = None
   858 
   867 
   859     def changectx(self, req):
   868     def changectx(self, req):
   860         if req.form.has_key('node'):
   869         if req.form.has_key('node'):
  1036         if (type_ in self.archives and (type_ in allowed or
  1045         if (type_ in self.archives and (type_ in allowed or
  1037             self.configbool("web", "allow" + type_, False))):
  1046             self.configbool("web", "allow" + type_, False))):
  1038             self.archive(req, req.form['node'][0], type_)
  1047             self.archive(req, req.form['node'][0], type_)
  1039             return
  1048             return
  1040 
  1049 
  1041         req.write(self.t("error"))
  1050         req.respond(400, self.t('error',
       
  1051                                 error='Unsupported archive type: %s' % type_))
  1042 
  1052 
  1043     def do_static(self, req):
  1053     def do_static(self, req):
  1044         fname = req.form['file'][0]
  1054         fname = req.form['file'][0]
  1045         # a repo owner may set web.static in .hg/hgrc to get any file
  1055         # a repo owner may set web.static in .hg/hgrc to get any file
  1046         # readable by the user running the CGI script
  1056         # readable by the user running the CGI script
  1047         static = self.config("web", "static",
  1057         static = self.config("web", "static",
  1048                              os.path.join(self.templatepath, "static"),
  1058                              os.path.join(self.templatepath, "static"),
  1049                              untrusted=False)
  1059                              untrusted=False)
  1050         req.write(staticfile(static, fname, req)
  1060         req.write(staticfile(static, fname, req))
  1051                   or self.t("error", error="%r not found" % fname))
       
  1052 
  1061 
  1053     def do_capabilities(self, req):
  1062     def do_capabilities(self, req):
  1054         caps = ['lookup', 'changegroupsubset']
  1063         caps = ['lookup', 'changegroupsubset']
  1055         if self.configbool('server', 'uncompressed'):
  1064         if self.configbool('server', 'uncompressed'):
  1056             caps.append('stream=%d' % self.repo.changelog.version)
  1065             caps.append('stream=%d' % self.repo.changelog.version)
  1196                 if filename.startswith(self.repo.root):
  1205                 if filename.startswith(self.repo.root):
  1197                     filename = filename[len(self.repo.root)+1:]
  1206                     filename = filename[len(self.repo.root)+1:]
  1198                 else:
  1207                 else:
  1199                     filename = ''
  1208                     filename = ''
  1200                 error = getattr(inst, 'strerror', 'Unknown error')
  1209                 error = getattr(inst, 'strerror', 'Unknown error')
  1201                 req.write('%s: %s\n' % (error, filename))
  1210                 if inst.errno == errno.ENOENT:
       
  1211                     code = 404
       
  1212                 else:
       
  1213                     code = 500
       
  1214                 req.respond(code, '%s: %s\n' % (error, filename))
  1202         finally:
  1215         finally:
  1203             fp.close()
  1216             fp.close()
  1204             os.unlink(tempname)
  1217             os.unlink(tempname)
  1205 
  1218 
  1206     def do_stream_out(self, req):
  1219     def do_stream_out(self, req):