Changeset 4601 in subversion


Ignore:
Timestamp:
Mar 9, 2011 5:30:15 AM (2 years ago)
Author:
alec
Message:
  • Add code for prevention from IMAP connection hangs when server closes socket unexpectedly
Location:
trunk/roundcubemail
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/CHANGELOG

    r4599 r4601  
    22=========================== 
    33 
     4- Add code for prevention from IMAP connection hangs when server closes socket unexpectedly 
    45- Remove redundant DELETE query (for old session deletion) on login 
    56- Get around unreliable rand() and mt_rand() in session ID generation (#1486281) 
  • trunk/roundcubemail/program/include/rcube_imap_generic.php

    r4592 r4601  
    214214        $line = ''; 
    215215 
    216         if (!$this->fp) { 
    217             return NULL; 
    218         } 
    219  
    220216        if (!$size) { 
    221217            $size = 1024; 
     
    223219 
    224220        do { 
    225             if (feof($this->fp)) { 
     221            if ($this->eof()) { 
    226222                return $line ? $line : NULL; 
    227223            } 
     
    230226 
    231227            if ($buffer === false) { 
    232                 @fclose($this->fp); 
    233                 $this->fp = null; 
     228                $this->closeSocket(); 
    234229                break; 
    235230            } 
     
    238233            } 
    239234            $line .= $buffer; 
    240         } while ($buffer[strlen($buffer)-1] != "\n"); 
     235        } while (substr($buffer, -1) != "\n"); 
    241236 
    242237        return $line; 
     
    268263        $data = ''; 
    269264        $len  = 0; 
    270         while ($len < $bytes && !feof($this->fp)) 
     265        while ($len < $bytes && !$this->eof()) 
    271266        { 
    272267            $d = fread($this->fp, $bytes-$len); 
     
    313308                $this->errornum = self::ERROR_BAD; 
    314309            } else if ($res == 'BYE') { 
    315                 @fclose($this->fp); 
    316                 $this->fp = null; 
     310                $this->closeSocket(); 
    317311                $this->errornum = self::ERROR_BYE; 
    318312            } 
     
    340334    } 
    341335 
     336    private function eof() 
     337    { 
     338        if (!is_resource($this->fp)) { 
     339            return true; 
     340        } 
     341 
     342        // If a connection opened by fsockopen() wasn't closed 
     343        // by the server, feof() will hang. 
     344        $start = microtime(true); 
     345 
     346        if (feof($this->fp) ||  
     347            ($this->prefs['timeout'] && (microtime(true) - $start > $this->prefs['timeout'])) 
     348        ) { 
     349            $this->closeSocket(); 
     350            return true; 
     351        } 
     352 
     353        return false; 
     354    } 
     355 
     356    private function closeSocket() 
     357    { 
     358        @fclose($this->fp); 
     359        $this->fp = null; 
     360    } 
     361 
    342362    function setError($code, $msg='') 
    343363    { 
     
    361381        if ($error && preg_match('/^\* (BYE|BAD) /i', $string, $m)) { 
    362382            if (strtoupper($m[1]) == 'BYE') { 
    363                 @fclose($this->fp); 
    364                 $this->fp = null; 
     383                $this->closeSocket(); 
    365384            } 
    366385            return true; 
     
    702721        } 
    703722 
     723        if ($this->prefs['timeout'] <= 0) { 
     724            $this->prefs['timeout'] = ini_get('default_socket_timeout'); 
     725        } 
     726 
    704727        // Connect 
    705         if ($this->prefs['timeout'] > 0) 
    706             $this->fp = @fsockopen($host, $this->prefs['port'], $errno, $errstr, $this->prefs['timeout']); 
    707         else 
    708             $this->fp = @fsockopen($host, $this->prefs['port'], $errno, $errstr); 
     728        $this->fp = @fsockopen($host, $this->prefs['port'], $errno, $errstr, $this->prefs['timeout']); 
    709729 
    710730        if (!$this->fp) { 
     
    849869        } 
    850870 
    851         @fclose($this->fp); 
    852         $this->fp = false; 
     871        $this->closeSocket(); 
    853872    } 
    854873 
Note: See TracChangeset for help on using the changeset viewer.