[Looking for Charlie's main web site?]

CF8 Hidden Gem: CFMAIL auto-generated message-id uses specified mail server name

Note: This blog post is from 2007. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Here's a neat hidden gem for CF8 that will delight some: CFMAIL now uses the mail server name you specify in CFMAIL SERVER attribute or the CF Admin mail setup page, in creating the message-id header that's generated when your mail is sent.

Some have lamented that in CFMX 6 and 7, it instead used the name of your server where CF is installed, which might be something like "server1" or "bingo", as in:

Message-ID: <23070863.1197039960343.JavaMail.SYSTEM@Server1>

This might cause a recipient mail server to flag the mail as spam, if the mail server was a different domain name (like "yourcompany.com"). The bummer was that many found no way to fix this. Sure, in CF5 you could set it in a CFMAILPARAM to set a mail header, but CF 6 and above ignores that.

So the good news is that CF8 now does use that CF Admin or CFMAIL SERVER value to create the message-id. If I use CFMAIL SERVER="mail.carehart.org"..., for instance, I might get something like:

Message-ID: <[email protected]>

What about CF 6 or 7?

But what if you're on 6 or 7? Well, there's a solution for you, too, by way of a tweak in the CF startup script (jvm.config) or (less preferably) in code. Since the change for CF 6 or 7 deserves some explanation to do it justice, I'll take that up in a part 2 message next. I'll also lay out the whole problem with the auto-generated message-id and why it's a concern for some.

For now, I just wanted to get this word out to those who understand the problem already that CF8 solves it. Woo hoo.

CF and OO and blogs, oh my (a flush of CF-OO blog tutorials)

Note: This blog post is from 2007. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Step right up ladies and gentlemen, get your CF-OO tutorials here. :-)

I've noticed a sudden flush of multipart CF-OO tutorial blog series being done, to help people make the leap to using CFML in a more Object-Oriented way. I thought I'd point them out for those who may have missed them:

Don't know if there's a connection between the rather simultaneous releases, or if it's just pure coincidence. Charlie clarified that there indeed was no connection between the two.

And for those who want to get their CF-OO freak on, there are still more resources on the topic.

And there are certainly many more. I'd welcome hearing of those to add to the list. And there may well be more multi-part CF-OO blog series' created before or after now. Feel free to make note in the comments here and I'll update the list for posterity.

Maybe we're starting to reach a tipping point. Of course, there are some who will lament a push to OO (too complicated for them), while others will say you're a hopeless loser if you don't get with the program.

I don't want to debate that here, nor do I really want to see it blow up in my comments, please! :-) Feel free, instead, to point people to where else it may have taken place so that they can evaluate the discussions there instead.

Resources for getting a much greater understanding of the SQL Server query plan/procedure cache

Note: This blog post is from 2007. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Ever wanted to understand the SQL Server query plan/procedure cache better? It can be vital to good performance of SQL statements, especially with respect to the concept of "bind variables" or "parameterized queries" (using CFQUERYPARAM in a CFML context, or Parameters.Add() in a C# context, among other ways).

Update: If you may wonder why any of this is important, see some subsequent talks I gave on the topic, that give far more context on the problem. While you rarely hear about it from others, it is a source of potentially significant problems so is worth understanding more completely. See the "My Own Talks" section at the bottom of this entry.

Yet we so often just kind of assume the database will do what's best. Or we blindly use (or recommend use of) bind variables without fully understanding why, nor understanding some implications when it may not always be such a good idea.

And did you know that if you can't (or don't) change your code to cause parameterization, did you know that the database can do it for you, either automatically in some simple cases, or by way of an enforced parameterization, either for an entire table of for queries that meet certain "plan guides"? There are many implications to understand in all this.

And how do you track the plan cache (using DMVs, the profiler, perfmon)? And how does it work (allocation of memory, flushing the cache automatically or manually)?

Fortunately, I've found many great resources to help you understand, and I've not found them listed (all together) anywhere else yet.

The info applies to 2005, 2000, and 7, though some aspects may differ, as the resources indicate. (There are even substantive changes in 2005 SP2 that are important to note over the RTM and SP1 releases.)

Huge Plan Caching Article Series by MS Engineers

First, I'll point out that some MS engineers have put together a long and very resourceful series of article-length blog posts on the topic, with explanations, code, demos, troubleshooting techniques, and lots more.

They do kindly offer a "table of contents" page listing all the topics covered, with bullet points about topics within each entry.

Sadly, that page doesn't offer URLs to the articles, nor have any that I found there, nor do the articles link to each other. You can dig around and find the URLs, even finding a category page that lists them in rather random order. But I've looked around the web and can't find any page that lists them all with their links, in order, so here you go:

  1. Structure of the Plan Cache and Types of Cached Objects (original URL)
  2. Sql_Handle and Plan_Handle Explained (Original URL)
  3. How Cache Lookups Work
  4. Query Parameterization
  5. Retrieving Query Plans from Plan Cache DMV's
  6. Best Programming Practices
  7. Costing Cache Entries
  8. Factors that affect Batch Cache-ability
  9. Memory Pressure Limits
  10. Plan Cache Flush
  11. Temporary Tables, Table Variables and Recompiles
  12. Plan Cache Trace Events and Performance

They also offer a series of extensions to that, on troubleshooting:

Chapter in "Practical SQL Server 2005 Troubleshooting" book

Next, I'd point out that one of the contributors to that, Bart Duncan, is a Microsoft Support engineer who I saw speak on the topic at the SQL Server PASS 2006 conference, where I first learned a lot of this info.

He identified then that a lot of the info was in a chapter of a new book, SQL Server 2005 Practical Troubleshooting: The Database Engine, which I've since gotten and was indeed very useful.

If you're a member of the O'Reilly Safari service (or join for their trial), you can find the chapter online.

Of course, both the talk and the book came out before the article series above, and certainly before SP2, so I would recommend you consider both. (I've not yet done a comparison to determine what may be in the chapter that's not in the articles.)

SQL Server BooksOnline

Of course, it always pays to read the docs, and there are indeed some discussions of this concept and related features in the SQL Server Books Online, but I honestly found the info above either easier to find or just more complete.

My Own Talks

I've made my own attempts to communicate some of this info myself in a couple of talks I've given to both CFML and SQL Server audiences:

But really, there is just too much to communicate in any one hour. If this topic seems of interest, take a few hours to digest all the above. I think you'll be AMAZED at what you learn.

Did you know about the NULL attribute of CFQUERYPARAM? I didn't, until today.

Note: This blog post is from 2007. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Will the riches of CFML ever cease to amaze me? :-) Did you know about the NULL attribute of CFQUERYPARAM? I didn't, until today. Consider that you use CFQUERYPARAM and point its VALUE to a variable. What would happen if the value was empty, but your database required a null? How would you solve this? If you didn't know better, you might use an IF test to say "if it's null, use a null, else use the variable", but there a much more elegant solution.

Did you know that CFQUERYPARAM has a NULL attribute that is just for this purpose? It takes a boolean to indicate whether and when to use a NULL rather than the VALUE.

It's not new, having been around since 4.5 according to the CFML language history file. I've just never noticed it before. I learned about it today from a couple of folks on the great CFAUSSIE list.

Now, to be honest, the docs (CFML Reference for the tag) just don't make it as clear as it could be, I don't think (otherwise I'd like to think I'd have noticed it before). I don't see any mention of it in the Developer's Guide, for instance.

Anyway, you can read more about it in a blog entry from Michael Sharman, who I see also just happened to blog about it last month, with a lot more detail:

http://www.chapter31.com/2007/02/04/cfqueryparam-and-conditional-handling-of-nulls/

You might also want to read the comments there as well as at the CFMX 7 docs for the tag, both of which have people sharing their experiences using the tag, over time.

Using a range of hex values in a CF regular expression

Note: This blog post is from 2007. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
If you were asked by someone to strip a string of all characters having ASCII codes from some value and higher, how would you do it? If you'd think to use a regular expression, you get 5 points. :-) But how would you get it to take a range? If you're ever stumped, here's how.

Assume you have a str1 variable with the string to be processed, and you want a resulting str2 holding the result. Let's assume as well that you've been asked to strip any codes with ASCII values of 160 or higher. This will do it:

<cfset str2 = rereplace(str1,"[\xa0-\xff]","","all")>

The CF docs do discuss using the \xnn option to search for a hex value, but they don't show how to specify a range. You might, as I did, try a few variations until you stumble upon it. That's the format.

Oh, and as for the xa0, that's the hex equivalent of decimal 160, and ff is the top of the range. I didn't find that it performed any more slowly with ff or some lower number.

Hope all that's helpful to someone. As for why you may do the above, I'd rather take that up in a separate entry which I hope to write today.

Did you know you can store CFDOCUMENT and CFREPORT output in a variable?

Note: This blog post is from 2007. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
This may not be news to some, but it was to me. I just noticed that the CF7 tag, CFDOCUMENT (as well as the new form of CFREPORT), has an available NAME attribute. This allows you to save the resulting PDF or FlashPaper (or Excel, in the case of CFREPORT) output (in binary form) to a variable.

Some may know the available FileName attribute, which allows you to save the output to a file. This NAME attribute is simply an interesting alternative.

Here's a quick example:

<cfdocument format="PDF" name="test">
test
</cfdocument>

This creates a variable named test. How would you output it? CFCONTENT, of course, with the appropriate content type. If your page has created any other output, don't forget the Reset attribute as well:

<cfcontent variable="#test#" type="application/pdf" reset="Yes">

