Show More
@@ -61,6 +61,25 b" def makebreadcrumb(url, prefix=''):" | |||
|
61 | 61 | return reversed(breadcrumb) |
|
62 | 62 | |
|
63 | 63 | |
|
64 | class requestcontext(object): | |
|
65 | """Holds state/context for an individual request. | |
|
66 | ||
|
67 | Servers can be multi-threaded. Holding state on the WSGI application | |
|
68 | is prone to race conditions. Instances of this class exist to hold | |
|
69 | mutable and race-free state for requests. | |
|
70 | """ | |
|
71 | def __init__(self, app): | |
|
72 | object.__setattr__(self, 'app', app) | |
|
73 | object.__setattr__(self, 'repo', app.repo) | |
|
74 | ||
|
75 | # Proxy unknown reads and writes to the application instance | |
|
76 | # until everything is moved to us. | |
|
77 | def __getattr__(self, name): | |
|
78 | return getattr(self.app, name) | |
|
79 | ||
|
80 | def __setattr__(self, name, value): | |
|
81 | return setattr(self.app, name, value) | |
|
82 | ||
|
64 | 83 | class hgweb(object): |
|
65 | 84 | """HTTP server for individual repositories. |
|
66 | 85 | |
@@ -193,6 +212,7 b' class hgweb(object):' | |||
|
193 | 212 | should be using instances of this class as the WSGI application. |
|
194 | 213 | """ |
|
195 | 214 | self.refresh(req) |
|
215 | rctx = requestcontext(self) | |
|
196 | 216 | |
|
197 | 217 | # work with CGI variables to create coherent structure |
|
198 | 218 | # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME |
@@ -223,7 +243,7 b' class hgweb(object):' | |||
|
223 | 243 | if query: |
|
224 | 244 | raise ErrorResponse(HTTP_NOT_FOUND) |
|
225 | 245 | if cmd in perms: |
|
226 | self.check_perm(req, perms[cmd]) | |
|
246 | self.check_perm(rctx, req, perms[cmd]) | |
|
227 | 247 | return protocol.call(self.repo, req, cmd) |
|
228 | 248 | except ErrorResponse as inst: |
|
229 | 249 | # A client that sends unbundle without 100-continue will |
@@ -284,7 +304,7 b' class hgweb(object):' | |||
|
284 | 304 | |
|
285 | 305 | # check read permissions non-static content |
|
286 | 306 | if cmd != 'static': |
|
287 | self.check_perm(req, None) | |
|
307 | self.check_perm(rctx, req, None) | |
|
288 | 308 | |
|
289 | 309 | if cmd == '': |
|
290 | 310 | req.form['cmd'] = [tmpl.cache['default']] |
@@ -297,9 +317,9 b' class hgweb(object):' | |||
|
297 | 317 | raise ErrorResponse(HTTP_BAD_REQUEST, msg) |
|
298 | 318 | elif cmd == 'file' and 'raw' in req.form.get('style', []): |
|
299 | 319 | self.ctype = ctype |
|
300 |
content = webcommands.rawfile( |
|
|
320 | content = webcommands.rawfile(rctx, req, tmpl) | |
|
301 | 321 | else: |
|
302 |
content = getattr(webcommands, cmd)( |
|
|
322 | content = getattr(webcommands, cmd)(rctx, req, tmpl) | |
|
303 | 323 | req.respond(HTTP_OK, ctype) |
|
304 | 324 | |
|
305 | 325 | return content |
@@ -442,6 +462,6 b' class hgweb(object):' | |||
|
442 | 462 | 'zip': ('application/zip', 'zip', '.zip', None), |
|
443 | 463 | } |
|
444 | 464 | |
|
445 | def check_perm(self, req, op): | |
|
465 | def check_perm(self, rctx, req, op): | |
|
446 | 466 | for permhook in permhooks: |
|
447 |
permhook( |
|
|
467 | permhook(rctx, req, op) |
General Comments 0
You need to be logged in to leave comments.
Login now