Mercurial > public > mercurial-scm > hg
diff mercurial/hgweb/hgweb_mod.py @ 6926:57b954d8d003
hgweb: raise ErrorResponses to communicate protocol errors
author | Dirkjan Ochtman <dirkjan@ochtman.nl> |
---|---|
date | Tue, 22 Jul 2008 18:23:20 +0200 |
parents | 95f35b553ae6 |
children | 2cfdabe235fb |
line wrap: on
line diff
--- 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')