Changeset 511 in subversion


Ignore:
Timestamp:
Mar 19, 2007 6:36:24 PM (6 years ago)
Author:
thomasb
Message:

Correctly parse message/rfc822; fixed html2text conversion; code cleanup

Location:
trunk/roundcubemail
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/CHANGELOG

    r510 r511  
    11CHANGELOG RoundCube Webmail 
    22--------------------------- 
     3 
     42007/03/19 (thomasb) 
     5---------- 
     6- Don't download HTML message parts 
     7- Convert HTML parts to plaintext if 'prefer_html' is off 
     8- Correctly parse message/rfc822 parts (closes #1484045) 
     9- Code cleanup 
     10 
    311 
    4122007/03/18 (thomasb) 
  • trunk/roundcubemail/program/include/rcube_imap.inc

    r507 r511  
    989989      return FALSE; 
    990990 
    991         $structure_str = iil_C_FetchStructureString($this->conn, $this->mailbox, $msg_id);  
    992         $structure = iml_GetRawStructureArray($structure_str); 
    993         $struct = false; 
    994          
     991    $structure_str = iil_C_FetchStructureString($this->conn, $this->mailbox, $msg_id);  
     992    $structure = iml_GetRawStructureArray($structure_str); 
     993    $struct = false; 
     994 
    995995    // parse structure and add headers 
    996996    if (!empty($structure)) 
     
    10141014        $this->add_message_cache($cache_key, $msg_id, $headers, $struct); 
    10151015      } 
    1016          
    1017         return $struct; 
    1018         } 
     1016       
     1017    return $struct; 
     1018    } 
    10191019 
    10201020   
     
    10481048        if (is_array($part[$i]) && count($part[$i]) > 5) 
    10491049          $struct->parts[] = $this->_structure_part($part[$i], ++$count, $struct->mime_id); 
    1050  
    1051       return $struct;       
     1050           
     1051      return $struct; 
    10521052      } 
    10531053     
     
    10571057    $struct->ctype_secondary = strtolower($part[1]); 
    10581058    $struct->mimetype = $struct->ctype_primary.'/'.$struct->ctype_secondary; 
    1059          
     1059 
    10601060    // read content type parameters 
    1061         if (is_array($part[2])) 
    1062           { 
    1063           $struct->ctype_parameters = array(); 
     1061    if (is_array($part[2])) 
     1062      { 
     1063      $struct->ctype_parameters = array(); 
    10641064      for ($i=0; $i<count($part[2]); $i+=2) 
    10651065        $struct->ctype_parameters[strtolower($part[2][$i])] = $part[2][$i+1]; 
     
    10671067      if (isset($struct->ctype_parameters['charset'])) 
    10681068        $struct->charset = $struct->ctype_parameters['charset']; 
    1069           } 
    1070            
    1071         // read content encoding 
    1072         if (!empty($part[5]) && $part[5]!='NIL') 
    1073           { 
    1074           $struct->encoding = strtolower($part[5]); 
    1075           $struct->headers['content-transfer-encoding'] = $struct->encoding; 
    1076           } 
    1077            
    1078         // get part size 
    1079         if (!empty($part[6]) && $part[6]!='NIL') 
    1080           $struct->size = intval($part[6]); 
    1081  
    1082         // read part disposition 
     1069      } 
     1070     
     1071    // read content encoding 
     1072    if (!empty($part[5]) && $part[5]!='NIL') 
     1073      { 
     1074      $struct->encoding = strtolower($part[5]); 
     1075      $struct->headers['content-transfer-encoding'] = $struct->encoding; 
     1076      } 
     1077     
     1078    // get part size 
     1079    if (!empty($part[6]) && $part[6]!='NIL') 
     1080      $struct->size = intval($part[6]); 
     1081 
     1082    // read part disposition 
    10831083    $di = count($part) - 2; 
    10841084    if ((is_array($part[$di]) && count($part[$di]) == 2 && is_array($part[$di][1])) || 
     
    11001100          $struct->parts[] = $this->_structure_part($part[8][$i], ++$count, $struct->mime_id); 
    11011101      } 
    1102        
    1103         // get part ID 
    1104         if (!empty($part[3]) && $part[3]!='NIL') 
    1105           { 
    1106           $struct->content_id = $part[3]; 
    1107           $struct->headers['content-id'] = $part[3]; 
    1108            
    1109           if (empty($struct->disposition)) 
    1110             $struct->disposition = 'inline'; 
    1111           } 
     1102 
     1103    // get part ID 
     1104    if (!empty($part[3]) && $part[3]!='NIL') 
     1105      { 
     1106      $struct->content_id = $part[3]; 
     1107      $struct->headers['content-id'] = $part[3]; 
     1108     
     1109      if (empty($struct->disposition)) 
     1110        $struct->disposition = 'inline'; 
     1111      } 
    11121112 
    11131113    // fetch message headers if message/rfc822 
     
    11161116      $headers = iil_C_FetchPartBody($this->conn, $this->mailbox, $this->_msg_id, $struct->mime_id.'.HEADER'); 
    11171117      $struct->headers = $this->_parse_headers($headers); 
    1118       } 
    1119    
    1120         return $struct; 
     1118       
     1119      if (is_array($part[8]) && empty($struct->parts)) 
     1120        $struct->parts[] = $this->_structure_part($part[8], ++$count, $struct->mime_id); 
     1121      } 
     1122       
     1123    // normalize filename property 
     1124    if (!empty($struct->d_parameters['filename'])) 
     1125      $struct->filename = $this->decode_mime_string($struct->d_parameters['filename']); 
     1126    else if (!empty($struct->ctype_parameters['name'])) 
     1127      $struct->filename = $this->decode_mime_string($struct->ctype_parameters['name']); 
     1128    else if (!empty($struct->headers['content-description'])) 
     1129      $struct->filename = $this->decode_mime_string($struct->headers['content-description']); 
     1130       
     1131    return $struct; 
    11211132    } 
    11221133     
     
    25112522  var $mimetype = 'text/plain'; 
    25122523  var $disposition = ''; 
     2524  var $filename = ''; 
    25132525  var $encoding = '8bit'; 
    25142526  var $charset = ''; 
  • trunk/roundcubemail/program/lib/html2text.inc

    r392 r511  
    113113        '/<script[^>]*>.*?<\/script>/i',         // <script>s -- which strip_tags supposedly has problems with 
    114114        //'/<!-- .* -->/',                         // Comments -- which strip_tags might have problem a with 
    115         '/<a href="([^"]+)"[^>]*>(.+?)<\/a>/ie', // <a href=""> 
     115        '/<a [^>]*href="([^"]+)"[^>]*>(.+?)<\/a>/ie', // <a href=""> 
    116116        '/<h[123][^>]*>(.+?)<\/h[123]>/ie',      // H1 - H3 
    117117        '/<h[456][^>]*>(.+?)<\/h[456]>/ie',      // H4 - H6 
     
    161161        ' ',                                    // Newlines and tabs 
    162162        '',                                     // <script>s -- which strip_tags supposedly has problems with 
    163         //'',                                     // Comments -- which strip_tags might have problem a with 
     163        //'',                                  // Comments -- which strip_tags might have problem a with 
    164164        '$this->_build_link_list("\\1", "\\2")', // <a href=""> 
    165165        "strtoupper(\"\n\n\\1\n\n\")",          // H1 - H3 
    166         "ucwords(\"\n\n\\1\n\n\")",             // H4 - H6 
    167         "\n",                                   // <P> 
     166        "ucwords(\"\n\n\\1\n\")",               // H4 - H6 
     167        "\n\n",                                 // <P> 
    168168        "\n",                                   // <br> 
    169169        'strtoupper("\\1")',                    // <b> 
     
    256256     *  @return void 
    257257     */ 
    258     function html2text( $source = '', $from_file = false, $do_link_table = true ) 
     258    function html2text( $source = '', $from_file = false, $produce_link_table = true ) 
    259259    { 
    260260        if ( !empty($source) ) { 
  • trunk/roundcubemail/program/steps/mail/compose.inc

    r497 r511  
    402402      $isHtml = false; 
    403403      } 
    404     if (strlen($body)) 
    405       $body = rcmail_create_forward_body($body, $isHtml); 
     404 
     405    $body = rcmail_create_forward_body($body, $isHtml); 
    406406    } 
    407407  else if ($compose_mode == RCUBE_COMPOSE_DRAFT) 
     
    565565 
    566566  // add attachments 
    567   if (!isset($_SESSION['compose']['forward_attachments']) && 
    568       is_array($MESSAGE['parts']) && sizeof($MESSAGE['parts'])>1) 
     567  if (!isset($_SESSION['compose']['forward_attachments']) && is_array($MESSAGE['parts'])) 
    569568    rcmail_write_compose_attachments($MESSAGE); 
    570  
     569     
    571570  return $prefix.$body; 
    572571  } 
     
    599598    if ($part->ctype_primary != 'message' && $part->ctype_primary != 'text' && 
    600599        ($part->disposition=='attachment' || $part->disposition=='inline' || $part->headers['content-id'] || 
    601          (empty($part->disposition) && ($part->d_parameters['filename'] || $part->ctype_parameters['name'])))) 
     600         (empty($part->disposition) && $part->filename))) 
    602601      { 
    603602      $tmp_path = tempnam($temp_dir, 'rcmAttmnt'); 
     
    607606        fclose($fp); 
    608607         
    609         $filename = !empty($part->d_parameters['filename']) ? $part->d_parameters['filename'] : 
    610                      (!empty($part->ctype_parameters['name']) ? $part->ctype_parameters['name'] : 
    611                       (!empty($part->headers['content-description']) ? $part->headers['content-description'] : 'file')); 
    612  
    613608        $_SESSION['compose']['attachments'][] = array( 
    614           'name' => rcube_imap::decode_mime_string($filename), 
    615609          'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary, 
     610          'name' => $part->filename, 
    616611          'path' => $tmp_path 
    617612          ); 
  • trunk/roundcubemail/program/steps/mail/func.inc

    r510 r511  
    728728  $body = is_array($part->replaces) ? strtr($part->body, $part->replaces) : $part->body; 
    729729 
     730  // convert html to text/plain 
     731  if ($part->ctype_secondary=='html' && $plain) 
     732    { 
     733    $txt = new html2text($body, false, true); 
     734    $body = $txt->get_text(); 
     735    $part->ctype_secondary = 'plain'; 
     736    } 
     737     
    730738  // text/html 
    731739  if ($part->ctype_secondary=='html') 
     
    976984      // part is file/attachment 
    977985      else if ($mail_part->disposition=='attachment' || $mail_part->disposition=='inline' || $mail_part->headers['content-id'] || 
    978                (empty($mail_part->disposition) && ($mail_part->d_parameters['filename'] || $mail_part->ctype_parameters['name']))) 
     986               (empty($mail_part->disposition) && $mail_part->filename)) 
    979987        { 
    980988        // skip apple resource forks 
     
    985993        if ($message_ctype_secondary=='related' && $mail_part->headers['content-id']) 
    986994          { 
    987           $mail_part->filename = rcube_imap::decode_mime_string($mail_part->d_parameters['filename']); 
    988995          $mail_part->content_id = preg_replace(array('/^</', '/>$/'), '', $mail_part->headers['content-id']); 
    989996          $sa_inline_objects[] = $mail_part; 
    990997          } 
    991998        // is regular attachment 
    992         else if (($fname = $mail_part->d_parameters['filename']) || 
    993                  ($fname = $mail_part->ctype_parameters['name']) || 
    994                  ($fname = $mail_part->headers['content-description'])) 
    995           { 
    996           $mail_part->filename = rcube_imap::decode_mime_string($fname); 
     999        else if ($mail_part->filename) 
    9971000          $a_attachments[] = $mail_part; 
    998           } 
    9991001        } 
    10001002      } 
     
    10191021 
    10201022  // message is single part non-text 
    1021   else 
    1022     { 
    1023     if (($fname = $structure->d_parameters['filename']) || 
    1024         ($fname = $structure->ctype_parameters['name']) || 
    1025         ($fname = $structure->headers['content-description'])) 
    1026       { 
    1027       $structure->filename = rcube_imap::decode_mime_string($fname); 
    1028       $a_attachments[] = $structure; 
    1029       } 
    1030     } 
     1023  else if ($structure->filename) 
     1024    $a_attachments[] = $structure; 
    10311025 
    10321026  return array($a_return_parts, $a_attachments); 
     
    11371131          $part->body = $IMAP->get_message_part($MESSAGE['UID'], $part->mime_id, $part); 
    11381132 
    1139         $body = rcmail_print_body($part, $safe_mode); 
     1133        $body = rcmail_print_body($part, $safe_mode, !$CONFIG['prefer_html']); 
    11401134        $out .= '<div class="message-part">'; 
    11411135         
    11421136        if ($part->ctype_secondary != 'plain') 
    1143           $out .= rcmail_mod_html_body($body, $attrib['id']); 
     1137          $out .= rcmail_sanitize_html($body, $attrib['id']); 
    11441138        else 
    11451139          $out .= $body; 
     
    11811175 
    11821176// modify a HTML message that it can be displayed inside a HTML page 
    1183 function rcmail_mod_html_body($body, $container_id) 
     1177function rcmail_sanitize_html($body, $container_id) 
    11841178  { 
    11851179  // remove any null-byte characters before parsing 
     
    14531447  $out = '<table '. $attrib_str . ">\n"; 
    14541448   
    1455   $filename = $part->d_parameters['filename'] ? $part->d_parameters['filename'] : $part->ctype_parameters['name']; 
    1456   $filesize = $part->size; 
    1457    
    14581449  if ($filename) 
    14591450    { 
    14601451    $out .= sprintf('<tr><td class="title">%s</td><td>%s</td><td>[<a href="./?%s">%s</a>]</tr>'."\n", 
    14611452                    Q(rcube_label('filename')), 
    1462                     Q(rcube_imap::decode_mime_string($filename)), 
     1453                    Q($part->filename), 
    14631454                    str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING']), 
    14641455                    Q(rcube_label('download'))); 
    14651456    } 
    14661457     
    1467   if ($filesize) 
     1458  if ($part->size) 
    14681459    $out .= sprintf('<tr><td class="title">%s</td><td>%s</td></tr>'."\n", 
    14691460                    Q(rcube_label('filesize')), 
    1470                     show_bytes($filesize)); 
     1461                    show_bytes($part->size)); 
    14711462   
    14721463  $out .= "\n</table>"; 
  • trunk/roundcubemail/program/steps/mail/get.inc

    r506 r511  
    6060    $ctype_primary = strtolower($part->ctype_primary); 
    6161    $ctype_secondary = strtolower($part->ctype_secondary); 
    62  
    6362    $mimetype = sprintf('%s/%s', $ctype_primary, $ctype_secondary); 
    64     $filename = $part->d_parameters['filename'] ? $part->d_parameters['filename'] : $part->ctype_parameters['name']; 
    6563 
    6664    header("Expires: 0"); 
     
    6866    header("Cache-Control: private", false); 
    6967    header("Content-Transfer-Encoding: binary"); 
    70     header(sprintf('Content-Disposition: attachment; filename="%s";', 
    71                    $filename ? rcube_imap::decode_mime_string($filename) : "roundcube.$ctype_secondary")); 
    7268 
    7369    // send download headers 
     
    111107    else 
    112108      { 
     109      header(sprintf('Content-Disposition: %s; filename="%s";', 
     110                     $part->disposition ? $part->disposition : 'attachment', 
     111                     $part->filename ? $part->filename : "roundcube.$ctype_secondary")); 
     112 
    113113      // turn off output buffering and print part content 
    114114      $IMAP->get_message_part($MESSAGE['UID'], $part->mime_id, $part->encoding, true); 
  • trunk/roundcubemail/skins/default/mail.css

    r492 r511  
    629629  background-color: #EBEBEB; 
    630630  table-layout: fixed; 
    631  
     631} 
     632 
     633#messagebody table.headers-table 
     634{ 
     635  width: auto; 
     636  margin: 6px 8px; 
     637  background-color: #F4F4F4; 
     638  border: 1px solid #ccc; 
    632639} 
    633640 
Note: See TracChangeset for help on using the changeset viewer.