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 specified content_length variable.

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

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -