]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Fixing HTTP_Request2_SocketWrapper so it times out
authorMikael Nordfeldth <mmn@hethane.se>
Tue, 11 Jul 2017 10:04:09 +0000 (12:04 +0200)
committerMikael Nordfeldth <mmn@hethane.se>
Tue, 11 Jul 2017 10:04:09 +0000 (12:04 +0200)
HTTP_Request2_SocketWrapper would never time out on an fgets() call as
discussed in issue #281 https://git.gnu.io/gnu/gnu-social/issues/281

I'm patching it here by setting the socket to non-blocking mode and
using stream_select to wait until the timeout. This patch or some
similar variant must be implemented in HTTP_Request2_SocketWrapper
to avoid the same issue for other users.

extlib/HTTP/Request2/SocketWrapper.php

index 2cf4257db2e26a45b7b4afa8f397a23a17fdf721..3028a108d7c10bef8061ae757b87084e96762a81 100644 (file)
@@ -181,12 +181,27 @@ class HTTP_Request2_SocketWrapper
         $line = '';\r
         while (!feof($this->socket)) {\r
             if (null !== $localTimeout) {\r
-                stream_set_timeout($this->socket, $localTimeout);\r
+                $timeout = $localTimeout;\r
             } elseif ($this->deadline) {\r
-                stream_set_timeout($this->socket, max($this->deadline - time(), 1));\r
+                $timeout = max($this->deadline - time(), 1);\r
+            } else {\r
+                // "If tv_sec is NULL stream_select() can block\r
+                // indefinitely, returning only when an event on one of\r
+                // the watched streams occurs (or if a signal interrupts\r
+                // the system call)." - http://php.net/stream_select\r
+                $timeout = null;\r
             }\r
 \r
-            $line .= @fgets($this->socket, $bufferSize);\r
+            $info = stream_get_meta_data($this->socket);\r
+            $old_blocking = (bool)$info['blocked'];\r
+            stream_set_blocking($this->socket, false);\r
+            $r = array($this->socket);\r
+            $w = array();\r
+            $e = array();\r
+            if (stream_select($r, $w, $e, $timeout)) {\r
+                $line .= @fgets($this->socket, $bufferSize);\r
+            }\r
+            stream_set_blocking($this->socket, $old_blocking);\r
 \r
             if (null === $localTimeout) {\r
                 $this->checkTimeout();\r