Changeset 2072 in subversion


Ignore:
Timestamp:
Nov 20, 2008 3:10:03 PM (5 years ago)
Author:
alec
Message:
  • optimize iil_C_FetchHeaders() to use only one FETCH command
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/program/lib/imap.inc

    r2069 r2072  
    7373                - fix iil_C_FetchPartHeader() in some cases by use of iil_C_HandlePartBody() 
    7474                - allow iil_C_HandlePartBody() to fetch whole message 
     75                - optimize iil_C_FetchHeaders() to use only one FETCH command 
    7576 
    7677********************************************************/ 
     
    16111612        global $IMAP_USE_INTERNAL_DATE; 
    16121613         
    1613         $c      = 0; 
    16141614        $result = array(); 
    16151615        $fp     = $conn->fp; 
     
    16491649        } 
    16501650 
    1651         /* FETCH date,from,subject headers */ 
    1652         $key      = 'fh' . ($c++); 
    1653         $prefix   = $uidfetch?' UID':''; 
    1654         $request  = $key . $prefix; 
    1655         $request .= " FETCH $message_set (BODY.PEEK[HEADER.FIELDS "; 
     1651        /* FETCH uid, size, flags and headers */ 
     1652        $key      = 'FH12'; 
     1653        $request  = $key . ($uidfetch ? ' UID' : '') . " FETCH $message_set "; 
     1654        $request .= "(UID RFC822.SIZE FLAGS INTERNALDATE BODY.PEEK[HEADER.FIELDS "; 
    16561655        $request .= "(DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC "; 
    16571656        $request .= "CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID "; 
     
    16621661        } 
    16631662        do { 
    1664                 $line = chop(iil_ReadLine($fp, 200)); 
     1663                $line = chop(iil_ReadLine($fp, 1024)); 
    16651664                $a    = explode(' ', $line); 
    16661665                if (($line[0] == '*') && ($a[2] == 'FETCH')) { 
     
    16731672 
    16741673                        /* 
     1674                            Sample reply line: 
     1675                            * 321 FETCH (UID 2417 RFC822.SIZE 2730 FLAGS (\Seen) 
     1676                            INTERNALDATE "16-Nov-2008 21:08:46 +0100" BODY[HEADER.FIELDS ... 
     1677                        */ 
     1678                         
     1679                        if (preg_match('/^\* [0-9]+ FETCH \((.*) BODY\[HEADER/', $line, $matches)) { 
     1680                                $str = $matches[1]; 
     1681 
     1682                                //swap parents with quotes, then explode 
     1683                                $str = eregi_replace("[()]", "\"", $str); 
     1684                                $a = iil_ExplodeQuotedString(' ', $str); 
     1685 
     1686                                //did we get the right number of replies? 
     1687                                $parts_count = count($a); 
     1688                                if ($parts_count>=8) { 
     1689                                        for ($i=0; $i<$parts_count; $i=$i+2) { 
     1690                                                if (strcasecmp($a[$i],'UID') == 0) 
     1691                                                        $result[$id]->uid = $a[$i+1]; 
     1692                                                else if (strcasecmp($a[$i],'RFC822.SIZE') == 0) 
     1693                                                        $result[$id]->size = $a[$i+1]; 
     1694                                                else if (strcasecmp($a[$i],'INTERNALDATE') == 0) 
     1695                                                        $time_str = $a[$i+1]; 
     1696                                                else if (strcasecmp($a[$i],'FLAGS') == 0) 
     1697                                                        $flags_str = $a[$i+1]; 
     1698                                        } 
     1699 
     1700                                        // process flags 
     1701                                        $flags_str = eregi_replace('[\\\"]', '', $flags_str); 
     1702                                        $flags_a   = explode(' ', $flags_str); 
     1703                                         
     1704                                        if (is_array($flags_a)) { 
     1705                                                reset($flags_a); 
     1706                                                while (list(,$val)=each($flags_a)) { 
     1707                                                        if (strcasecmp($val,'Seen') == 0) { 
     1708                                                            $result[$id]->seen = true; 
     1709                                                        } else if (strcasecmp($val, 'Deleted') == 0) { 
     1710                                                            $result[$id]->deleted=true; 
     1711                                                        } else if (strcasecmp($val, 'Recent') == 0) { 
     1712                                                            $result[$id]->recent = true; 
     1713                                                        } else if (strcasecmp($val, 'Answered') == 0) { 
     1714                                                            $result[$id]->answered = true; 
     1715                                                        } else if (strcasecmp($val, '$Forwarded') == 0) { 
     1716                                                            $result[$id]->forwarded = true; 
     1717                                                        } else if (strcasecmp($val, 'Draft') == 0) { 
     1718                                                            $result[$id]->is_draft = true; 
     1719                                                        } else if (strcasecmp($val, '$MDNSent') == 0) { 
     1720                                                            $result[$id]->mdn_sent = true; 
     1721                                                        } else if (strcasecmp($val, 'Flagged') == 0) { 
     1722                                                             $result[$id]->flagged = true; 
     1723                                                        } 
     1724                                                } 
     1725                                                $result[$id]->flags = $flags_a; 
     1726                                        } 
     1727 
     1728                                        $time_str = str_replace('"', '', $time_str); 
     1729                                         
     1730                                        // if time is gmt... 
     1731                                        $time_str = str_replace('GMT','+0000',$time_str); 
     1732                                         
     1733                                        //get timezone 
     1734                                        $time_str      = substr($time_str, 0, -1); 
     1735                                        $time_zone_str = substr($time_str, -5); // extract timezone 
     1736                                        $time_str      = substr($time_str, 1, -6); // remove quotes 
     1737                                        $time_zone     = (float)substr($time_zone_str, 1, 2); // get first two digits 
     1738                         
     1739                                        if ($time_zone_str[3] != '0') { 
     1740                                                 $time_zone += 0.5;  //handle half hour offset 
     1741                                        } 
     1742                                        if ($time_zone_str[0] == '-') { 
     1743                                                $time_zone = $time_zone * -1.0; //minus? 
     1744                                        } 
     1745                                         
     1746                                        //calculate timestamp 
     1747                                        $timestamp     = strtotime($time_str); //return's server's time 
     1748                                        $timestamp    -= $time_zone * 3600; //compensate for tz, get GMT 
     1749                                         
     1750                                        $result[$id]->internaldate = $time_str; 
     1751                                        $result[$id]->timestamp = $timestamp; 
     1752                                        $result[$id]->date = $time_str; 
     1753                                } 
     1754                        } 
     1755 
     1756                        /* 
    16751757                                Start parsing headers.  The problem is, some header "lines" take up multiple lines. 
    16761758                                So, we'll read ahead, and if the one we're reading now is a valid header, we'll 
     
    16781760                                to the next valid header line. 
    16791761                        */ 
     1762         
    16801763                        $i     = 0; 
    16811764                        $lines = array(); 
    16821765                        do { 
    16831766                                $line = chop(iil_ReadLine($fp, 300), "\r\n"); 
     1767 
    16841768                                if (ord($line[0])<=32) { 
    16851769                                    $lines[$i] .= (empty($lines[$i])?'':"\n").trim($line); 
     
    16901774                                /*  
    16911775                                        The preg_match below works around communigate imap, which outputs " UID <number>)". 
    1692                                         Without this, the while statement continues on and gets the "fh0 OK completed" message. 
     1776                                        Without this, the while statement continues on and gets the "FH0 OK completed" message. 
    16931777                                        If this loop gets the ending message, then the outer loop does not receive it from radline on line 1249.   
    16941778                                        This in causes the if statement on line 1278 to never be true, which causes the headers to end up missing 
     
    17031787                        // patch from "Maksim Rubis" <siburny@hotmail.com> 
    17041788                        } while (trim($line[0]) != ')' && strncmp($line, $key, strlen($key))); 
    1705                          
     1789 
    17061790                        if (strncmp($line, $key, strlen($key))) {  
    17071791                                //process header, fill iilBasicHeader obj. 
     
    17231807                                        switch ($field) { 
    17241808                                        case 'date'; 
    1725                                                 $result[$id]->date = $string; 
    1726                                                 $result[$id]->timestamp = iil_StrToTime($string); 
     1809                                                if (!$IMAP_USE_INTERNAL_DATE) { 
     1810                                                        $result[$id]->date = $string; 
     1811                                                        $result[$id]->timestamp = iil_StrToTime($string); 
     1812                                                } 
    17271813                                                break; 
    17281814                                        case 'from': 
     
    17771863                                        } // end switch () 
    17781864                                } // end while () 
     1865                 
     1866                                if ($conn->do_cache) { 
     1867                                        $uid = $result[$id]->uid; 
     1868                                        $conn->cache[$mailbox][$uid] = $result[$id]; 
     1869                                        $conn->cache_dirty[$mailbox] = true; 
     1870                                } 
    17791871                        } else { 
    17801872                                $a = explode(' ', $line); 
     
    17831875        } while (strcmp($a[0], $key) != 0); 
    17841876 
    1785         /*  
    1786                 FETCH uid, size, flags 
    1787                 Sample reply line: "* 3 FETCH (UID 2417 RFC822.SIZE 2730 FLAGS (\Seen \Deleted))" 
    1788         */ 
    1789         $command_key = 'fh' . ($c++); 
    1790         $request     = $command_key . $prefix; 
    1791         $request    .= " FETCH $message_set (UID RFC822.SIZE FLAGS INTERNALDATE)"; 
    1792          
    1793         if (!iil_PutLine($fp, $request)) { 
    1794             return false; 
    1795         } 
    1796         do { 
    1797                 $line = chop(iil_ReadLine($fp, 200)); 
    1798                 //$a = explode(' ', $line); 
    1799                 //if (($line[0]=="*") && ($a[2]=="FETCH")) { 
    1800                 if ($line[0] == '*') { 
    1801                         //echo "<!-- $line //-->\n"; 
    1802                         //get outter most parens 
    1803                         $open_pos = strpos($line, "(") + 1; 
    1804                         $close_pos = strrpos($line, ")"); 
    1805                         if ($open_pos && $close_pos) { 
    1806                                 //extract ID from pre-paren 
    1807                                 $pre_str = substr($line, 0, $open_pos); 
    1808                                 $pre_a = explode(' ', $line); 
    1809                                 $id = $pre_a[1]; 
    1810                                  
    1811                                 //get data 
    1812                                 $len = $close_pos - $open_pos; 
    1813                                 $str = substr($line, $open_pos, $len); 
    1814                                  
    1815                                 //swap parents with quotes, then explode 
    1816                                 $str = eregi_replace("[()]", "\"", $str); 
    1817                                 $a = iil_ExplodeQuotedString(' ', $str); 
    1818                                  
    1819                                 //did we get the right number of replies? 
    1820                                 $parts_count = count($a); 
    1821                                 if ($parts_count>=8) { 
    1822                                         for ($i=0;$i<$parts_count;$i=$i+2) { 
    1823                                                 if (strcasecmp($a[$i],"UID") == 0) $result[$id]->uid=$a[$i+1]; 
    1824                                                 else if (strcasecmp($a[$i],"RFC822.SIZE") == 0) $result[$id]->size=$a[$i+1]; 
    1825                                                 else if (strcasecmp($a[$i],"INTERNALDATE") == 0) $time_str = $a[$i+1]; 
    1826                                                 else if (strcasecmp($a[$i],"FLAGS") == 0) $flags_str = $a[$i+1]; 
    1827                                         } 
    1828  
    1829                                         // process flags 
    1830                                         $flags_str = eregi_replace('[\\\"]', '', $flags_str); 
    1831                                         $flags_a   = explode(' ', $flags_str); 
    1832                                          
    1833                                         if (is_array($flags_a)) { 
    1834                                                 reset($flags_a); 
    1835                                                 while (list($key,$val)=each($flags_a)) { 
    1836                                                         if (strcasecmp($val,'Seen') == 0) { 
    1837                                                             $result[$id]->seen = true; 
    1838                                                         } else if (strcasecmp($val, 'Deleted') == 0) { 
    1839                                                             $result[$id]->deleted=true; 
    1840                                                         } else if (strcasecmp($val, 'Recent') == 0) { 
    1841                                                             $result[$id]->recent = true; 
    1842                                                         } else if (strcasecmp($val, 'Answered') == 0) { 
    1843                                                             $result[$id]->answered = true; 
    1844                                                         } else if (strcasecmp($val, '$Forwarded') == 0) { 
    1845                                                             $result[$id]->forwarded = true; 
    1846                                                         } else if (strcasecmp($val, 'Draft') == 0) { 
    1847                                                             $result[$id]->is_draft = true; 
    1848                                                         } else if (strcasecmp($val, '$MDNSent') == 0) { 
    1849                                                             $result[$id]->mdn_sent = true; 
    1850                                                         } else if (strcasecmp($val, 'Flagged') == 0) { 
    1851                                                              $result[$id]->flagged = true; 
    1852                                                         } 
    1853                                                 } 
    1854                                                 $result[$id]->flags = $flags_a; 
    1855                                         } 
    1856                          
    1857                                         // if time is gmt...     
    1858                                         $time_str = str_replace('GMT','+0000',$time_str); 
    1859                                          
    1860                                         //get timezone 
    1861                                         $time_str      = substr($time_str, 0, -1); 
    1862                                         $time_zone_str = substr($time_str, -5); //extract timezone 
    1863                                         $time_str      = substr($time_str, 1, -6); //remove quotes 
    1864                                         $time_zone     = (float)substr($time_zone_str, 1, 2); //get first two digits 
    1865                                         if ($time_zone_str[3] != '0') { 
    1866                                             $time_zone += 0.5;  //handle half hour offset 
    1867                                         } 
    1868                                         if ($time_zone_str[0] == '-') { 
    1869                                                 $time_zone = $time_zone * -1.0; //minus? 
    1870                                         } 
    1871                                         $result[$id]->internaldate = $time_str; 
    1872                                          
    1873                                         if ($IMAP_USE_INTERNAL_DATE || empty($result[$id]->date)) { 
    1874                                                 //calculate timestamp 
    1875                                                 $timestamp     = strtotime($time_str); //return's server's time 
    1876                                                 $na_timestamp  = $timestamp; 
    1877                                                 $timestamp    -= $time_zone * 3600; //compensate for tz, get GMT 
    1878                                                  
    1879                                                 $result[$id]->timestamp = $timestamp; 
    1880                                                 $result[$id]->date = $time_str; 
    1881                                         } 
    1882                                                  
    1883                                         if ($conn->do_cache) { 
    1884                                                 $uid = $result[$id]->uid; 
    1885                                                 $conn->cache[$mailbox][$uid] = $result[$id]; 
    1886                                                 $conn->cache_dirty[$mailbox] = true; 
    1887                                         } 
    1888                                         //echo "<!-- ID: $id : $time_str -- local: $na_timestamp (".date("F j, Y, g:i a", $na_timestamp).") tz: $time_zone -- GMT: ".$timestamp." (".date("F j, Y, g:i a", $timestamp).")  //-->\n"; 
    1889                                 } else { 
    1890                                         //echo "<!-- ERROR: $id : $str //-->\n"; 
    1891                                 } 
    1892                         } 
    1893                 } 
    1894         } while (strpos($line, $command_key) === false); 
    1895                  
    18961877        return $result; 
    18971878} 
    18981879 
    18991880function iil_C_FetchHeader(&$conn, $mailbox, $id, $uidfetch=false) { 
    1900         $fp = $conn->fp; 
     1881 
    19011882        $a  = iil_C_FetchHeaders($conn, $mailbox, $id, $uidfetch); 
    19021883        if (is_array($a)) { 
     
    23862367        $fp     = $conn->fp; 
    23872368        $result = false; 
    2388  
     2369         
    23892370        if (iil_C_Select($conn, $mailbox)) { 
    23902371                $reply_key = '* ' . $id; 
Note: See TracChangeset for help on using the changeset viewer.