Mercurial > public > mercurial-scm > hg-stable
diff mercurial/hgweb/hgweb_mod.py @ 36876:1f42d621f090
hgweb: support using new response object for web commands
We have a "requestcontext" type for holding state for the current
request. Why we pass in the wsgirequest and templater instance
to @webcommand functions, I don't know.
I like the idea of standardizing on using "requestcontext" for passing
all state to @webcommand functions because that scales well without
API changes every time you want to pass a new piece of data. So,
we add our new request and response instances to "requestcontext" so
@webcommand functions can access them.
We also teach our command dispatcher to recognize a new calling
convention. Instead of returning content from the @webcommand
function, we return our response object. This signals that this
response object is to be used for sending output. The keyword
extension was wrapping various @webcommand and assuming the output
was iterable, so we had to teach it about the new calling convention.
To prove everything works, we convert the "filelog" @webcommand
to use the new convention.
The new calling convention is a bit wonky. I intend to improve this
once all commands are ported to use the new response object.
Differential Revision: https://phab.mercurial-scm.org/D2786
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sat, 10 Mar 2018 17:02:57 -0800 |
parents | 7ad6a275316f |
children | 9fc3d814646e |
line wrap: on
line diff
--- a/mercurial/hgweb/hgweb_mod.py Sat Mar 10 14:19:27 2018 -0800 +++ b/mercurial/hgweb/hgweb_mod.py Sat Mar 10 17:02:57 2018 -0800 @@ -91,9 +91,11 @@ is prone to race conditions. Instances of this class exist to hold mutable and race-free state for requests. """ - def __init__(self, app, repo): + def __init__(self, app, repo, req, res): self.repo = repo self.reponame = app.reponame + self.req = req + self.res = res self.archivespecs = archivespecs @@ -305,7 +307,7 @@ def _runwsgi(self, wsgireq, repo): req = wsgireq.req res = wsgireq.res - rctx = requestcontext(self, repo) + rctx = requestcontext(self, repo, req, res) # This state is global across all threads. encoding.encoding = rctx.config('web', 'encoding') @@ -401,7 +403,15 @@ rctx.ctype = ctype content = webcommands.rawfile(rctx, wsgireq, tmpl) else: + # Set some globals appropriate for web handlers. Commands can + # override easily enough. + res.status = '200 Script output follows' + res.headers['Content-Type'] = ctype content = getattr(webcommands, cmd)(rctx, wsgireq, tmpl) + + if content is res: + return res.sendresponse() + wsgireq.respond(HTTP_OK, ctype) return content