A two step proposal to fix the situation with different behaviors of input streams in WSGI.
WSGI servers have two options to providing the input stream:
- Provide
wsgi.input
as socket file unchanged. This means thatwsgi.input_terminated
is set to False or not added to the WSGI environ at all. In that case the WSGI application is required to look at theCONTENT_LENGTH
and only read up to that point. - Provide
wsgi.input
as an end-of-file terminated stream. In that casewsgi.input_terminated
is set to True and an app is required to read to the end of the file and disregardCONTENT_LENGTH
for reading.
Pseudocode for a WSGI implementation:
def get_input_stream(environ):
stream = environ['wsgi.input']
# This part is new
if environ.get('wsgi.input_terminated'):
return stream
# This part was necessary before anyways to not accidentally
# read past the length of the stream.
return wrap_stream(environ['wsgi.input'],
environ['CONTENT_LENGTH'])
The only thing that needs to be changed in the WSGI server is either nothing (for instance wsgiref or any other simple WSGI server that just puts the socket through does nothing) or a server like mod_wsgi or gunicorn that terminate the input stream set the flag wsgi.input_terminated
to True when making the WSGI environ.
-1 on your proposal mcdonc because it means that you now need to provide two streams and you need to synchronize them. Imagine what happens if someone wants to make a middleware that wraps the input.