[wp-trac] [WordPress Trac] #31653: Two content types are added when sending mutlipart email messages

WordPress Trac noreply at wordpress.org
Mon Mar 16 16:05:55 UTC 2015


#31653: Two content types are added when sending mutlipart email messages
-----------------------------+-----------------------------
 Reporter:  christinecooper  |      Owner:
     Type:  defect (bug)     |     Status:  new
 Priority:  normal           |  Milestone:  Awaiting Review
Component:  General          |    Version:  4.1.1
 Severity:  normal           |   Keywords:
  Focuses:                   |
-----------------------------+-----------------------------
 This has been tested on WP 4.1.1 and on various servers. The bug is
 definitely in core.

 This requires a long explanation but the summary is; when sending
 multipart messages, it outputs the Content Type (multipart/*) twice, once
 with boundary (if customly set) and once without. This behaviour results
 with the email being displayed '''as a raw message''' and not multipart on
 some emails, including all Microsoft (Hotmail, Outlook, etc...)

 To confirm this, simply run the following:


 {{{
 // Set $to to an hotmail.com or outlook.com email
 $to = "YourEmail at hotmail.com";

 $subject = 'wp_mail testing multipart';

 $message = '------=_Part_18243133_1346573420.1408991447668
 Content-Type: text/plain; charset=UTF-8

 Hello world! This is plain text...


 ------=_Part_18243133_1346573420.1408991447668
 Content-Type: text/html; charset=UTF-8

 <html>
 <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 </head>
 <body>

 <p>Hello World! This is HTML...</p>

 </body>
 </html>


 ------=_Part_18243133_1346573420.1408991447668--';

 $headers = "MIME-Version: 1.0\r\n";
 $headers .= "From: Foo <foo at bar.com>\r\n";
 $headers .= 'Content-Type:
 multipart/alternative;boundary="----=_Part_18243133_1346573420.1408991447668"';


 // send email
 wp_mail( $to, $subject, $message, $headers );
 }}}


 And if you want to change the
 [http://codex.wordpress.org/Plugin_API/Filter_Reference/wp_mail_content_type
 default content type], use:


 {{{
 add_filter( 'wp_mail_content_type', 'set_content_type' );
 function set_content_type( $content_type ) {
         return 'multipart/alternative';
 }
 }}}


 So if you check the full source of the message, you will see something
 like [http://pastebin.com/3YbYvrPi this]. You will notice that the content
 type is added twice, once without boundary:


 {{{
 MIME-Version: 1.0
 Content-Type: multipart/alternative;
          boundary="====f230673f9d7c359a81ffebccb88e5d61=="
 MIME-Version: 1.0
 Content-Type: multipart/alternative; charset=

 }}}


 That's the issue.

 The source of the problem lies in pluggable.php - if we look somewhere
 here:


 {{{
 // Set Content-Type and charset
         // If we don't have a content-type from the input headers
         if ( !isset( $content_type ) )
                 $content_type = 'text/plain';

         /**
          * Filter the wp_mail() content type.
          *
          * @since 2.3.0
          *
          * @param string $content_type Default wp_mail() content type.
          */
         $content_type = apply_filters( 'wp_mail_content_type',
 $content_type );

         $phpmailer->ContentType = $content_type;

         // Set whether it's plaintext, depending on $content_type
         if ( 'text/html' == $content_type )
                 $phpmailer->IsHTML( true );

         // If we don't have a charset from the input headers
         if ( !isset( $charset ) )
                 $charset = get_bloginfo( 'charset' );

         // Set the content-type and charset

         /**
          * Filter the default wp_mail() charset.
          *
          * @since 2.3.0
          *
          * @param string $charset Default email charset.
          */
         $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset
 );

         // Set custom headers
         if ( !empty( $headers ) ) {
                 foreach( (array) $headers as $name => $content ) {
                         $phpmailer->AddCustomHeader( sprintf( '%1$s:
 %2$s', $name, $content ) );
                 }

                 if ( false !== stripos( $content_type, 'multipart' ) && !
 empty($boundary) )
                         $phpmailer->AddCustomHeader( sprintf( "Content-
 Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) );
         }

         if ( !empty( $attachments ) ) {
                 foreach ( $attachments as $attachment ) {
                         try {
                                 $phpmailer->AddAttachment($attachment);
                         } catch ( phpmailerException $e ) {
                                 continue;
                         }
                 }
         }
 }}}


 I have researched and found one more thread about this issue
 [https://wordpress.org/support/topic/using-wp_mail-with-php-generated-
 attachments here]. This user provides a hack. While his solution works, it
 breaks emails that do not have custom $headers set.

 This is obviously a severe problem and is currently affecting all WP
 platforms that use wp_mail() to send multipart messages.

 Our mailing list is over 100k and we made a search to check how many of
 these use Microsoft emails (hotmail, outlook, msn, live etc) and it was
 40%+. This is not to say that the problem only affects Microsoft emails,
 but that should be enough.

 The likely reason why this hasn't been reported here earlier is because it
 seems to work fine on gmail, giving the idea that there is no problem
 present, when it is.

--
Ticket URL: <https://core.trac.wordpress.org/ticket/31653>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list