To output a Flashpaper format report, use a CFCONTENT type of "application/x-shockwave-flash", and for a CFREPORT Excel spreadsheet, use a CFCONTENT type of "application/vnd.ms-excel".

Why might you do this?

Of course, if you just did that above, you might as well not have bothered, right? The point is that you may do something between when you create the variable and when you output it. For one thing, you may create it in one CFC, custom tag, or CFFUNCTION-based UDF and then output it later in the request.

More likely, you may choose this approach to facilitate caching and later reusing the generated output. Just as with creating a variable with any tag, you could have instead provided a prefix scope like session, application, or server. Then you could manage that cached result any of the many ways that have long existed for caching other tag results in shared scope variables.

Posting a form to itself without trickery, using an empty ACTION attribute

Note: This blog post is from 2007. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Did you know that if a form has an empty ACTION attribute (or none at all), it will post back to itself (to the page that presented the form)? This can be very useful, and it's a lot easier than more complicated code that struggles to build the ACTION attribute to hold the current filename and any query string.

In the first iteration of this entry, I referred to the two approaches of either providing an empty ACTION or none at all, but as the comments below show, the former violates the HTML spec. So let's stick with the notion of an empty ACTION. Same result, though.

How often have we all seen code along the lines of:

<form action="<cfoutput>#cgi.script_name#?#cgi.query_string#</cfoutput>" method="post">
...

or more involved:

<cfset action=CGI.SCRIPT_NAME>
<cfif CGI.QUERY_STRING NEQ "">
   <cfset action=action & "?" & xmlformat(CGI.QUERY_STRING)>
</cfif>
<form action="<cfoutput>#action#</cfoutput>" method="post">
...

All this could be replaced very simply with:

<form method="post" action="">
...

The form will post back to itself. I'll offer another post that shows a unique way to take advantage of this. In any case, I hope that this observation may help some folks.

(Update: I never got around to that other entry in 2007, but see a my reply to a comment below where someone asked for more info on the idea I had in mind.

Is this reliable?

Now, there are some who will argue that this is a violation of the HTTP HTML spec, and so it may be, but I've never found a browser in which it didn't work.

Again, a clarification over what I wrote originallyhere. As was refined in the comments below, it's a violation to have *no* ACTION, but it's perfectly legit according to the URI spec (section 4.2 at http://www.ietf.org/rfc/rfc2396.txt) to have an empty ACTION, which is interpreted as a "same-document reference. (Thanks, Christopher Bradford, for that info.) Given that, even the following cautions seem needless, but I'll leave them for any still concerned.

If you have any hesitation, because you have to support multiple browsers and you can't test all possibilities, I'll understand if you choose to pass on this. But certainly if you only need to support browsers you can test, then if it works as expected, enjoy.

If anyone reading this can offer where this is the case, I'd appreciate hearing it. If you want some simple code to test, try this:

<form method="post" action="">
   <input type="Submit">
</form>
<cfif cgi.request_method is "post">
   Posted to itself
</cfif>

If it shows the text within the IF, then it worked as expected.

What about query string info?

You may wonder about the earlier more involved examples that showed passing the query string, in case any had been passed to the form. No problem. This technique passes any query string along just fine. Try it yourself (add ?test=test to the form and view in the debugging info that it's still in the URL scope after submission.)

CFFundamentals: Mimicking a form submission using CFHTTP

Note: This blog post is from 2006. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
While developers who've used CFML for a long time will regard some topics as old hat, we have to remember that there are folks who either have come along recently or simply never used some feature. This is one of those topics, and since I answered it on a list, I offer it here.

[....Continue Reading....]

Programmatically accessing allowed IP Addresses in Developer Edition (and understanding the limits)

Note: This blog post is from 2006. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Have you ever needed to know programmatically what IP addresses, besides localhost, ARE allowed to access your Developer Edition of ColdFusion? I'll show you how here.

[....Continue Reading....]

Reloading CF web services programmatically, using the CF7 Admin API

Note: This blog post is from 2006. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
I'm surprised to not see much out there about how to reload or refresh CF's cached WSDL proxy for calling a web service, at least programmatically using the new CF 7 Admin API. Perhaps it's because people have been tripped up, or simply haven't explored it. Either way, I'd like to offer here the code you need, and also point out some tips and traps.

Update for CF8: As an update to this entry from 2006, which is focused on CF7, I'll note that there was yet another approach that was added in CF8. Both still work and have their own value. More on the CF8 feature in my later blog entry. Still, the feature added in CF7 is important to understand, too, so please read on.

[....Continue Reading....]

More Entries

Copyright ©2024 Charlie Arehart
Carehart Logo
BlogCFC was created by Raymond Camden. This blog is running version 5.005.
(Want to validate the html in this page?)

Managed Hosting Services provided by
Managed Dedicated Hosting