WordPress.org

Make WordPress Core

Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#31653 closed defect (bug) (duplicate)

Two content types are added when sending multipart email messages

Reported by: christinecooper Owned by:
Milestone: Priority: normal
Severity: critical Version: 4.1.1
Component: Mail Keywords:
Focuses: Cc:
PR Number:

Description

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@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@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 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 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 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.

Change History (5)

#1 follow-up: @jasonhendriks
5 years ago

Or perhaps the problem is less wide-spread because most users (especially those with large mailing lists) install SMTP plugins which redefine the default wp_mail?

#2 in reply to: ↑ 1 ; follow-up: @christinecooper
5 years ago

  • Severity changed from normal to critical

Replying to jasonhendriks:

Or perhaps the problem is less wide-spread because most users (especially those with large mailing lists) install SMTP plugins which redefine the default wp_mail?

I understand why you can say that when being a plugin developer of one yourself, but this doesn't make this bug any less current and severe. Additionally, this is a ticket system to report bugs for core WP files, which this is.

Last edited 5 years ago by christinecooper (previous) (diff)

#3 in reply to: ↑ 2 @jasonhendriks
5 years ago

I don't disagree.

#4 @SergeyBiryukov
5 years ago

  • Component changed from General to Mail
  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #15448.

#5 @SergeyBiryukov
5 years ago

  • Summary changed from Two content types are added when sending mutlipart email messages to Two content types are added when sending multipart email messages
Note: See TracTickets for help on using tickets.