Wait for a non-empty chunk in WSGIContext._app_call

We're functioning as a WSGI server here, so this bit from PEP-3333 seems
to apply:

> The start_response callable must not actually transmit the response
> headers. Instead, it must store them for the server or gateway to
> transmit only after the first iteration of the application return
> value that yields a non-empty bytestrin ... . In other words, response
> headers must not be sent until there is actual body data available, or
> until the application's returned iterable is exhausted.

Plus, it mirrors what swob.Request.call_application does.

Change-Id: I1e8501f8ce91ea912780db64fee1c56bef809a98
This commit is contained in:
Tim Burke
2016-08-12 05:46:33 +00:00
parent 1f90e8a4ac
commit f7a820ed3a
2 changed files with 8 additions and 11 deletions

View File

@@ -42,7 +42,7 @@ from swift.common.swob import Request
from swift.common.utils import capture_stdio, disable_fallocate, \
drop_privileges, get_logger, NullLogger, config_true_value, \
validate_configuration, get_hub, config_auto_int_value, \
CloseableChain
reiterate
# Set maximum line size of message headers to be accepted.
wsgi.MAX_HEADER_LINE = constraints.MAX_HEADER_SIZE
@@ -1053,16 +1053,11 @@ class WSGIContext(object):
self._response_headers = None
self._response_exc_info = None
resp = self.app(env, self._start_response)
# if start_response has been called, just return the iter
if self._response_status is not None:
return resp
resp = iter(resp)
try:
first_chunk = next(resp)
except StopIteration:
return iter([])
else: # We got a first_chunk
return CloseableChain([first_chunk], resp)
# if start_response has not been called, iterate until we've got a
# non-empty chunk, by which time the app *should* have called it
if self._response_status is None:
resp = reiterate(resp)
return resp
def _get_status_int(self):
"""

View File

@@ -1242,6 +1242,8 @@ class TestWSGIContext(unittest.TestCase):
def test_app_iter_is_closable(self):
def app(env, start_response):
yield ''
yield ''
start_response('200 OK', [('Content-Length', '25')])
yield 'aaaaa'
yield 'bbbbb'