BF on CF
A Better
A Better
Sep. 11, 2003 12:00 AM
One of the most used tags in CFML is <CFMAIL>. It is
definitely the most used of all the Internet protocol tags, and as
one of the original CFML tags (it was actually one of the DBML tags
and originally named <DBMAIL>), it has also been slowly enhanced and
updated with each new release of ColdFusion. Slowly. Maybe a little
too slowly.
ColdFusion MX 6.1 introduces a whole new <CFMAIL>, a much
better and much more powerful <CFMAIL>, and this month I'd like to
walk you through these important changes.
Improved Performance
Let's start with performance. <CFMAIL> was never designed to
be a high-performance mass mailer, and yet many developers have tried
using it as just that. <CFMAIL> has always been very capable of
delivering hundreds, even thousands, of messages, but that's about as
far as the tag could be pushed.
ColdFusion MX 6.1 introduces important changes to the
<CFMAIL> engine that facilitate dramatically increased mail-delivery
performance. In fact, in testing, we clocked <CFMAIL> on a fairly
typical box delivering mail at over 1,000,000 messages an hour (so
fast that the bottleneck became the network and mail server rather
than ColdFusion).
So what changed? Two things:
The ColdFusion mail delivery engine now supports the use of
multiple mail delivery threads. What this means is simply that
ColdFusion can create multiple processes, and each can deliver mail
at the same time. So, instead of just one thread processing all
queued mail, multiple threads can do the job, and that translates
into greater mail throughout. The number of threads defaults to 10,
but you can change this number in the ColdFusion Administrator. Each
thread requires system resources (some memory and a bit of CPU
power), but the overhead is actually minimal and only present during
mail delivery itself. As such, if you need to deliver large amounts
of e-mail quickly you can raise this number as needed; the greater
the number of threads ColdFusion can allocate, the more mail it can
deliver concurrently. (The number specified is a maximum value;
ColdFusion may actually allocate fewer threads if there's not enough
queued mail to warrant all threads being allocated.)
When ColdFusion delivers mail, it connects to an SMTP server
and disconnects when done. It does this for each and every message.
And the process of locating the server, opening the connection, and
then closing it when done, often takes longer than the actual mail
delivery. Or rather, ColdFusion used to do this. In ColdFusion MX 6.1
there is a new option (in the ColdFusion Administrator) named
"Maintain connection to SMTP server", and when checked, ColdFusion
keeps connections open so as to be able to reuse them for subsequent
message delivery. Not having to keep making and breaking connections
improves the delivery time for each and every message, so unless you
have a very compelling reason not to, you should keep this checkbox
checked.
<CFMAIL> performance has been improved in all versions of
ColdFusion, but if you need high-volume mail delivery, then you
should be using ColdFusion MX Enterprise. The two changes just
described apply to ColdFusion MX Enterprise only.
Server Redundancy
One frequently requested <CFMAIL> enhancement is support for
backup SMTP servers so that if a mail server is down, a backup SMTP
server would be used. Support for redundant (backup) SMTP servers has
been added to ColdFusion MX 6.1 Enterprise (this too is an
Enterprise-only feature).
ColdFusion Administrator contains a new field (in the Mail
page) named "Backup mail servers". You may specify as many servers as
you like here (DNS names or IP addresses) in a comma-delimited format
(you may also list backup servers right in the <CFMAIL> tag SERVER
attribute). The specified servers are the backup servers, and will be
used automatically if the primary SMTP server is unavailable.
It is important to note that <CFMAIL> does not support
multiple mail server delivery. These additional servers are backup
servers and are used only if the primary server is unavailable. If a
server (any server) is unavailable, then ColdFusion will attempt to
use the next server in the list. Once a server has been flagged as
unavailable, ColdFusion will not attempt to use it again for 60
seconds. If all servers are unavailable, then an error is logged.
Like the high-performance features discussed above, the
ability to specify backup SMTP servers is an Enterprise-only feature.
(From this point on, however, everything discussed applies to all
versions of ColdFusion, including ColdFusion MX Standard).
SMTP Security
SMTP was never designed to a be a secure protocol. As we are
all painfully aware, you can never really be sure who mail comes from
and whether or not a FROM field contains the actual sender address.
It's all too easy to submit fake SMTP e-mail to mail servers for
processing.
In recent years, mail administrators have started taking
steps to prevent their servers from being used to deliver
unauthorized mail (commonly known as relaying). One technique that
has gained popularity is to require an SMTP login. Unlike POP, which
always requires a login, SMTP usually does not, but many SMTP servers
now do require that login credentials be passed in in order to
deliver outbound mail. If enabled, this security prevented the use of
<CFMAIL>, as <CFMAIL> provided no way to specify login information.
ColdFusion MX 6.1 supports SMTP logins in two ways:
The <CFMAIL> tag has two new attributes named USERNAME and
PASSWORD. You may pass SMTP login information to these attributes,
and <CFMAIL> will use this information to log in to the SMTP server.
You may also specify login information at the server
definition itself (so as not to have to pass it to every <CFMAIL>
tag). Login information can be specified in the ColdFusion
Administrator as part of the server name. The syntax for this is
modeled on the syntax used by many Web sites: user:password@hostname.
If you specify backup SMTP servers, you'll probably want to provide
the login information for each and every server (assuming that they
all require SMTP logins).
The ability to use SMTP logins is an important enhancement,
and one that will make many server administrators very happy.
Multiple MIME Types
One of the most eagerly anticipated <CFMAIL> enhancements is
the ability to include multiple bodies of different MIME types all in
a single message. What does this mean? Consider the following:
You deliver reports via <CFMAIL>. Your reports are detailed,
have columns, colors and fonts, use images, and more, and so you tell
<CFMAIL> to deliver the e-mail in HTML, as most mail clients,
including Outlook and Outlook Express, support HTML e-mail. The
problem, however, is that not all users have mail clients capable of
displaying HTML e-mail, so you also need to generate a plain-text
version of your report for those users. Of course, this then requires
that you maintain a record of which version to send to which user
(probably a flag in your database). You'd need a way for users to
specify the message type they'd like, and then mail generation code
that might look a bit like this:
<!--- Check HTML mail flag --->
<CFIF user.htmlmail>
<!--- Send HTML version --->
<CFMAIL TO="..."
FROM="..."
SUBJECT="..."
TYPE="html">
<B>HTML body</B>
</CFMAIL>
<CFELSE>
<!--- Send text version --->
<CFMAIL TO="..."
FROM="..."
SUBJECT="..."
TYPE="text">
Text body
</CFMAIL>
</CFIF>
You'd need to repeat everything, not to mention maintaining
the user mail preferences. You'd also not be able to use the <CFMAIL>
query attribute easily, or you'd need two queries - one for text
message recipients and one for HTML message recipients - and then
you'd need two <CFMAIL> tags (one for each query).
There's a better way to do this. E-mail messages can actually
contain multiple bodies, each of a different MIME type. The problem
is that <CFMAIL> did not support the use of this feature. Until now,
that is. Here's the ColdFusion MX 6.1 version of the previous example:
<!--- Generate mail message --->
<CFMAIL TO="..."
FROM="..."
SUBJECT="...">
<!--- Generate text body --->
<CFMAILPART TYPE="text">
Text body goes here
</CFMAILPART>
<!--- Generate HTML body --->
<CFMAILPART TYPE="html">
<B>HTML body goes here</B>
</CFMAILPART>
</CFMAIL>
As you can see, a single <CFMAIL> tag is being used along
with two instances of a new tag named <CFMAILPART>. This new tag
allows you to embed multiple bodies in a single message, as long as
each has a different MIME type. This way it is the mail client that
decides which body to display, and this makes your life a bit
simpler. (It also means that your mail messages will be bigger;
you'll need to decide whether or not this is acceptable.)
Any and all MIME types are supported, although in practice
you'll probably use only TEXT and HTML.
Note: Although we're just covering <CFMAIL> in this column,
it's worth noting that <CFPOP> has been similarly enhanced and now
supports the retrieval of multiple bodies as well.
Other Enhancements
In addition to all the changes listed thus far, <CFMAIL> also
features lots of little enhancements. Some worth noting are:
A new REPLYTO attribute, which can be used to specify the
e-mail address to which replies should be sent (previously replies
would have been sent to the FROM address).
A new FAILTO attribute, which can be used to specify the
address to which SMTP delivery failure notifications should be sent.
This is an important attribute for mailing list-type applications.
A new CHARSET attribute, which can be used to specify the
character encoding to be used for the mail message (overriding the
default encoding specified in the ColdFusion Administrator). This
attribute is present in both <CFMAIL> and <CFMAILPART>.
A new WRAPTEXT attribute, which can be used to force a wrap
(a line break) at a specified location within text messages. This
attribute is present in both <CFMAIL> and <CFMAILPART>.
A new TYPE attribute in <CFMAILPARAM>, which can be used to
specify the MIME type of file attachments.
Conclusion
<CFMAIL> is an important ColdFusion tag and ranks as one of
the most used tags in the CFML language. For high performance and
high-availability mail delivery you should definitely consider using
ColdFusion MX Enterprise. For all users, the enhancements to this tag
in ColdFusion MX 6.1 provide yet another compelling reason to upgrade.
* * *
On a totally separate note, this is my 50th CFDJ <BF> on <CF>
column - that's 50 back-to-back columns (with only one exception,
and I'll try not to let that happen again). While writing this
column, I glanced at the topics covered since way back when, and was
reminded of just how far ColdFusion has come in such a short time.
It's been a great ride thus far, here's to another 50!
About Ben FortaBen Forta is Adobe's Senior Technical Evangelist. In that capacity he spends a considerable amount of time talking and writing about Adobe products (with an emphasis on ColdFusion and Flex), and providing feedback to help shape the future direction of the products. By the way, if you are not yet a ColdFusion user, you should be. It is an incredible product, and is truly deserving of all the praise it has been receiving. In a prior life he was a ColdFusion customer (he wrote one of the first large high visibility web sites using the product) and was so impressed he ended up working for the company that created it (Allaire). Ben is also the author of books on ColdFusion, SQL, Windows 2000, JSP, WAP, Regular Expressions, and more. Before joining Adobe (well, Allaire actually, and then Macromedia and Allaire merged, and then Adobe bought Macromedia) he helped found a company called Car.com which provides automotive services (buy a car, sell a car, etc) over the Web. Car.com (including Stoneage) is one of the largest automotive web sites out there, was written entirely in ColdFusion, and is now owned by Auto-By-Tel.