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.
This commit is contained in:
Mikael Nordfeldth 2017-07-11 12:04:09 +02:00
parent 9919ccb8b5
commit 05a9c11c47

View File

@ -181,12 +181,27 @@ class HTTP_Request2_SocketWrapper
$line = ''; $line = '';
while (!feof($this->socket)) { while (!feof($this->socket)) {
if (null !== $localTimeout) { if (null !== $localTimeout) {
stream_set_timeout($this->socket, $localTimeout); $timeout = $localTimeout;
} elseif ($this->deadline) { } 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;
} }
$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); $line .= @fgets($this->socket, $bufferSize);
}
stream_set_blocking($this->socket, $old_blocking);
if (null === $localTimeout) { if (null === $localTimeout) {
$this->checkTimeout(); $this->checkTimeout();