##// END OF EJS Templates
hgweb: remove wsgirequest (API)...
Gregory Szorc -
r37077:f0a85154 default
parent child Browse files
Show More
@@ -290,10 +290,12 b' class hgweb(object):'
290
290
291 This may be called by multiple threads.
291 This may be called by multiple threads.
292 """
292 """
293 req = requestmod.wsgirequest(env, respond)
293 req = requestmod.parserequestfromenv(env)
294 return self.run_wsgi(req)
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 """Internal method to run the WSGI application.
299 """Internal method to run the WSGI application.
298
300
299 This is typically only called by Mercurial. External consumers
301 This is typically only called by Mercurial. External consumers
@@ -302,12 +304,10 b' class hgweb(object):'
302 with self._obtainrepo() as repo:
304 with self._obtainrepo() as repo:
303 profile = repo.ui.configbool('profiling', 'enabled')
305 profile = repo.ui.configbool('profiling', 'enabled')
304 with profiling.profile(repo.ui, enabled=profile):
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 yield r
308 yield r
307
309
308 def _runwsgi(self, wsgireq, repo):
310 def _runwsgi(self, req, res, repo):
309 req = wsgireq.req
310 res = wsgireq.res
311 rctx = requestcontext(self, repo, req, res)
311 rctx = requestcontext(self, repo, req, res)
312
312
313 # This state is global across all threads.
313 # This state is global across all threads.
@@ -348,19 +348,18 b' class hgwebdir(object):'
348
348
349 def __call__(self, env, respond):
349 def __call__(self, env, respond):
350 baseurl = self.ui.config('web', 'baseurl')
350 baseurl = self.ui.config('web', 'baseurl')
351 wsgireq = requestmod.wsgirequest(env, respond, altbaseurl=baseurl)
351 req = requestmod.parserequestfromenv(env, altbaseurl=baseurl)
352 return self.run_wsgi(wsgireq)
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 profile = self.ui.configbool('profiling', 'enabled')
357 profile = self.ui.configbool('profiling', 'enabled')
356 with profiling.profile(self.ui, enabled=profile):
358 with profiling.profile(self.ui, enabled=profile):
357 for r in self._runwsgi(wsgireq):
359 for r in self._runwsgi(req, res):
358 yield r
360 yield r
359
361
360 def _runwsgi(self, wsgireq):
362 def _runwsgi(self, req, res):
361 req = wsgireq.req
362 res = wsgireq.res
363
364 try:
363 try:
365 self.refresh()
364 self.refresh()
366
365
@@ -423,13 +422,13 b' class hgwebdir(object):'
423 if real:
422 if real:
424 # Re-parse the WSGI environment to take into account our
423 # Re-parse the WSGI environment to take into account our
425 # repository path component.
424 # repository path component.
426 wsgireq.req = requestmod.parserequestfromenv(
425 req = requestmod.parserequestfromenv(
427 wsgireq.env, wsgireq.req.bodyfh, reponame=virtualrepo,
426 req.rawenv, reponame=virtualrepo,
428 altbaseurl=self.ui.config('web', 'baseurl'))
427 altbaseurl=self.ui.config('web', 'baseurl'))
429 try:
428 try:
430 # ensure caller gets private copy of ui
429 # ensure caller gets private copy of ui
431 repo = hg.repository(self.ui.copy(), real)
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 except IOError as inst:
432 except IOError as inst:
434 msg = encoding.strtolocal(inst.strerror)
433 msg = encoding.strtolocal(inst.strerror)
435 raise ErrorResponse(HTTP_SERVER_ERROR, msg)
434 raise ErrorResponse(HTTP_SERVER_ERROR, msg)
@@ -152,7 +152,7 b' class parsedrequest(object):'
152 # WSGI environment dict, unmodified.
152 # WSGI environment dict, unmodified.
153 rawenv = attr.ib()
153 rawenv = attr.ib()
154
154
155 def parserequestfromenv(env, bodyfh, reponame=None, altbaseurl=None):
155 def parserequestfromenv(env, reponame=None, altbaseurl=None):
156 """Parse URL components from environment variables.
156 """Parse URL components from environment variables.
157
157
158 WSGI defines request attributes via environment variables. This function
158 WSGI defines request attributes via environment variables. This function
@@ -325,11 +325,9 b' def parserequestfromenv(env, bodyfh, rep'
325 if 'CONTENT_LENGTH' in env and 'HTTP_CONTENT_LENGTH' not in env:
325 if 'CONTENT_LENGTH' in env and 'HTTP_CONTENT_LENGTH' not in env:
326 headers['Content-Length'] = env['CONTENT_LENGTH']
326 headers['Content-Length'] = env['CONTENT_LENGTH']
327
327
328 # TODO do this once we remove wsgirequest.inp, otherwise we could have
328 bodyfh = env['wsgi.input']
329 # multiple readers from the underlying input stream.
329 if 'Content-Length' in headers:
330 #bodyfh = env['wsgi.input']
330 bodyfh = util.cappedreader(bodyfh, int(headers['Content-Length']))
331 #if 'Content-Length' in headers:
332 # bodyfh = util.cappedreader(bodyfh, int(headers['Content-Length']))
333
331
334 return parsedrequest(method=env['REQUEST_METHOD'],
332 return parsedrequest(method=env['REQUEST_METHOD'],
335 url=fullurl, baseurl=baseurl,
333 url=fullurl, baseurl=baseurl,
@@ -578,34 +576,6 b' class wsgiresponse(object):'
578 assert self._bodywritefn
576 assert self._bodywritefn
579 return offsettrackingwriter(self._bodywritefn)
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 def wsgiapplication(app_maker):
579 def wsgiapplication(app_maker):
610 '''For compatibility with old CGI scripts. A plain hgweb() or hgwebdir()
580 '''For compatibility with old CGI scripts. A plain hgweb() or hgwebdir()
611 can and should now be used as a WSGI application.'''
581 can and should now be used as a WSGI application.'''
@@ -23,11 +23,11 b' DEFAULT_ENV = {'
23 r'wsgi.run_once': False,
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 env = dict(env)
27 env = dict(env)
28 env.update(extra or {})
28 env.update(extra or {})
29
29
30 return requestmod.parserequestfromenv(env, bodyfh, reponame=reponame,
30 return requestmod.parserequestfromenv(env, reponame=reponame,
31 altbaseurl=altbaseurl)
31 altbaseurl=altbaseurl)
32
32
33 class ParseRequestTests(unittest.TestCase):
33 class ParseRequestTests(unittest.TestCase):
General Comments 0
You need to be logged in to leave comments. Login now