From 05a9c11c476b384e5ef3f3cc83b66406fcf7a378 Mon Sep 17 00:00:00 2001 From: Mikael Nordfeldth Date: Tue, 11 Jul 2017 12:04:09 +0200 Subject: [PATCH] Fixing HTTP_Request2_SocketWrapper so it times out 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 | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/extlib/HTTP/Request2/SocketWrapper.php b/extlib/HTTP/Request2/SocketWrapper.php index 2cf4257db2..3028a108d7 100644 --- a/extlib/HTTP/Request2/SocketWrapper.php +++ b/extlib/HTTP/Request2/SocketWrapper.php @@ -181,12 +181,27 @@ class HTTP_Request2_SocketWrapper $line = ''; while (!feof($this->socket)) { if (null !== $localTimeout) { - stream_set_timeout($this->socket, $localTimeout); + $timeout = $localTimeout; } elseif ($this->deadline) { - stream_set_timeout($this->socket, max($this->deadline - time(), 1)); + $timeout = max($this->deadline - time(), 1); + } else { + // "If tv_sec is NULL stream_select() can block + // indefinitely, returning only when an event on one of + // the watched streams occurs (or if a signal interrupts + // the system call)." - http://php.net/stream_select + $timeout = null; } - $line .= @fgets($this->socket, $bufferSize); + $info = stream_get_meta_data($this->socket); + $old_blocking = (bool)$info['blocked']; + stream_set_blocking($this->socket, false); + $r = array($this->socket); + $w = array(); + $e = array(); + if (stream_select($r, $w, $e, $timeout)) { + $line .= @fgets($this->socket, $bufferSize); + } + stream_set_blocking($this->socket, $old_blocking); if (null === $localTimeout) { $this->checkTimeout();