##// END OF EJS Templates
hgweb: remove wsgirequest (API)...
Gregory Szorc -
r36928:f0a85154 default
parent child Browse files
Show More
@@ -290,10 +290,12 b' class hgweb(object):'
290 290
291 291 This may be called by multiple threads.
292 292 """
293 req = requestmod.wsgirequest(env, respond)
294 return self.run_wsgi(req)
293 req = requestmod.parserequestfromenv(env)
294 res = requestmod.wsgiresponse(req, respond)
295 295
296 def run_wsgi(self, wsgireq):
296 return self.run_wsgi(req, res)
297
298 def run_wsgi(self, req, res):
297 299 """Internal method to run the WSGI application.
298 300
299 301 This is typically only called by Mercurial. External consumers
@@ -302,12 +304,10 b' class hgweb(object):'
302 304 with self._obtainrepo() as repo:
303 305 profile = repo.ui.configbool('profiling', 'enabled')
304 306 with profiling.profile(repo.ui, enabled=profile):
305 for r in self._runwsgi(wsgireq, repo):
307 for r in self._runwsgi(req, res, repo):
306 308 yield r
307 309
308 def _runwsgi(self, wsgireq, repo):
309 req = wsgireq.req
310 res = wsgireq.res
310 def _runwsgi(self, req, res, repo):
311 311 rctx = requestcontext(self, repo, req, res)
312 312
313 313 # This state is global across all threads.
@@ -348,19 +348,18 b' class hgwebdir(object):'
348 348
349 349 def __call__(self, env, respond):
350 350 baseurl = self.ui.config('web', 'baseurl')
351 wsgireq = requestmod.wsgirequest(env, respond, altbaseurl=baseurl)
352 return self.run_wsgi(wsgireq)
351 req = requestmod.parserequestfromenv(env, altbaseurl=baseurl)
352 res = requestmod.wsgiresponse(req, respond)
353 353
354 def run_wsgi(self, wsgireq):
354 return self.run_wsgi(req, res)
355
356 def run_wsgi(self, req, res):
355 357 profile = self.ui.configbool('profiling', 'enabled')
356 358 with profiling.profile(self.ui, enabled=profile):
357 for r in self._runwsgi(wsgireq):
359 for r in self._runwsgi(req, res):
358 360 yield r
359 361
360 def _runwsgi(self, wsgireq):
361 req = wsgireq.req
362 res = wsgireq.res
363
362 def _runwsgi(self, req, res):
364 363 try:
365 364 self.refresh()
366 365
@@ -423,13 +422,13 b' class hgwebdir(object):'
423 422 if real:
424 423 # Re-parse the WSGI environment to take into account our
425 424 # repository path component.
426 wsgireq.req = requestmod.parserequestfromenv(
427 wsgireq.env, wsgireq.req.bodyfh, reponame=virtualrepo,
425 req = requestmod.parserequestfromenv(
426 req.rawenv, reponame=virtualrepo,
428 427 altbaseurl=self.ui.config('web', 'baseurl'))
429 428 try:
430 429 # ensure caller gets private copy of ui
431 430 repo = hg.repository(self.ui.copy(), real)
432 return hgweb_mod.hgweb(repo).run_wsgi(wsgireq)
431 return hgweb_mod.hgweb(repo).run_wsgi(req, res)
433 432 except IOError as inst:
434 433 msg = encoding.strtolocal(inst.strerror)
435 434 raise ErrorResponse(HTTP_SERVER_ERROR, msg)
@@ -152,7 +152,7 b' class parsedrequest(object):'
152 152 # WSGI environment dict, unmodified.
153 153 rawenv = attr.ib()
154 154
155 def parserequestfromenv(env, bodyfh, reponame=None, altbaseurl=None):
155 def parserequestfromenv(env, reponame=None, altbaseurl=None):
156 156 """Parse URL components from environment variables.
157 157
158 158 WSGI defines request attributes via environment variables. This function
@@ -325,11 +325,9 b' def parserequestfromenv(env, bodyfh, rep'
325 325 if 'CONTENT_LENGTH' in env and 'HTTP_CONTENT_LENGTH' not in env:
326 326 headers['Content-Length'] = env['CONTENT_LENGTH']
327 327
328 # TODO do this once we remove wsgirequest.inp, otherwise we could have
329 # multiple readers from the underlying input stream.
330 #bodyfh = env['wsgi.input']
331 #if 'Content-Length' in headers:
332 # bodyfh = util.cappedreader(bodyfh, int(headers['Content-Length']))
328 bodyfh = env['wsgi.input']
329 if 'Content-Length' in headers:
330 bodyfh = util.cappedreader(bodyfh, int(headers['Content-Length']))
333 331
334 332 return parsedrequest(method=env['REQUEST_METHOD'],
335 333 url=fullurl, baseurl=baseurl,
@@ -578,34 +576,6 b' class wsgiresponse(object):'
578 576 assert self._bodywritefn
579 577 return offsettrackingwriter(self._bodywritefn)
580 578
581 class wsgirequest(object):
582 """Higher-level API for a WSGI request.
583
584 WSGI applications are invoked with 2 arguments. They are used to
585 instantiate instances of this class, which provides higher-level APIs
586 for obtaining request parameters, writing HTTP output, etc.
587 """
588 def __init__(self, wsgienv, start_response, altbaseurl=None):
589 version = wsgienv[r'wsgi.version']
590 if (version < (1, 0)) or (version >= (2, 0)):
591 raise RuntimeError("Unknown and unsupported WSGI version %d.%d"
592 % version)
593
594 inp = wsgienv[r'wsgi.input']
595
596 if r'HTTP_CONTENT_LENGTH' in wsgienv:
597 inp = util.cappedreader(inp, int(wsgienv[r'HTTP_CONTENT_LENGTH']))
598 elif r'CONTENT_LENGTH' in wsgienv:
599 inp = util.cappedreader(inp, int(wsgienv[r'CONTENT_LENGTH']))
600
601 self.err = wsgienv[r'wsgi.errors']
602 self.threaded = wsgienv[r'wsgi.multithread']
603 self.multiprocess = wsgienv[r'wsgi.multiprocess']
604 self.run_once = wsgienv[r'wsgi.run_once']
605 self.env = wsgienv
606 self.req = parserequestfromenv(wsgienv, inp, altbaseurl=altbaseurl)
607 self.res = wsgiresponse(self.req, start_response)
608
609 579 def wsgiapplication(app_maker):
610 580 '''For compatibility with old CGI scripts. A plain hgweb() or hgwebdir()
611 581 can and should now be used as a WSGI application.'''
@@ -23,11 +23,11 b' DEFAULT_ENV = {'
23 23 r'wsgi.run_once': False,
24 24 }
25 25
26 def parse(env, bodyfh=None, reponame=None, altbaseurl=None, extra=None):
26 def parse(env, reponame=None, altbaseurl=None, extra=None):
27 27 env = dict(env)
28 28 env.update(extra or {})
29 29
30 return requestmod.parserequestfromenv(env, bodyfh, reponame=reponame,
30 return requestmod.parserequestfromenv(env, reponame=reponame,
31 31 altbaseurl=altbaseurl)
32 32
33 33 class ParseRequestTests(unittest.TestCase):
General Comments 0
You need to be logged in to leave comments. Login now