hgweb: remove wsgirequest (API)
Good riddance.
.. api::
The old ``wsgirequest`` class for handling everything WSGI in hgweb
has been replaced by separate request and response types. Various
high-level functions in the hgweb WSGI applications now receive
these new types as arguments instead of the old ``wsgirequest``
type.
Differential Revision: https://phab.mercurial-scm.org/D2832
--- a/mercurial/hgweb/hgweb_mod.py Sat Mar 10 15:24:24 2018 +0530
+++ b/mercurial/hgweb/hgweb_mod.py Sun Mar 11 16:29:54 2018 -0700
@@ -290,10 +290,12 @@
This may be called by multiple threads.
"""
- req = requestmod.wsgirequest(env, respond)
- return self.run_wsgi(req)
+ req = requestmod.parserequestfromenv(env)
+ res = requestmod.wsgiresponse(req, respond)
- def run_wsgi(self, wsgireq):
+ return self.run_wsgi(req, res)
+
+ def run_wsgi(self, req, res):
"""Internal method to run the WSGI application.
This is typically only called by Mercurial. External consumers
@@ -302,12 +304,10 @@
with self._obtainrepo() as repo:
profile = repo.ui.configbool('profiling', 'enabled')
with profiling.profile(repo.ui, enabled=profile):
- for r in self._runwsgi(wsgireq, repo):
+ for r in self._runwsgi(req, res, repo):
yield r
- def _runwsgi(self, wsgireq, repo):
- req = wsgireq.req
- res = wsgireq.res
+ def _runwsgi(self, req, res, repo):
rctx = requestcontext(self, repo, req, res)
# This state is global across all threads.
--- a/mercurial/hgweb/hgwebdir_mod.py Sat Mar 10 15:24:24 2018 +0530
+++ b/mercurial/hgweb/hgwebdir_mod.py Sun Mar 11 16:29:54 2018 -0700
@@ -348,19 +348,18 @@
def __call__(self, env, respond):
baseurl = self.ui.config('web', 'baseurl')
- wsgireq = requestmod.wsgirequest(env, respond, altbaseurl=baseurl)
- return self.run_wsgi(wsgireq)
+ req = requestmod.parserequestfromenv(env, altbaseurl=baseurl)
+ res = requestmod.wsgiresponse(req, respond)
- def run_wsgi(self, wsgireq):
+ return self.run_wsgi(req, res)
+
+ def run_wsgi(self, req, res):
profile = self.ui.configbool('profiling', 'enabled')
with profiling.profile(self.ui, enabled=profile):
- for r in self._runwsgi(wsgireq):
+ for r in self._runwsgi(req, res):
yield r
- def _runwsgi(self, wsgireq):
- req = wsgireq.req
- res = wsgireq.res
-
+ def _runwsgi(self, req, res):
try:
self.refresh()
@@ -423,13 +422,13 @@
if real:
# Re-parse the WSGI environment to take into account our
# repository path component.
- wsgireq.req = requestmod.parserequestfromenv(
- wsgireq.env, wsgireq.req.bodyfh, reponame=virtualrepo,
+ req = requestmod.parserequestfromenv(
+ req.rawenv, reponame=virtualrepo,
altbaseurl=self.ui.config('web', 'baseurl'))
try:
# ensure caller gets private copy of ui
repo = hg.repository(self.ui.copy(), real)
- return hgweb_mod.hgweb(repo).run_wsgi(wsgireq)
+ return hgweb_mod.hgweb(repo).run_wsgi(req, res)
except IOError as inst:
msg = encoding.strtolocal(inst.strerror)
raise ErrorResponse(HTTP_SERVER_ERROR, msg)
--- a/mercurial/hgweb/request.py Sat Mar 10 15:24:24 2018 +0530
+++ b/mercurial/hgweb/request.py Sun Mar 11 16:29:54 2018 -0700
@@ -152,7 +152,7 @@
# WSGI environment dict, unmodified.
rawenv = attr.ib()
-def parserequestfromenv(env, bodyfh, reponame=None, altbaseurl=None):
+def parserequestfromenv(env, reponame=None, altbaseurl=None):
"""Parse URL components from environment variables.
WSGI defines request attributes via environment variables. This function
@@ -325,11 +325,9 @@
if 'CONTENT_LENGTH' in env and 'HTTP_CONTENT_LENGTH' not in env:
headers['Content-Length'] = env['CONTENT_LENGTH']
- # TODO do this once we remove wsgirequest.inp, otherwise we could have
- # multiple readers from the underlying input stream.
- #bodyfh = env['wsgi.input']
- #if 'Content-Length' in headers:
- # bodyfh = util.cappedreader(bodyfh, int(headers['Content-Length']))
+ bodyfh = env['wsgi.input']
+ if 'Content-Length' in headers:
+ bodyfh = util.cappedreader(bodyfh, int(headers['Content-Length']))
return parsedrequest(method=env['REQUEST_METHOD'],
url=fullurl, baseurl=baseurl,
@@ -578,34 +576,6 @@
assert self._bodywritefn
return offsettrackingwriter(self._bodywritefn)
-class wsgirequest(object):
- """Higher-level API for a WSGI request.
-
- WSGI applications are invoked with 2 arguments. They are used to
- instantiate instances of this class, which provides higher-level APIs
- for obtaining request parameters, writing HTTP output, etc.
- """
- def __init__(self, wsgienv, start_response, altbaseurl=None):
- version = wsgienv[r'wsgi.version']
- if (version < (1, 0)) or (version >= (2, 0)):
- raise RuntimeError("Unknown and unsupported WSGI version %d.%d"
- % version)
-
- inp = wsgienv[r'wsgi.input']
-
- if r'HTTP_CONTENT_LENGTH' in wsgienv:
- inp = util.cappedreader(inp, int(wsgienv[r'HTTP_CONTENT_LENGTH']))
- elif r'CONTENT_LENGTH' in wsgienv:
- inp = util.cappedreader(inp, int(wsgienv[r'CONTENT_LENGTH']))
-
- self.err = wsgienv[r'wsgi.errors']
- self.threaded = wsgienv[r'wsgi.multithread']
- self.multiprocess = wsgienv[r'wsgi.multiprocess']
- self.run_once = wsgienv[r'wsgi.run_once']
- self.env = wsgienv
- self.req = parserequestfromenv(wsgienv, inp, altbaseurl=altbaseurl)
- self.res = wsgiresponse(self.req, start_response)
-
def wsgiapplication(app_maker):
'''For compatibility with old CGI scripts. A plain hgweb() or hgwebdir()
can and should now be used as a WSGI application.'''
--- a/tests/test-wsgirequest.py Sat Mar 10 15:24:24 2018 +0530
+++ b/tests/test-wsgirequest.py Sun Mar 11 16:29:54 2018 -0700
@@ -23,11 +23,11 @@
r'wsgi.run_once': False,
}
-def parse(env, bodyfh=None, reponame=None, altbaseurl=None, extra=None):
+def parse(env, reponame=None, altbaseurl=None, extra=None):
env = dict(env)
env.update(extra or {})
- return requestmod.parserequestfromenv(env, bodyfh, reponame=reponame,
+ return requestmod.parserequestfromenv(env, reponame=reponame,
altbaseurl=altbaseurl)
class ParseRequestTests(unittest.TestCase):