python - Why does environ['wsgi.input'].read() block even though it is allowed by PEP-3333? -
issue
here simple wsgi application supposed print content-length , request body in header.
def application(environ, start_response): start_response('200 ok', [('content-type','text/plain')]) content_length = int(environ['content_length']) print('---- begin ----') print('content_length:', content_length) print('wsgi.input:', environ['wsgi.input'].read()) print('---- end ----') return [b'foo\n'] if __name__ == '__main__': wsgiref import simple_server server = simple_server.make_server('0.0.0.0', 8080, application) server.serve_forever() when run application, gets blocked @ following call: environ['wsgi.input'].read().
i run application using python 3 interpreter , submit http post request using curl.
lone@debian:~$ curl --data "a=1&b=2" http://localhost:8080/ the curl command gets blocked waiting output. python interpreter gets blocked @ environ['wsgi.input'].read() call.
lone@debian:~$ python3 foo.py ---- begin ---- content_length: 7 as can see in output above, application() function has got blocked after printing content_length.
workaround
i know how work around issue: passing content-length header value read() call.
modified code workaround issue:
def application(environ, start_response): start_response('200 ok', [('content-type','text/plain')]) content_length = int(environ['content_length']) print('---- begin ----') print('content_length:', content_length) print('wsgi.input:', environ['wsgi.input'].read(content_length)) print('---- end ----') return [b'foo\n'] if __name__ == '__main__': wsgiref import simple_server server = simple_server.make_server('0.0.0.0', 8080, application) server.serve_forever() the curl command gets valid http response now.
lone@debian:~$ curl --data "a=1&b=2" http://localhost:8080/ foo lone@debian:~$ the application() function completes execution.
lone@debian:~$ python3 foo.py ---- begin ---- content_length: 7 wsgi.input: b'a=1&b=2' ---- end ---- 127.0.0.1 - - [06/apr/2014 17:53:21] "post / http/1.1" 200 4 question
why environ['wsgi.input'].read() call block when read called without arguments?
the pep-3333 document seems imply should work. here relevant text.
the server not required read past client's specified
content-length, , should simulate end-of-file condition if application attempts read past point. application should not attempt read more data specifiedcontent_lengthvariable.a server should allow
read()called without argument, , return remainder of client's input stream.
i understand application should not attempt read more data specified content_length variable. disobeying directive. server should allow read() called without argument , return me entire input stream. why isn't doing so?
because implements pep 333 , not pep 3333.
pep 333 didn't have condition simulating end of stream returning empty string.
in pep 333 have problems if tried read more content_length if wsgi server supported http 1.1 , request pipe lining (keep alive) being used.
i suggest read pep 333 , compare language pep 3333.
also read:
where describe whole issue , contributed change in pep when updated python 3.
Comments
Post a Comment