Show More
@@ -10,7 +10,9 b' import errno, mimetypes, os' | |||
|
10 | 10 | |
|
11 | 11 | HTTP_OK = 200 |
|
12 | 12 | HTTP_BAD_REQUEST = 400 |
|
13 | HTTP_UNAUTHORIZED = 401 | |
|
13 | 14 | HTTP_NOT_FOUND = 404 |
|
15 | HTTP_METHOD_NOT_ALLOWED = 405 | |
|
14 | 16 | HTTP_SERVER_ERROR = 500 |
|
15 | 17 | |
|
16 | 18 | class ErrorResponse(Exception): |
@@ -13,6 +13,7 b' from mercurial import mdiff, ui, hg, uti' | |||
|
13 | 13 | from mercurial import revlog, templater, templatefilters |
|
14 | 14 | from common import get_mtime, style_map, paritygen, countgen, ErrorResponse |
|
15 | 15 | from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR |
|
16 | from common import HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED | |
|
16 | 17 | from request import wsgirequest |
|
17 | 18 | import webcommands, protocol, webutil |
|
18 | 19 | |
@@ -88,10 +89,16 b' class hgweb(object):' | |||
|
88 | 89 | |
|
89 | 90 | cmd = req.form.get('cmd', [''])[0] |
|
90 | 91 | if cmd and cmd in protocol.__all__: |
|
91 | if cmd in perms and not self.check_perm(req, perms[cmd]): | |
|
92 |
|
|
|
93 | method = getattr(protocol, cmd) | |
|
94 | return method(self.repo, req) | |
|
92 | try: | |
|
93 | if cmd in perms: | |
|
94 | self.check_perm(req, perms[cmd]) | |
|
95 | method = getattr(protocol, cmd) | |
|
96 | return method(self.repo, req) | |
|
97 | except ErrorResponse, inst: | |
|
98 | req.respond(inst.code, protocol.HGTYPE) | |
|
99 | if not inst.message: | |
|
100 | return [] | |
|
101 | return '0\n%s\n' % inst.message, | |
|
95 | 102 | |
|
96 | 103 | # work with CGI variables to create coherent structure |
|
97 | 104 | # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME |
@@ -344,35 +351,29 b' class hgweb(object):' | |||
|
344 | 351 | '''Check permission for operation based on request data (including |
|
345 | 352 | authentication info. Return true if op allowed, else false.''' |
|
346 | 353 | |
|
347 | def error(status, message): | |
|
348 | req.respond(status, protocol.HGTYPE) | |
|
349 | req.write('0\n%s\n' % message) | |
|
350 | ||
|
351 | if op == 'pull': | |
|
352 | return self.allowpull | |
|
354 | if op == 'pull' and not self.allowpull: | |
|
355 | raise ErrorResponse(HTTP_OK, '') | |
|
356 | elif op == 'pull': | |
|
357 | return | |
|
353 | 358 | |
|
354 | 359 | # enforce that you can only push using POST requests |
|
355 | 360 | if req.env['REQUEST_METHOD'] != 'POST': |
|
356 |
|
|
|
357 | return False | |
|
361 | msg = 'push requires POST request' | |
|
362 | raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg) | |
|
358 | 363 | |
|
359 | 364 | # require ssl by default for pushing, auth info cannot be sniffed |
|
360 | 365 | # and replayed |
|
361 | 366 | scheme = req.env.get('wsgi.url_scheme') |
|
362 | 367 | if self.configbool('web', 'push_ssl', True) and scheme != 'https': |
|
363 | error(HTTP_OK, 'ssl required') | |
|
364 | return False | |
|
368 | raise ErrorResponse(HTTP_OK, 'ssl required') | |
|
365 | 369 | |
|
366 | 370 | user = req.env.get('REMOTE_USER') |
|
367 | 371 | |
|
368 | 372 | deny = self.configlist('web', 'deny_push') |
|
369 | 373 | if deny and (not user or deny == ['*'] or user in deny): |
|
370 |
error( |
|
|
371 | return False | |
|
374 | raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') | |
|
372 | 375 | |
|
373 | 376 | allow = self.configlist('web', 'allow_push') |
|
374 | 377 | result = allow and (allow == ['*'] or user in allow) |
|
375 | 378 | if not result: |
|
376 |
error( |
|
|
377 | ||
|
378 | return result | |
|
379 | raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') |
@@ -108,7 +108,6 b' def capabilities(repo, req):' | |||
|
108 | 108 | |
|
109 | 109 | def unbundle(repo, req): |
|
110 | 110 | |
|
111 | errorfmt = '0\n%s\n' | |
|
112 | 111 | proto = req.env.get('wsgi.url_scheme') or 'http' |
|
113 | 112 | their_heads = req.form['heads'][0].split(' ') |
|
114 | 113 | |
@@ -123,10 +122,7 b' def unbundle(repo, req):' | |||
|
123 | 122 | # drain incoming bundle, else client will not see |
|
124 | 123 | # response when run outside cgi script |
|
125 | 124 | pass |
|
126 | req.respond(HTTP_OK, HGTYPE) | |
|
127 | return errorfmt % 'unsynced changes', | |
|
128 | ||
|
129 | req.respond(HTTP_OK, HGTYPE) | |
|
125 | raise ErrorResponse(HTTP_OK, 'unsynced changes') | |
|
130 | 126 | |
|
131 | 127 | # do not lock repo until all changegroup data is |
|
132 | 128 | # streamed. save to temporary file. |
@@ -142,7 +138,7 b' def unbundle(repo, req):' | |||
|
142 | 138 | lock = repo.lock() |
|
143 | 139 | try: |
|
144 | 140 | if not check_heads(): |
|
145 |
re |
|
|
141 | raise ErrorResponse(HTTP_OK, 'unsynced changes') | |
|
146 | 142 | |
|
147 | 143 | fp.seek(0) |
|
148 | 144 | header = fp.read(6) |
@@ -168,11 +164,12 b' def unbundle(repo, req):' | |||
|
168 | 164 | finally: |
|
169 | 165 | val = sys.stdout.getvalue() |
|
170 | 166 | sys.stdout, sys.stderr = oldio |
|
167 | req.respond(HTTP_OK, HGTYPE) | |
|
171 | 168 | return '%d\n%s' % (ret, val), |
|
172 | 169 | finally: |
|
173 | 170 | del lock |
|
174 | 171 | except ValueError, inst: |
|
175 | return errorfmt % inst, | |
|
172 | raise ErrorResponse(HTTP_OK, inst) | |
|
176 | 173 | except (OSError, IOError), inst: |
|
177 | 174 | filename = getattr(inst, 'filename', '') |
|
178 | 175 | # Don't send our filesystem layout to the client |
@@ -185,8 +182,7 b' def unbundle(repo, req):' | |||
|
185 | 182 | code = HTTP_NOT_FOUND |
|
186 | 183 | else: |
|
187 | 184 | code = HTTP_SERVER_ERROR |
|
188 | req.respond(code) | |
|
189 | return '0\n%s: %s\n' % (error, filename), | |
|
185 | raise ErrorResponse(code, '%s: %s' % (error, filename)) | |
|
190 | 186 | finally: |
|
191 | 187 | fp.close() |
|
192 | 188 | os.unlink(tempname) |
General Comments 0
You need to be logged in to leave comments.
Login now