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_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
Post a Comment