# HG changeset patch # User Gregory Szorc # Date 1520742994 28800 # Node ID 9fc3d814646e6824c017b4a83021364788b6be4c # Parent 1f42d621f090b2ad88e747557c0504212c524fda hgweb: port most @webcommand to use modern response type This only focused on porting the return value. raw file requests are wonky because they go through a separate code path at the dispatch layer. Now that everyone is using the same API, we could clean this up. It's worth noting that wsgirequest.respond() allows sending the Content-Disposition header, but the only user of that feature was removed as part of this change (with the setting of the header now being performed inline). A few @webcommand are not as straightforward as the others and they have not been ported yet. Differential Revision: https://phab.mercurial-scm.org/D2787 diff -r 1f42d621f090 -r 9fc3d814646e hgext/highlight/__init__.py --- a/hgext/highlight/__init__.py Sat Mar 10 17:02:57 2018 -0800 +++ b/hgext/highlight/__init__.py Sat Mar 10 20:36:34 2018 -0800 @@ -30,7 +30,6 @@ from . import highlight from mercurial.hgweb import ( - common, webcommands, webutil, ) @@ -84,9 +83,12 @@ def generate_css(web, req, tmpl): pg_style = web.config('web', 'pygments_style', 'colorful') fmter = highlight.HtmlFormatter(style=pg_style) - req.respond(common.HTTP_OK, 'text/css') - return ['/* pygments_style = %s */\n\n' % pg_style, - fmter.get_style_defs('')] + web.res.headers['Content-Type'] = 'text/css' + web.res.setbodybytes(''.join([ + '/* pygments_style = %s */\n\n' % pg_style, + fmter.get_style_defs(''), + ])) + return web.res def extsetup(): # monkeypatch in the new version diff -r 1f42d621f090 -r 9fc3d814646e mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py Sat Mar 10 17:02:57 2018 -0800 +++ b/mercurial/hgweb/hgweb_mod.py Sat Mar 10 20:36:34 2018 -0800 @@ -400,8 +400,11 @@ msg = 'no such method: %s' % cmd raise ErrorResponse(HTTP_BAD_REQUEST, msg) elif cmd == 'file' and req.qsparams.get('style') == 'raw': - rctx.ctype = ctype + res.status = '200 Script output follows' + res.headers['Content-Type'] = ctype content = webcommands.rawfile(rctx, wsgireq, tmpl) + assert content is res + return res.sendresponse() else: # Set some globals appropriate for web handlers. Commands can # override easily enough. diff -r 1f42d621f090 -r 9fc3d814646e mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py Sat Mar 10 17:02:57 2018 -0800 +++ b/mercurial/hgweb/webcommands.py Sat Mar 10 20:36:34 2018 -0800 @@ -106,17 +106,13 @@ path = webutil.cleanpath(web.repo, req.req.qsparams.get('file', '')) if not path: - content = manifest(web, req, tmpl) - req.respond(HTTP_OK, web.ctype) - return content + return manifest(web, req, tmpl) try: fctx = webutil.filectx(web.repo, req) except error.LookupError as inst: try: - content = manifest(web, req, tmpl) - req.respond(HTTP_OK, web.ctype) - return content + return manifest(web, req, tmpl) except ErrorResponse: raise inst @@ -133,8 +129,12 @@ if mt.startswith('text/'): mt += '; charset="%s"' % encoding.encoding - req.respond(HTTP_OK, mt, path, body=text) - return [] + web.res.headers['Content-Type'] = mt + filename = (path.rpartition('/')[-1] + .replace('\\', '\\\\').replace('"', '\\"')) + web.res.headers['Content-Disposition'] = 'inline; filename="%s"' % filename + web.res.setbodybytes(text) + return web.res def _filerevision(web, req, tmpl, fctx): f = fctx.path() @@ -153,15 +153,18 @@ "linenumber": "% 6d" % (lineno + 1), "parity": next(parity)} - return tmpl("filerevision", - file=f, - path=webutil.up(f), - text=lines(), - symrev=webutil.symrevorshortnode(req, fctx), - rename=webutil.renamelink(fctx), - permissions=fctx.manifest().flags(f), - ishead=int(ishead), - **pycompat.strkwargs(webutil.commonentry(web.repo, fctx))) + web.res.setbodygen(tmpl( + 'filerevision', + file=f, + path=webutil.up(f), + text=lines(), + symrev=webutil.symrevorshortnode(req, fctx), + rename=webutil.renamelink(fctx), + permissions=fctx.manifest().flags(f), + ishead=int(ishead), + **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))) + + return web.res @webcommand('file') def file(web, req, tmpl): @@ -335,11 +338,20 @@ tip = web.repo['tip'] parity = paritygen(web.stripecount) - return tmpl('search', query=query, node=tip.hex(), symrev='tip', - entries=changelist, archives=web.archivelist("tip"), - morevars=morevars, lessvars=lessvars, - modedesc=searchfunc[1], - showforcekw=showforcekw, showunforcekw=showunforcekw) + web.res.setbodygen(tmpl( + 'search', + query=query, + node=tip.hex(), + symrev='tip', + entries=changelist, + archives=web.archivelist('tip'), + morevars=morevars, + lessvars=lessvars, + modedesc=searchfunc[1], + showforcekw=showforcekw, + showunforcekw=showunforcekw)) + + return web.res @webcommand('changelog') def changelog(web, req, tmpl, shortlog=False): @@ -423,12 +435,23 @@ else: nextentry = [] - return tmpl('shortlog' if shortlog else 'changelog', changenav=changenav, - node=ctx.hex(), rev=pos, symrev=symrev, changesets=count, - entries=entries, - latestentry=latestentry, nextentry=nextentry, - archives=web.archivelist("tip"), revcount=revcount, - morevars=morevars, lessvars=lessvars, query=query) + web.res.setbodygen(tmpl( + 'shortlog' if shortlog else 'changelog', + changenav=changenav, + node=ctx.hex(), + rev=pos, + symrev=symrev, + changesets=count, + entries=entries, + latestentry=latestentry, + nextentry=nextentry, + archives=web.archivelist('tip'), + revcount=revcount, + morevars=morevars, + lessvars=lessvars, + query=query)) + + return web.res @webcommand('shortlog') def shortlog(web, req, tmpl): @@ -461,8 +484,9 @@ templates related to diffs may all be used to produce the output. """ ctx = webutil.changectx(web.repo, req) - - return tmpl('changeset', **webutil.changesetentry(web, req, tmpl, ctx)) + web.res.setbodygen(tmpl('changeset', + **webutil.changesetentry(web, req, tmpl, ctx))) + return web.res rev = webcommand('rev')(changeset) @@ -563,15 +587,18 @@ "emptydirs": "/".join(emptydirs), "basename": d} - return tmpl("manifest", - symrev=symrev, - path=abspath, - up=webutil.up(abspath), - upparity=next(parity), - fentries=filelist, - dentries=dirlist, - archives=web.archivelist(hex(node)), - **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) + web.res.setbodygen(tmpl( + 'manifest', + symrev=symrev, + path=abspath, + up=webutil.up(abspath), + upparity=next(parity), + fentries=filelist, + dentries=dirlist, + archives=web.archivelist(hex(node)), + **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))) + + return web.res @webcommand('tags') def tags(web, req, tmpl): @@ -600,11 +627,14 @@ "date": web.repo[n].date(), "node": hex(n)} - return tmpl("tags", - node=hex(web.repo.changelog.tip()), - entries=lambda **x: entries(False, False, **x), - entriesnotip=lambda **x: entries(True, False, **x), - latestentry=lambda **x: entries(True, True, **x)) + web.res.setbodygen(tmpl( + 'tags', + node=hex(web.repo.changelog.tip()), + entries=lambda **x: entries(False, False, **x), + entriesnotip=lambda **x: entries(True, False, **x), + latestentry=lambda **x: entries(True, True, **x))) + + return web.res @webcommand('bookmarks') def bookmarks(web, req, tmpl): @@ -638,11 +668,14 @@ else: latestrev = -1 - return tmpl("bookmarks", - node=hex(web.repo.changelog.tip()), - lastchange=[{"date": web.repo[latestrev].date()}], - entries=lambda **x: entries(latestonly=False, **x), - latestentry=lambda **x: entries(latestonly=True, **x)) + web.res.setbodygen(tmpl( + 'bookmarks', + node=hex(web.repo.changelog.tip()), + lastchange=[{'date': web.repo[latestrev].date()}], + entries=lambda **x: entries(latestonly=False, **x), + latestentry=lambda **x: entries(latestonly=True, **x))) + + return web.res @webcommand('branches') def branches(web, req, tmpl): @@ -660,8 +693,14 @@ """ entries = webutil.branchentries(web.repo, web.stripecount) latestentry = webutil.branchentries(web.repo, web.stripecount, 1) - return tmpl('branches', node=hex(web.repo.changelog.tip()), - entries=entries, latestentry=latestentry) + + web.res.setbodygen(tmpl( + 'branches', + node=hex(web.repo.changelog.tip()), + entries=entries, + latestentry=latestentry)) + + return web.res @webcommand('summary') def summary(web, req, tmpl): @@ -731,18 +770,22 @@ desc = web.config("web", "description") if not desc: desc = 'unknown' - return tmpl("summary", - desc=desc, - owner=get_contact(web.config) or "unknown", - lastchange=tip.date(), - tags=tagentries, - bookmarks=bookmarks, - branches=webutil.branchentries(web.repo, web.stripecount, 10), - shortlog=changelist, - node=tip.hex(), - symrev='tip', - archives=web.archivelist("tip"), - labels=web.configlist('web', 'labels')) + + web.res.setbodygen(tmpl( + 'summary', + desc=desc, + owner=get_contact(web.config) or 'unknown', + lastchange=tip.date(), + tags=tagentries, + bookmarks=bookmarks, + branches=webutil.branchentries(web.repo, web.stripecount, 10), + shortlog=changelist, + node=tip.hex(), + symrev='tip', + archives=web.archivelist('tip'), + labels=web.configlist('web', 'labels'))) + + return web.res @webcommand('filediff') def filediff(web, req, tmpl): @@ -782,12 +825,16 @@ else: rename = [] ctx = ctx - return tmpl("filediff", - file=path, - symrev=webutil.symrevorshortnode(req, ctx), - rename=rename, - diff=diffs, - **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) + + web.res.setbodygen(tmpl( + 'filediff', + file=path, + symrev=webutil.symrevorshortnode(req, ctx), + rename=rename, + diff=diffs, + **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))) + + return web.res diff = webcommand('diff')(filediff) @@ -853,16 +900,20 @@ else: rename = [] ctx = ctx - return tmpl('filecomparison', - file=path, - symrev=webutil.symrevorshortnode(req, ctx), - rename=rename, - leftrev=leftrev, - leftnode=hex(leftnode), - rightrev=rightrev, - rightnode=hex(rightnode), - comparison=comparison, - **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) + + web.res.setbodygen(tmpl( + 'filecomparison', + file=path, + symrev=webutil.symrevorshortnode(req, ctx), + rename=rename, + leftrev=leftrev, + leftnode=hex(leftnode), + rightrev=rightrev, + rightnode=hex(rightnode), + comparison=comparison, + **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))) + + return web.res @webcommand('annotate') def annotate(web, req, tmpl): @@ -944,16 +995,19 @@ diffopts = webutil.difffeatureopts(req, web.repo.ui, 'annotate') diffopts = {k: getattr(diffopts, k) for k in diffopts.defaults} - return tmpl("fileannotate", - file=f, - annotate=annotate, - path=webutil.up(f), - symrev=webutil.symrevorshortnode(req, fctx), - rename=webutil.renamelink(fctx), - permissions=fctx.manifest().flags(f), - ishead=int(ishead), - diffopts=diffopts, - **pycompat.strkwargs(webutil.commonentry(web.repo, fctx))) + web.res.setbodygen(tmpl( + 'fileannotate', + file=f, + annotate=annotate, + path=webutil.up(f), + symrev=webutil.symrevorshortnode(req, fctx), + rename=webutil.renamelink(fctx), + permissions=fctx.manifest().flags(f), + ishead=int(ishead), + diffopts=diffopts, + **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))) + + return web.res @webcommand('filelog') def filelog(web, req, tmpl): @@ -1318,17 +1372,26 @@ rows = len(tree) - return tmpl('graph', rev=rev, symrev=symrev, revcount=revcount, - uprev=uprev, - lessvars=lessvars, morevars=morevars, downrev=downrev, - graphvars=graphvars, - rows=rows, - bg_height=bg_height, - changesets=count, - nextentry=nextentry, - jsdata=lambda **x: jsdata(), - nodes=lambda **x: nodes(), - node=ctx.hex(), changenav=changenav) + web.res.setbodygen(tmpl( + 'graph', + rev=rev, + symrev=symrev, + revcount=revcount, + uprev=uprev, + lessvars=lessvars, + morevars=morevars, + downrev=downrev, + graphvars=graphvars, + rows=rows, + bg_height=bg_height, + changesets=count, + nextentry=nextentry, + jsdata=lambda **x: jsdata(), + nodes=lambda **x: nodes(), + node=ctx.hex(), + changenav=changenav)) + + return web.res def _getdoc(e): doc = e[0].__doc__ @@ -1384,8 +1447,13 @@ for c, doc in other: yield {'topic': c, 'summary': doc} - return tmpl('helptopics', topics=topics, earlycommands=earlycommands, - othercommands=othercommands, title='Index') + web.res.setbodygen(tmpl( + 'helptopics', + topics=topics, + earlycommands=earlycommands, + othercommands=othercommands, + title='Index')) + return web.res # Render an index of sub-topics. if topicname in helpmod.subtopics: @@ -1397,8 +1465,12 @@ 'summary': summary, }) - return tmpl('helptopics', topics=topics, title=topicname, - subindex=True) + web.res.setbodygen(tmpl( + 'helptopics', + topics=topics, + title=topicname, + subindex=True)) + return web.res u = webutil.wsgiui.load() u.verbose = True @@ -1418,7 +1490,13 @@ doc = helpmod.help_(u, commands, topic, subtopic=subtopic) except error.Abort: raise ErrorResponse(HTTP_NOT_FOUND) - return tmpl('help', topic=topicname, doc=doc) + + web.res.setbodygen(tmpl( + 'help', + topic=topicname, + doc=doc)) + + return web.res # tell hggettext to extract docstrings from these functions: i18nfunctions = commands.values()