浏览代码

Merge branch 'trunk'

Andy 3 年之前
父节点
当前提交
2d4192f3af

+ 4 - 0
class/deliver/Deliver.class.php

@@ -773,6 +773,10 @@ class Deliver {
             /* RFC 2298 */
             $header[] = 'Disposition-Notification-To: '.$dnt. $rn;
         }
+        if ($rfc822_header->dsn) {
+            $dsn = $rfc822_header->getAddr_s('dsn');
+            $header[] = 'Return-Receipt-To: '.$dsn. $rn;
+        }
         if ($rfc822_header->priority) {
             switch($rfc822_header->priority)
             {

+ 33 - 3
class/deliver/Deliver_SMTP.class.php

@@ -411,7 +411,17 @@ class Deliver_SMTP extends Deliver {
         for ($i = 0, $cnt = count($to); $i < $cnt; $i++) {
             if (!$to[$i]->host) $to[$i]->host = $domain;
             if (strlen($to[$i]->mailbox)) {
-                fputs($stream, 'RCPT TO:<'.$to[$i]->mailbox.'@'.$to[$i]->host.">\r\n");
+                // Ask for DSN if user has requested such and remote server supports it
+                if ($rfc822_header->dsn && array_key_exists('DSN',$this->ehlo)) {
+                    // TODO: Make the DSN parameters configurable by admin? user?
+                    fputs($stream, 'RCPT TO:<'.$to[$i]->mailbox.'@'.$to[$i]->host."> NOTIFY=SUCCESS,DELAY,FAILURE\r\n");
+                    // Retry without DSN fields for cranky MTAs
+                    if ($this->errorCheck($tmp, $stream)) {
+                        fputs($stream, 'RCPT TO:<'.$to[$i]->mailbox.'@'.$to[$i]->host.">\r\n");
+                    }
+                }
+                else
+                    fputs($stream, 'RCPT TO:<'.$to[$i]->mailbox.'@'.$to[$i]->host.">\r\n");
                 $tmp = fgets($stream, 1024);
                 if ($this->errorCheck($tmp, $stream)) {
                     return(0);
@@ -422,7 +432,17 @@ class Deliver_SMTP extends Deliver {
         for ($i = 0, $cnt = count($cc); $i < $cnt; $i++) {
             if (!$cc[$i]->host) $cc[$i]->host = $domain;
             if (strlen($cc[$i]->mailbox)) {
-                fputs($stream, 'RCPT TO:<'.$cc[$i]->mailbox.'@'.$cc[$i]->host.">\r\n");
+                // Ask for DSN if user has requested such and remote server supports it
+                if ($rfc822_header->dsn && array_key_exists('DSN',$this->ehlo)) {
+                    // TODO: Make the DSN parameters configurable by admin? user?
+                    fputs($stream, 'RCPT TO:<'.$cc[$i]->mailbox.'@'.$cc[$i]->host."> NOTIFY=SUCCESS,DELAY,FAILURE\r\n");
+                    // Retry without DSN fields for cranky MTAs
+                    if ($this->errorCheck($tmp, $stream)) {
+                        fputs($stream, 'RCPT TO:<'.$cc[$i]->mailbox.'@'.$cc[$i]->host.">\r\n");
+                    }
+                }
+                else
+                    fputs($stream, 'RCPT TO:<'.$cc[$i]->mailbox.'@'.$cc[$i]->host.">\r\n");
                 $tmp = fgets($stream, 1024);
                 if ($this->errorCheck($tmp, $stream)) {
                     return(0);
@@ -433,7 +453,17 @@ class Deliver_SMTP extends Deliver {
         for ($i = 0, $cnt = count($bcc); $i < $cnt; $i++) {
             if (!$bcc[$i]->host) $bcc[$i]->host = $domain;
             if (strlen($bcc[$i]->mailbox)) {
-                fputs($stream, 'RCPT TO:<'.$bcc[$i]->mailbox.'@'.$bcc[$i]->host.">\r\n");
+                // Ask for DSN if user has requested such and remote server supports it
+                if ($rfc822_header->dsn && array_key_exists('DSN',$this->ehlo)) {
+                    // TODO: Make the DSN parameters configurable by admin? user?
+                    fputs($stream, 'RCPT TO:<'.$bcc[$i]->mailbox.'@'.$bcc[$i]->host."> NOTIFY=SUCCESS,DELAY,FAILURE\r\n");
+                    // Retry without DSN fields for cranky MTAs
+                    if ($this->errorCheck($tmp, $stream)) {
+                        fputs($stream, 'RCPT TO:<'.$bcc[$i]->mailbox.'@'.$bcc[$i]->host.">\r\n");
+                    }
+                }
+                else
+                    fputs($stream, 'RCPT TO:<'.$bcc[$i]->mailbox.'@'.$bcc[$i]->host.">\r\n");
                 $tmp = fgets($stream, 1024);
                 if ($this->errorCheck($tmp, $stream)) {
                     return(0);

+ 4 - 4
class/mime/Rfc822Header.class.php

@@ -1,4 +1,4 @@
-`<?php
+<?php
 
 /**
  * Rfc822Header.class.php
@@ -122,10 +122,10 @@ class Rfc822Header {
      */
     var $dnt = '';
     /**
-     * Delivery notification (DR)
+     * Address for requesting message delivery status notification (DSN)
      * @var mixed
      */
-    var $drnt = '';
+    var $dsn = '';
     /**
      * @var mixed
      */
@@ -289,7 +289,7 @@ class Rfc822Header {
                 break;
             case 'return-receipt-to':
                 $value = $this->stripComments($value);
-                $this->drnt = $this->parseAddress($value);
+                $this->dsn = $this->parseAddress($value);
                 break;
             case 'mime-version':
                 $value = $this->stripComments($value);

+ 7 - 0
functions/page_header.php

@@ -188,6 +188,13 @@ function displayHtmlHeader( $title = 'SquirrelMail', $xtra = '', $do_hook = TRUE
         if (!empty($output)) trigger_error('A plugin on the "generic_header" hook has attempted to output directly to the browser', E_USER_ERROR);
     }
 
+    // Add message subject to page title (should only have an effect when loaded in its own browser window/tab)
+    // TODO: For search page, could add " - Search: $what" or something like that
+    global $message;
+    if (!empty($message) && !empty($message->rfc822_header) && !empty($message->rfc822_header->subject))
+        // decodeHeader() should already encode the output, so no sm_encode_html_special_chars()
+        $title .= ' - ' . decodeHeader($message->rfc822_header->subject);
+
     $header_tags .= $xtra;
     $oTemplate->assign('page_title', $title);
 

+ 4 - 5
src/compose.php

@@ -948,7 +948,7 @@ function newMail ($mailbox='', $passed_id='', $passed_ent_id='', $action='', $se
 
                 // Remember the receipt settings
                 $request_mdn = $mdn_user_support && !empty($orig_header->dnt) ? '1' : '0';
-                $request_dr = $mdn_user_support && !empty($orig_header->drnt) ? '1' : '0';
+                $request_dr = $mdn_user_support && !empty($orig_header->dsn) ? '1' : '0';
 
                 /* remember the references and in-reply-to headers in case of an reply */
 //FIXME: it would be better to fiddle with headers inside of the message object or possibly when delivering the message to its destination (drafts folder?); is this possible?
@@ -1781,10 +1781,9 @@ function deliverMessage(&$composeMessage, $draft=false) {
 
     /* Receipt: On Delivery */
     if (!empty($request_dr)) {
-//FIXME: it would be better to fiddle with headers inside of the message object or possibly when delivering the message to its destination; is this possible?
-        $rfc822_header->more_headers['Return-Receipt-To'] = $from_addr;
-    } elseif (isset($rfc822_header->more_headers['Return-Receipt-To'])) {
-        unset($rfc822_header->more_headers['Return-Receipt-To']);
+        $rfc822_header->dsn = $rfc822_header->parseAddress($from_addr,true);
+    } elseif (isset($rfc822_header->dsn)) {
+        unset($rfc822_header->dsn);
     }
 
     /* multipart messages */

+ 7 - 2
src/read_body.php

@@ -145,7 +145,10 @@ function SendMDN ( $mailbox, $passed_id, $message, $imapConnection) {
         $content_type->properties['charset']=$default_charset;
     }
     $rfc822_header->content_type = $content_type;
-    $rfc822_header->to[] = $header->dnt;
+    if (!empty($header->dnt))
+        $rfc822_header->to[] = $header->dnt;
+    else
+        $rfc822_header->to[] = $header->dsn;
     $rfc822_header->subject = _("Read:") . ' ' . decodeHeader($header->subject,true,false);
 
     $idents = get_identities();
@@ -410,7 +413,9 @@ function formatEnvheader($aMailbox, $passed_id, $passed_ent_id, $message,
 
     if ($default_use_mdn) {
         if ($mdn_user_support) {
-            if ($header->dnt) {
+            // We are generous to the sender because DSNs are commonly ignored by servers and
+            // technically offering a return receipt in the MUA for a DSN is overstepping the RFCs
+            if ($header->dnt || $header->dnt) {
                 $mdn_url = $PHP_SELF;
                 $mdn_url = set_url_var($mdn_url, 'mailbox', urlencode($mailbox));
                 $mdn_url = set_url_var($mdn_url, 'passed_id', $passed_id);