Commit 62e3ffed authored by Jason Madden's avatar Jason Madden

Set the non-standard wsgi.input_terminated flag. Fixes #1308.

parent b74209a7
...@@ -50,6 +50,9 @@ ...@@ -50,6 +50,9 @@
enums instead of plain integers for the socket type and address enums instead of plain integers for the socket type and address
family on Python 3. See :issue:`1310` reported by TheYOSH. family on Python 3. See :issue:`1310` reported by TheYOSH.
- Make gevent's pywsgi server set the non-standard environment value
``wsgi.input_terminated`` to True. See :issue:`1308`.
1.3.7 (2018-10-12) 1.3.7 (2018-10-12)
================== ==================
......
...@@ -1119,6 +1119,10 @@ class WSGIHandler(object): ...@@ -1119,6 +1119,10 @@ class WSGIHandler(object):
chunked = env.get('HTTP_TRANSFER_ENCODING', '').lower() == 'chunked' chunked = env.get('HTTP_TRANSFER_ENCODING', '').lower() == 'chunked'
self.wsgi_input = Input(self.rfile, self.content_length, socket=sock, chunked_input=chunked) self.wsgi_input = Input(self.rfile, self.content_length, socket=sock, chunked_input=chunked)
env['wsgi.input'] = self.wsgi_input env['wsgi.input'] = self.wsgi_input
# This is a non-standard flag indicating that our input stream is
# self-terminated (returns EOF when consumed).
# See https://github.com/gevent/gevent/issues/1308
env['wsgi.input_terminated'] = True
return env return env
......
...@@ -371,8 +371,8 @@ class TestNoChunks(CommonTests): ...@@ -371,8 +371,8 @@ class TestNoChunks(CommonTests):
# it calculates the content-length and joins all the chunks before sending # it calculates the content-length and joins all the chunks before sending
validator = None validator = None
@staticmethod def application(self, env, start_response):
def application(env, start_response): self.assertTrue(env.get('wsgi.input_terminated'))
path = env['PATH_INFO'] path = env['PATH_INFO']
if path == '/': if path == '/':
start_response('200 OK', [('Content-Type', 'text/plain')]) start_response('200 OK', [('Content-Type', 'text/plain')])
...@@ -400,8 +400,8 @@ class TestExplicitContentLength(TestNoChunks): # pylint:disable=too-many-ancesto ...@@ -400,8 +400,8 @@ class TestExplicitContentLength(TestNoChunks): # pylint:disable=too-many-ancesto
# when returning a list of strings a shortcut is empoyed by the # when returning a list of strings a shortcut is empoyed by the
# server - it caculates the content-length # server - it caculates the content-length
@staticmethod def application(self, env, start_response):
def application(env, start_response): self.assertTrue(env.get('wsgi.input_terminated'))
path = env['PATH_INFO'] path = env['PATH_INFO']
if path == '/': if path == '/':
start_response('200 OK', [('Content-Type', 'text/plain'), ('Content-Length', '11')]) start_response('200 OK', [('Content-Type', 'text/plain'), ('Content-Length', '11')])
...@@ -520,6 +520,7 @@ class TestChunkedApp(TestCase): ...@@ -520,6 +520,7 @@ class TestChunkedApp(TestCase):
return b''.join(self.chunks) return b''.join(self.chunks)
def application(self, env, start_response): def application(self, env, start_response):
self.assertTrue(env.get('wsgi.input_terminated'))
start_response('200 OK', [('Content-Type', 'text/plain')]) start_response('200 OK', [('Content-Type', 'text/plain')])
for chunk in self.chunks: for chunk in self.chunks:
yield chunk yield chunk
...@@ -552,8 +553,9 @@ class TestBigChunks(TestChunkedApp): ...@@ -552,8 +553,9 @@ class TestBigChunks(TestChunkedApp):
class TestNegativeRead(TestCase): class TestNegativeRead(TestCase):
@staticmethod
def application(env, start_response): def application(self, env, start_response):
self.assertTrue(env.get('wsgi.input_terminated'))
start_response('200 OK', [('Content-Type', 'text/plain')]) start_response('200 OK', [('Content-Type', 'text/plain')])
if env['PATH_INFO'] == '/read': if env['PATH_INFO'] == '/read':
data = env['wsgi.input'].read(-1) data = env['wsgi.input'].read(-1)
...@@ -605,8 +607,9 @@ class TestNegativeReadline(TestCase): ...@@ -605,8 +607,9 @@ class TestNegativeReadline(TestCase):
class TestChunkedPost(TestCase): class TestChunkedPost(TestCase):
@staticmethod
def application(env, start_response): def application(self, env, start_response):
self.assertTrue(env.get('wsgi.input_terminated'))
start_response('200 OK', [('Content-Type', 'text/plain')]) start_response('200 OK', [('Content-Type', 'text/plain')])
if env['PATH_INFO'] == '/a': if env['PATH_INFO'] == '/a':
data = env['wsgi.input'].read(6) data = env['wsgi.input'].read(6)
......
...@@ -412,7 +412,8 @@ add(Test1234, '1.2.3.4') ...@@ -412,7 +412,8 @@ add(Test1234, '1.2.3.4')
class Test127001(TestCase): class Test127001(TestCase):
pass pass
add(Test127001, '127.0.0.1', add(
Test127001, '127.0.0.1',
skip=greentest.RUNNING_ON_TRAVIS, skip=greentest.RUNNING_ON_TRAVIS,
skip_reason="Beginning Dec 1 2017, ares started returning ip6-localhost " skip_reason="Beginning Dec 1 2017, ares started returning ip6-localhost "
"instead of localhost" "instead of localhost"
...@@ -621,7 +622,7 @@ class TestInterrupted_gethostbyname(gevent.testing.timing.AbstractGenericWaitTes ...@@ -621,7 +622,7 @@ class TestInterrupted_gethostbyname(gevent.testing.timing.AbstractGenericWaitTes
# gaierror: [Errno -2] Name or service not known # gaierror: [Errno -2] Name or service not known
try: try:
gevent.get_hub().threadpool.join() gevent.get_hub().threadpool.join()
except Exception: # pylint:disable=broad-except pragma: no cover except Exception: # pragma: no cover pylint:disable=broad-except
traceback.print_exc() traceback.print_exc()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment