Whe are using mimemail to format emails and smtp to send them (via mailsystem's custom class MimeMailSystem__SmtpMailSystem.mail.inc)

The body of the email to be sent has images with relative URLs so mimemail uses multipart/related mime type (for including attachments) with a nested multipart/alternative for text-only and html versions.

This would rais an "Empty body" error when trying to send the email. As a workaround, changing URLs to absolute works because there is no multipart/related at all.

We are using:

  • smtp 7.x-1.0-beta2
  • mimemail 7.x-1.0-alpha2
  • mailsystem 7.x-2.34

Comments

simon georges’s picture

simon georges’s picture

simon georges’s picture

Version: 7.x-1.0-beta2 » 7.x-1.x-dev

Could you eventually test the (soon to be released) -dev version, as a few things have been fixed since then?

esclapes’s picture

Status: Active » Closed (cannot reproduce)

I am afraid we cannot reproduce the error anymore.

After some testing we found there was something wrong in the HTML for some nodes, although we could not say what it was. After re-creating all HTML the error went away.

ArtActivator.com’s picture

Priority: Normal » Critical

Subscribing. Still not working. Trying to send a simplenews newsletter with inline images.(using mimemail) Without images all fine.
Can't switch to phpmailer project, beacuse it does not integrates with mailsystem module. But I have logging_alerts installed, and need watchdog messages to be sent with mail() function....

------------------------
www.ArtActivator.com - Order your success

andyg5000’s picture

Issue summary: View changes

This is an old issue, but we're having the same problem with current releases of the same modules. The error in the logs is:

phpmailerException: Message body empty in PHPMailer->Send() (line 577 of /var/www/html/docroot/sites/all/modules/contrib/smtp/smtp.phpmailer.inc)

The resolution for us checking "Link images only" under admin/config/system/mimemail.

From what I can tell, smtp.mail.inc doesn't parse the message (via boundary) properly when processing the message because of the embedded attachments.

Leaving this closed for now, but wanted to post for other's reference.

maxlife58’s picture

I've the same error with current release!
"phpmailerException: Message body empty in PHPMailer->Send() (linea 577 di ....sites/all/modules/smtp/smtp.phpmailer.inc)"

Unfortunately, not everyone will realize the error because when the Logging option is disabled in admin/config/system/smtp (and is disabled by default), the emails seem to be sent correctly but really is never sent!

Please re-open the issue.

Thanks

dippers’s picture

I have the same problem when sending emails using the message module with embedded relative image links.
The body built by message starts:

This is a multi-part message in MIME format.

--88e9c97983d5f0747ffc2f4dddc2903a9f1a11112
Content-Type: multipart/related;
 type="multipart/alternative";
 boundary="ce1f23b0f449ed10f92fc0800dca09c4639a864f1"
Content-Transfer-Encoding: 8bit


--ce1f23b0f449ed10f92fc0800dca09c4639a864f1
Content-Type: multipart/alternative;
 boundary="b27293c180f301298921fe1aa8b8474caad53fc70"
Content-Transfer-Encoding: 8bit


--b27293c180f301298921fe1aa8b8474caad53fc70
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit

The content type in the headers is 'multipart/mixed'. The problem seems to be caused because of the two levels of nested boundaries. Once the message is split on the 'mixed' boundary (--88e9c9) the first body part is recognised as 'multipart/alternative' and split again on the boundary (--ce1f23). This still leaves a 'multipart/alternative' body part with both text/plain and text/html parts. This is then detected as a plaintext message because of the presence of 'plain/text' so the whole body part is put into mailer->AltBody. Because the html part of the message is now in AltBody no part of the message is assigned to mailer->Body and you therefore get the error message from the mailer of 'Empty Body'.

I think the multipart/mixed message handler needs to look for multiple nested multipart/alternative boundaries.

mozh92’s picture

The resolution for us checking "Link images only" under admin/config/system/mimemail.

Many Thanks!

ghadaezzat’s picture

still have this issue any one has a fix for it

mibfire’s picture

It is a serious problem. Why isn't this solved yet? I had to use the following module now: https://www.drupal.org/project/just_smtp

inascon’s picture

Same problem here.
Temporary solution of mozh92 worked for us too, but real solution would be appreciated.

Abelito’s picture

Same here.
solution of mozh92 worked for us too.

spelcheck’s picture

StatusFileSize
new4.19 KB

#2 does allow MIME formatted emails to be sent without destroying them, but if you are needing the images to be embedded we'll need another solution.

I did some debugging and initially posted to https://www.drupal.org/project/mailmime/issues/2848303 until it became clear that deconstructing MIME formatted emails to work with PHPMailer is a tough task. The reason is SMTP doesn't handle nested boundaries well enough, but mostly the problem is that PHPMailer wants to wrap anything sent to 'mailer->Body' as 'text/html'. We can't retain any of the boundaries or content-types from what's produced by MIME, it all needs to be deconstructed.

A solution would be to either extract the MIME encoded attachments from whatever is sent to SMTP as strings, and by 'cid' match the <img> element that is referencing it, then AddEmbeddedImage() them each back to PHPMailer with the corresponding cid OR build some auto-embedding functionality into SMTP itself. The main reason I had been using Mail MIME with HTML Mail was to embed images.

I created a cursory patch to provide auto-embedding of images that are found within the html sent to SMTP, and if the image is hosted locally (whether using relative path OR the hostname matches the current host), it embeds them. Enabling and disabling of this feature is available within the admin page. This is only handling 'text/html' content type, so I'm sure there's plenty more work to be done to make it compatible with every setup. I'm running HTML Mail (without Mail MIME)-> SMTP.

spelcheck’s picture

StatusFileSize
new7.41 KB

Added support for Mime Mail 1.x-dev (with Link images only config option enabled). Tested within rules Send HTML email action with and without attachments. Instead of Mime Mail auto-embedding images, we set (\Link images only as enabled, and SMTP will handle the auto-embedding.

spelcheck’s picture

Title: Empty body error when using multipart/related » Mime Mail -> SMTP with embedded images
Priority: Critical » Major
Status: Closed (cannot reproduce) » Needs review
Related issues: +#2848303: SMTP module breaks multipart structure when images are present.

Initial solution #2 was to use Link images onlyconfig option in Mime Mail to prevent SMTP from receiving properly formatted multipart/related content, which SMTP isn't built to handle gracefully. I submitted a patch that brings image auto-embed into SMTP itself, so that it still plays nice with Mime Mail while keeping auto image-embedding. Opening issue back up for review.

Related to https://www.drupal.org/project/mailmime/issues/2848303, only because the issue relates to MIME formatted email being sent through SMTP.

spelcheck’s picture

With #15 patch, HTML Mail will work with SMTP so long as Mail Mime is not enabled. If using Mime Mail, it has the Link images only option that should be used, which prevents it from auto-embedding inline images before sending it to SMTP. Though many are using Mime Mail or HTML Mail with Mail Mime to auto-embed inline images, this can now be done through SMTP itself. Either of these configurations should work:

  • HTML Mail (without Mail Mime) -> SMTP (patched)
  • Mime Mail (with Link images only option enabled) -> SMTP (patched)
robcarr’s picture

I suppose there's always the option of using the Pathlogic module, to convert all URLs to absolute values. Clearly has a whole site impact, but could be a safe approach for Mime mail and SMTP combinations.

spelcheck’s picture

@robcarr I'm not sure how converting relative image urls to absolute (assuming in text filters) would help with the issue of embedding images when using mimemail upstream of smtp module (or htmlmail with mailmime upstream of smtp module). Whether the images are relative or absolute, mimemail/mailmime will embed them afaik, only to reach smtp module which disassembles the mime encoded email, and in turn breaks the multipart boundaries. Only way I've found to maintain multipart boundaries when these mime-encoded emails are passed to smtp is to prevent the embedding of images before they get to smtp. Totally open to ideas, but hoping to get feedback on #15.

The reason I included logic to determine whether an image is hosted locally was to mitigate abuse, otherwise someone could potentially trigger an email to go out (like a comment approval notification email) with an img src of an enormous remotely hosted image, or worse. This way if someone includes an img src of a remote image, it won't embed it and whoever receives it will be presented with the option to display it.

naurisr’s picture

StatusFileSize
new13.64 KB

#15 works good only if body contains unique images.
Attaching the patch that makes it possible to have the same image multiple times.

gmaximus’s picture

Thanks @spelcheck. #15 works for me.

jparkinson1991’s picture

Patch in #15 working for me.

I am also able to embed the same image twice so unsure as to the need for #20? Unless im missing something.

jparkinson1991’s picture

StatusFileSize
new7.86 KB
new2.42 KB

Patch in #15 blindly preprends '.' to all file paths received during image embed.

Updated patch will only prepend the '.' when the file is known to exist within the DRUPAL_ROOT

This enables use of absolute file paths and also those outside of the public root directory (i.e. private files)

Note: That this patch does not build on #20, instead using #15 as it's base. Interdiff provided.

Note 2: Replaced by patch #26

jparkinson1991’s picture

Just a quick note from me on users who are finding that images are not autoembedded as expected when sending mail via queue (either default send queue or retry error queue) and using drush to execute invocation of these queues.

Chances are, Drush is unable to correctly determine the $base_url, thus when that base_url is checked against the host from the image path, they don't match, and auto embed of images is not triggered.

/**
  * @file smtp.mail.inc
  */

protected function _embed_local_images(&$body, $mailer) {
    ...

    if (count($found) > 0) {
      // In a drush context $my_host may equal 'http://default' or http://[multisite-directory-name]
      global $base_url;
      $my_host = parse_url($base_url, PHP_URL_HOST);

      foreach ($found as $index => $image) {
        $src = $image->getAttribute('src');
        $path = parse_url($src, PHP_URL_PATH);
        $host = parse_url($src, PHP_URL_HOST);

        // Check wont evaluate to true where $my_host not evalutated correctly
        if (!($host) || $host == $my_host) {
            // HANDLE AUTO EMBED HERE
        }
}

To fix this, when invoking queues via cron, if not already doing so ensure the --uri flag is passed with the expected host value.

I was using ultimate cron to invoke the queues, so the following changes were needed from me.

$ cd /my_site/sites/subsite.co.uk && /usr/local/bin/drush cron-run

to

$ cd /my_site/sites/subsite.co.uk && /usr/local/bin/drush --uri=http://mysubmit.localhost cron-run
jparkinson1991’s picture

StatusFileSize
new8.67 KB
new4.38 KB

Replaced by #26 due to leading whitespace in patch filename.

jparkinson1991’s picture

StatusFileSize
new8.67 KB
new4.38 KB

Updated patch to replace #23.

As with #23, patch builds on #15 and absolute local files outside of Drupal root still embedded.

Added host sanitisation prior to site host and image host comparisons. Fixes non-embed scenarios where image host is www.myhost.com and site host as resolved from $base_url is myhost.com

Interdiff with #15 provided.

bluegeek9’s picture

Status: Needs review » Closed (outdated)
//www.flaticon.com/free-icons/thank-you Thank you for your contribution!

Unfortunately, Drupal 7 is End of Life and no longer supported. We strongly encourage you to upgrade to a supported version of Drupal.

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.