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. |
|
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( |
|
307 | for r in self._runwsgi(req, res, repo): | |
306 | yield r |
|
308 | yield r | |
307 |
|
309 | |||
308 |
def _runwsgi(self, |
|
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 |
|
|
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( |
|
359 | for r in self._runwsgi(req, res): | |
358 | yield r |
|
360 | yield r | |
359 |
|
361 | |||
360 |
def _runwsgi(self, |
|
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 |
|
|
425 | req = requestmod.parserequestfromenv( | |
427 |
|
|
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( |
|
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 |
|
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 |
|
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, |
|
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