Skip to content

Commit

Permalink
Improve read_timeout handling (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
bytestream authored Jul 6, 2023
1 parent de1d7f0 commit 0bf16a5
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 12 deletions.
4 changes: 2 additions & 2 deletions lib/Horde/Imap/Client/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ abstract class Horde_Imap_Client_Base
* - timeout: (integer) Connection timeout, in seconds.
* DEFAULT: 30 seconds
* - read_timeout: (integer) Read timeout, in seconds.
* DEFAULT: 30 seconds
* DEFAULT: 120 seconds
* - username: (string) [REQUIRED] The username.
* - authusername (string) The username used for SASL authentication.
* If specified this is the user name whose password is used
Expand All @@ -254,7 +254,7 @@ public function __construct(array $params = array())
'hostspec' => 'localhost',
'secure' => false,
'timeout' => 30,
'read_timeout' => 30,
'read_timeout' => 120,
), array_filter($params));

if (!isset($params['port']) && strpos($params['hostspec'], 'unix://') !== 0) {
Expand Down
5 changes: 5 additions & 0 deletions lib/Horde/Imap/Client/Exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ class Horde_Imap_Client_Exception extends Horde_Exception_Wrapped
*/
const SERVER_READERROR = 12;

/**
* Thrown if read timeout occurs.
*/
const SERVER_READTIMEOUT = 28;

/**
* Thrown if write error in server interaction.
*/
Expand Down
30 changes: 24 additions & 6 deletions lib/Horde/Imap/Client/Socket.php
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@ protected function _connect()
array(
'debug' => $this->_debug,
'debugliteral' => $this->getParam('debug_literal'),
'timeout' => $this->getParam('timeout'),
'read_timeout' => $this->getParam('read_timeout'),
)
);
Expand Down Expand Up @@ -4311,17 +4312,34 @@ protected function _sendCmdChunk($pipeline, $chunk)

while ($cmd_count) {
try {
if (! isset($read_start)) {
$read_start = microtime(true);
}

if ($this->_getLine($pipeline) instanceof Horde_Imap_Client_Interaction_Server_Tagged) {
--$cmd_count;
}

$read_start = null;
} catch (Horde_Imap_Client_Exception $e) {
switch ($e->getCode()) {
case $e::DISCONNECT:
/* Guaranteed to have no more data incoming, so we can
* immediately logout. */
$this->_temp['logout'] = true;
$this->logout();
throw $e;
case $e::DISCONNECT:
/* Guaranteed to have no more data incoming, so we can
* immediately logout. */
$this->_temp['logout'] = true;
$this->logout();
throw $e;

case $e::SERVER_READTIMEOUT:
$read_now = microtime(true);
$t_read = $read_now - $read_start;
if ($t_read <= $this->_params['read_timeout']) {
break;
}

$this->_temp['logout'] = true;
$this->logout();
throw $e;
}

/* For all other issues, catch and store exception; don't
Expand Down
8 changes: 4 additions & 4 deletions lib/Horde/Imap/Client/Socket/Connection/Socket.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,12 @@ public function read($size = null)

$read_now = microtime(true);
$t_read = $read_now - $read_start;
if ($t_read > $this->_params['read_timeout']) {
if ($t_read > $this->_params['timeout']) {
$this->_params['debug']->info(sprintf('ERROR: read timeout. No data received for %d seconds.', $this->_params['read_timeout']));

throw new Horde_Imap_Client_Exception(
Horde_Imap_Client_Translation::r("Read timeout."),
Horde_Imap_Client_Exception::DISCONNECT
Horde_Imap_Client_Exception::SERVER_READTIMEOUT
);
}

Expand Down Expand Up @@ -237,10 +237,10 @@ public function read($size = null)
} while (true);

if (!$got_data) {
$this->_params['debug']->info('ERROR: read/timeout error.');
$this->_params['debug']->info('ERROR: read timeout error.');
throw new Horde_Imap_Client_Exception(
Horde_Imap_Client_Translation::r("Error when communicating with the mail server."),
Horde_Imap_Client_Exception::SERVER_READERROR
Horde_Imap_Client_Exception::SERVER_READTIMEOUT
);
}

Expand Down

0 comments on commit 0bf16a5

Please sign in to comment.