[issue21878] wsgi.simple_server's wsgi.input read/readline waits forever in certain circumstances

Dom Cote report at bugs.python.org
Fri Jun 2 16:21:09 EDT 2017


Dom Cote added the comment:

Just bumped into this issue today using bobo.

On the first attempt to load a page, it's OK, because there is something to read. But if you hit the "reload" button on the browser, for some reason, it will connect with the server a second time after the request is completed, and but there nothing is being sent, so readline() never comes back.

However, the documentation says that if the underlying object is set as non-blocking, then it shouldn't block.

So I first inspected the timeout value on the request's socket, and it comes back 0.0, which according to the sockets doc, should mean non blocking. That's weird.

So I decided to go ahead and call the setblocking(False) on the socket anyway, and this time, readline() came back with no data. The rest took care of itself.

This is my debug traces as well as a small patch to show the workaround.

Notice how the timeout is comes back as 0.0 despite the fact that the socket will block.

Also, notice the second connection request being '' after putting in the fix.

==============

> <socket.socket fd=5, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('192.168.1.113', 8085), raddr=('192.168.1.6', 59194)> 0.0
7> b'GET / HTTP/1.1\r\n'
192.168.1.6 - - [02/Jun/2017 16:01:39] "GET / HTTP/1.1" 200 690
5> <socket.socket fd=5, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('192.168.1.113', 8085), raddr=('192.168.1.6', 59195)> 0.0
6> <socket.socket fd=5, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('192.168.1.113', 8085), raddr=('192.168.1.6', 59195)> 0.0
7> b''

diff --git a/simple_server.py b/simple_server.py
index 7fddbe8..3df4ffa 100644
--- a/simple_server.py
+++ b/simple_server.py
@@ -115,9 +115,13 @@ class WSGIRequestHandler(BaseHTTPRequestHandler):

     def handle(self):
         """Handle a single HTTP request"""
-
+        print("5>",self.connection,self.connection.gettimeout())
+        self.connection.setblocking(False)
         self.raw_requestline = self.rfile.readline(65537)
-        if len(self.raw_requestline) > 65536:
+        print("6>",self.connection,self.connection.gettimeout())
+        print("7>",str(self.raw_requestline))
+
+        if False and len(self.raw_requestline) > 65536:
             self.requestline = ''
             self.request_version = ''
             self.command = ''

----------
nosy: +buzdelabuz2

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue21878>
_______________________________________


More information about the Python-bugs-list mailing list