Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/hgweb/hgweb_mod.py @ 36867:a88d68dc3ee8
hgweb: create dedicated type for WSGI responses
We have refactored the request side of WSGI processing into a dedicated
type. Now let's do the same thing for the response side.
We invent a ``wsgiresponse`` type. It takes an instance of a
request (for consulation) and the WSGI application's "start_response"
handler.
The type basically allows setting the HTTP status line, response
headers, and the response body.
The WSGI application calls sendresponse() to start sending output.
Output is emitted as a generator to be fed through the WSGI application.
According to PEP 3333, this is the preferred way for output to be
transmitted. (Our legacy ``wsgirequest`` exposed a write() to send
data. We do not wish to support this API because it isn't recommended
by PEP 3333.)
The wire protocol code has been ported to use the new API.
Differential Revision: https://phab.mercurial-scm.org/D2775
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sat, 10 Mar 2018 11:23:05 -0800 |
parents | 1f7d9024674c |
children | 1a1972b1a1ff |
comparison
equal
deleted
inserted
replaced
36866:2859c6fa4fc2 | 36867:a88d68dc3ee8 |
---|---|
303 for r in self._runwsgi(wsgireq, repo): | 303 for r in self._runwsgi(wsgireq, repo): |
304 yield r | 304 yield r |
305 | 305 |
306 def _runwsgi(self, wsgireq, repo): | 306 def _runwsgi(self, wsgireq, repo): |
307 req = wsgireq.req | 307 req = wsgireq.req |
308 res = wsgireq.res | |
308 rctx = requestcontext(self, repo) | 309 rctx = requestcontext(self, repo) |
309 | 310 |
310 # This state is global across all threads. | 311 # This state is global across all threads. |
311 encoding.encoding = rctx.config('web', 'encoding') | 312 encoding.encoding = rctx.config('web', 'encoding') |
312 rctx.repo.ui.environ = wsgireq.env | 313 rctx.repo.ui.environ = wsgireq.env |
315 # hgwebdir may have added CSP header. Since we generate our own, | 316 # hgwebdir may have added CSP header. Since we generate our own, |
316 # replace it. | 317 # replace it. |
317 wsgireq.headers = [h for h in wsgireq.headers | 318 wsgireq.headers = [h for h in wsgireq.headers |
318 if h[0] != 'Content-Security-Policy'] | 319 if h[0] != 'Content-Security-Policy'] |
319 wsgireq.headers.append(('Content-Security-Policy', rctx.csp)) | 320 wsgireq.headers.append(('Content-Security-Policy', rctx.csp)) |
320 | 321 res.headers['Content-Security-Policy'] = rctx.csp |
321 handled, res = wireprotoserver.handlewsgirequest( | 322 |
322 rctx, wsgireq, req, self.check_perm) | 323 handled = wireprotoserver.handlewsgirequest( |
324 rctx, wsgireq, req, res, self.check_perm) | |
323 if handled: | 325 if handled: |
324 return res | 326 return res.sendresponse() |
325 | 327 |
326 if req.havepathinfo: | 328 if req.havepathinfo: |
327 query = req.dispatchpath | 329 query = req.dispatchpath |
328 else: | 330 else: |
329 query = req.querystring.partition('&')[0].partition(';')[0] | 331 query = req.querystring.partition('&')[0].partition(';')[0] |