--- a/mercurial/hgweb/common.py Fri Aug 15 13:25:57 2008 +0200
+++ b/mercurial/hgweb/common.py Tue Jul 22 18:23:20 2008 +0200
@@ -10,7 +10,9 @@
HTTP_OK = 200
HTTP_BAD_REQUEST = 400
+HTTP_UNAUTHORIZED = 401
HTTP_NOT_FOUND = 404
+HTTP_METHOD_NOT_ALLOWED = 405
HTTP_SERVER_ERROR = 500
class ErrorResponse(Exception):
--- a/mercurial/hgweb/hgweb_mod.py Fri Aug 15 13:25:57 2008 +0200
+++ b/mercurial/hgweb/hgweb_mod.py Tue Jul 22 18:23:20 2008 +0200
@@ -13,6 +13,7 @@
from mercurial import revlog, templater, templatefilters
from common import get_mtime, style_map, paritygen, countgen, ErrorResponse
from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
+from common import HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED
from request import wsgirequest
import webcommands, protocol, webutil
@@ -88,10 +89,16 @@
cmd = req.form.get('cmd', [''])[0]
if cmd and cmd in protocol.__all__:
- if cmd in perms and not self.check_perm(req, perms[cmd]):
- return []
- method = getattr(protocol, cmd)
- return method(self.repo, req)
+ try:
+ if cmd in perms:
+ self.check_perm(req, perms[cmd])
+ method = getattr(protocol, cmd)
+ return method(self.repo, req)
+ except ErrorResponse, inst:
+ req.respond(inst.code, protocol.HGTYPE)
+ if not inst.message:
+ return []
+ return '0\n%s\n' % inst.message,
# work with CGI variables to create coherent structure
# use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
@@ -344,35 +351,29 @@
'''Check permission for operation based on request data (including
authentication info. Return true if op allowed, else false.'''
- def error(status, message):
- req.respond(status, protocol.HGTYPE)
- req.write('0\n%s\n' % message)
-
- if op == 'pull':
- return self.allowpull
+ if op == 'pull' and not self.allowpull:
+ raise ErrorResponse(HTTP_OK, '')
+ elif op == 'pull':
+ return
# enforce that you can only push using POST requests
if req.env['REQUEST_METHOD'] != 'POST':
- error('405 Method Not Allowed', 'push requires POST request')
- return False
+ msg = 'push requires POST request'
+ raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg)
# require ssl by default for pushing, auth info cannot be sniffed
# and replayed
scheme = req.env.get('wsgi.url_scheme')
if self.configbool('web', 'push_ssl', True) and scheme != 'https':
- error(HTTP_OK, 'ssl required')
- return False
+ raise ErrorResponse(HTTP_OK, 'ssl required')
user = req.env.get('REMOTE_USER')
deny = self.configlist('web', 'deny_push')
if deny and (not user or deny == ['*'] or user in deny):
- error('401 Unauthorized', 'push not authorized')
- return False
+ raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')
allow = self.configlist('web', 'allow_push')
result = allow and (allow == ['*'] or user in allow)
if not result:
- error('401 Unauthorized', 'push not authorized')
-
- return result
+ raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')
--- a/mercurial/hgweb/protocol.py Fri Aug 15 13:25:57 2008 +0200
+++ b/mercurial/hgweb/protocol.py Tue Jul 22 18:23:20 2008 +0200
@@ -108,7 +108,6 @@
def unbundle(repo, req):
- errorfmt = '0\n%s\n'
proto = req.env.get('wsgi.url_scheme') or 'http'
their_heads = req.form['heads'][0].split(' ')
@@ -123,10 +122,7 @@
# drain incoming bundle, else client will not see
# response when run outside cgi script
pass
- req.respond(HTTP_OK, HGTYPE)
- return errorfmt % 'unsynced changes',
-
- req.respond(HTTP_OK, HGTYPE)
+ raise ErrorResponse(HTTP_OK, 'unsynced changes')
# do not lock repo until all changegroup data is
# streamed. save to temporary file.
@@ -142,7 +138,7 @@
lock = repo.lock()
try:
if not check_heads():
- return errorfmt % 'unsynced changes',
+ raise ErrorResponse(HTTP_OK, 'unsynced changes')
fp.seek(0)
header = fp.read(6)
@@ -168,11 +164,12 @@
finally:
val = sys.stdout.getvalue()
sys.stdout, sys.stderr = oldio
+ req.respond(HTTP_OK, HGTYPE)
return '%d\n%s' % (ret, val),
finally:
del lock
except ValueError, inst:
- return errorfmt % inst,
+ raise ErrorResponse(HTTP_OK, inst)
except (OSError, IOError), inst:
filename = getattr(inst, 'filename', '')
# Don't send our filesystem layout to the client
@@ -185,8 +182,7 @@
code = HTTP_NOT_FOUND
else:
code = HTTP_SERVER_ERROR
- req.respond(code)
- return '0\n%s: %s\n' % (error, filename),
+ raise ErrorResponse(code, '%s: %s' % (error, filename))
finally:
fp.close()
os.unlink(tempname)