Issue with CFmail due to it splitting long lines

Using Lucee, I’m running into issues with my HTML emails due to the fact that Lucee is converting text/html for a message into a StringDataSource object, which automatically inserts a new line after 998 characters. This is basically very similar to the following issue:

My problem is my HTML messages contain some minified CSS and the fact that StringDataSource is automatically adding a new line character after 998 characters ends up breaking a CSS rule.

While I understand the code is doing this to comply with the message RFC spec, I would think a better way to deal with this would be convert the code to use “Content-Transfer-Encoding: quoted-printable” for the message part instead of sending it as “Content-Transfer-Encoding: 7bit”. If sent as quoted-printable, it should automatically wrap the content, but it keeps long lines intact. This is what ACF does and we’ve never had an issue with it.

Is there a reason Lucee decided to send HTML as 7bit instead of quoted-printable?

I’d be willing to work on a patch to address the behavior, but don’t want to spend time if it would never be approved for some reason unknown to me.

I’m all for doing this, maybe we can expose a new attribute to control this, for backwards compat etc?


So I had a couple of thoughts:

  1. We could check for to see if the Content-Transfer-Encoding: quoted-printable header was added via cfmailparam and if so, then honor that encoding. This would mean in the SMTPClient code in the fillHTMLText (and fillPlainText?) methods, we’d need to honor that Content-Transfer-Encoding value and then not have the StringDataSource wrap the text.
  2. We could have have a JVM property that toggles whether to use quoted-printable or 7bit for the transfer encoding.
  3. We could add a transferEncoding argument to cfmail and cfmailpart and honor that.

Since I don’t have a newer version of CF to test on, I wonder if ACF still uses quoted-printable. I’d assume they do. So one could argue that using 7bit is a compatibility issue, it should be fixed.

Quite frankly, I’m not sure why 7bit is being enforced—especially on HTML emails. Here’s a good summary on the effects of “Content-Transfer-Encoding”:

By forcing 7bit, that’s going to prevent non-standard ASCII characters from being sent. The quoted-printable encoding was added specifically to handle thinks like HTML that can expand past the 1,000 character limitation.

Quite frankly, I think the best fix would be to just send HTML emails as quoted-printable. That appears to be the only reliable way to make sure that the HTML isn’t broken. I suspect a lot of people run into the issue of HTML being sent in 7bit, but the problem is either swallowed up by how forgiving HTML rendering usually is (i.e. a line break in the middle of an HTML tag isn’t going to affect rendering), but that it sometimes creates very weird problems that are hard to trouble shoot, like links sometimes not working (because a new line was added in the middle of the URL), CSS broken (like what I ran into), etc.

I just don’t see any good reason that HTML would be sent as anything other than quoted-printable. 7bit and 8bit both have the 1,000 line character restriction and Base64 encoding would really inflate the size and make it not readable by a human.

I’ve got WIP PR adding a smtp service to the github actions for 6.0, which could be useful here

We used to use MailCatcher (which Mailhog is based on), but we now use Maildev, which I like a lot better. If you’re having issues with Mailhog, check out Maildev. It has a REST API as well.

interesting! ideally I’d like a mail server which supports TLS connections too for testing

You might be better served by using Greenmail. It supports SSL/TLS.

We use Greenmail for our POP/IMAP testing. It also supports SMTP, but we use Maildev for SMTP catching in our local development servers, so we just stuck with that since we’re familiar with the UI.

It would allow you to test things like CFPOP, CFIMAIL, etc.

1 Like

Since Greenmail is Java-based, it’s really probably the best option. There’s no real UI, it’s all API access as well. Probably much simpler than other solutions.


Did @micstriit have any input on this issue?

Should I fill a bug?

go ahead!

I created: