CFFormProtect Rocks!

Others have praised CFFormProtect, but I wanted to share a couple quick stats and give another shout out to Jake Munson for the very useful CFFormProtect. If you're not familiar with CFFormProtect, here is a snippet from the description at RIAForge:

CFFormProtect is a fully accessible, invisible to users form protection system to stop spam bots, and even human spammers. CFFormProtect works like some email spam protection systems, in that it uses a series of tests to find out if a form submission is from a spammer or not. Each test is given an amount of points, and each test that is failed accumulates points. Once a form submission passes the threshold of 'spamminess', the message is flagged as spam and is not posted. The points assigned to each test and the failure limit are easily configurable by you.

It is quite simple to implement, and the code is rather simple and lightweight, but brilliantly useful and powerful! The latest version of BlogCFC ships with CFFormProtect and you can optionally enable it to block comment spam. I rarely see any comment spam get through on my blog, but this morning I had a flurry of 10 or more, from the same spammer. I was quickly able to tweak my INI file for CFFormProtect so this particular spam would be blocked from now on. I also decided to peak at the log file for CFFormProtect (you can optionally have CFFormProtect log blocked spam occurrences) and noticed that my blog gets a *LOT* of comment spam, but I never have to deal with it, thanks to CFFormProtect!

This morning was the first comment spam I've had get through in months, but it turns out that CFFormProtect has quietly blocked more than 80 spam attempts for me in just the last 24 hours! If you're a CFML developer and you'd like to protect any form from spam without bothering with CAPTCHA, I highly encourage you to check out CFFormProtect.

Railo JARs on JBoss (or Tomcat) - Tips and Tricks

As a follow up to a previous related post, I wanted to share a couple potentially helpful tricks that I've since learned. Everything I document here has been tested with both Railo 3.0.2.004 (current stable) and Railo 3.1.0.012 (current beta), both of which can be downloaded from here, on JBoss Application Server (AS) 4.2.3.GA.

The purpose (as I see it) of a Railo JARs installation is to provide an alternative to using a full-blown Railo WAR for each of your Railo CFML applications. This allows you to define your Railo CFML servlet "globally" in JBoss/Tomcat and then use virtual hosts for multiple CFML apps. Each CFML app is then leveraging the same Railo instance, one copy of the jars and one Railo server admin (but still multiple Web contexts with unique Railo Web Admin for each Web site/context).

Also keep in mind that JBoss AS leverages Tomcat as its Web server, so just about everything here should directly translate. Here are the locations of key configuration files and directories in both JBoss 4.2 and Apache Tomcat 6:

{JBOSS_HOME}/lib/ {JBOSS_HOME}/server/default/lib/
or
{TOMCAT_HOME}/lib/

{JBOSS_HOME}/server/default/deploy/jboss-web.deployer/conf/web.xml
or
{TOMCAT_HOME}/conf/web.xml

{JBOSS_HOME}/server/default/deploy/jboss-web.deployer/server.xml
or
{TOMCAT_HOME}/conf/server.xml

Quick Review of Railo JARs Install on JBoss/Tomcat

I will first give a very brief outline of the steps required to install Railo (jars) on JBoss/Tomcat here. There are, however, some potential problems with this configuration, which I'll outline below, with a solution/workaround for each.

[More]

Sitemaps.org Data Driven Sitemap XML Generator (sitemap.xml for Google, Yahoo!, MSN and others)

Update: Get SitemapCFC at Google Code or at RIAForge.

If you're not familiar with Sitemaps, visit the sitemaps.org home page, which provides an overview of the Sitemaps protocol (adopted by Google, Yahoo! and Microsoft, among others).

I wanted to generate a sitemap.xml file to submit to Google, Yahoo!, etc. based on data from a simple CMS application's database. I ran some quick searches and was surprised to not quickly find a CFC that did exactly what I was looking for. There are a few sitemap generators out there that crawl site links to produce a sitemap XML file, but I didn't find any that generated an XML file based on data. I know there are a number of applications that have built-in site generator support (like BlogCFC and probably most modern blog and CMS apps), but I didn't find anything generic and flexible enough for my needs. Ray Camden did share a UDF that handles the basics very nicely, but I wanted to be able to pass in different URL collection types with flexible key/column names. I'd already cooked up two different (albeit simple) application-specific sitemap generators for apps that I maintain, so it was time to genericize and reuse!

I'll outline the Sitemap.cfc I created, its features and some examples. I will update this post with a link to RIAForge once I have the project approved for upload there. If you're not looking for a data-driven sitemap generator, but rather a crawler or spider style sitemap generator, then check out this "Google Sitemap XML Generator". For a data driven sitemap generator (or, if you want to use your own crawler and just need to model and generate a valid sitemap.xml file), read on...

I quickly put together a relatively simple Sitemap.cfc to suit my needs, but then I found myself adding more and more little enhancements. Since the sitemaps.org protocol is relatively simple, it wasn't too difficult to create a CFC to model the protocol. I tried to keep it simple, but flexible enough to take a collection of URLs (and relevant meta data) in just about any form and spit out a valid sitemap.xml file.

SitemapCFC Feature Overview

  • Use a list, query or array (of structs) to initialize a sitemap object.
  • Query column or struct key names used to initialize a Sitemap.cfc object are not important; an optional init() argument can be used to map to standard sitemaps.org protocol tag names.
  • Write your sitemap.xml file to disk or dynamically send a sitemap XML document to the browser as binary page output (cfcontent type text/xml).
  • Debugging methods available to access a Sitemap.cfc object's URL collection in the form of an array, an XML object or the raw XML string.
  • XML document is schema validation ready.
  • All initialization data values are cleaned (entity escaping, date/time format, valid string values, etc.) and validated.
  • Date(/time) values for the <lastmod> tags can be passed in as any valid date/time string or object; they will be automatically converted to UTC in proper W3C Datetime format (again, per sitemaps.org protocol).

Read on for an [] of examples...

[More]

Railo 3.0 on JBoss AS 4.2 via Apache 2.2 with Root Context and No Proxy

So I wanted to take a good look at the Railo 3.0 CFML engine and see what all the buzz was about. I wanted to be sure I could replicate the same basic Apache virtual host configurations I've been using with my ColdFusion 8 multi-server configuration. I also decided to try to get this all working with the JBoss Application Server. This entry summarizes the battle that was eventually won...

Choosing An Application Server

After a great deal of reading comparisons and opinions regarding Resin, Tomcat and JBoss Application Server (also with/without Apache), I decided I wanted to shoot for running the Railo CFML engine on the JBoss Application Server. There was plenty of good press and lots of die hard proponents for each of these application server options, so I don't feel there's a wrong decision and recommend you decide for yourself. For me, I just liked the robustness of JBoss and the full-featured community edition (Resin, for example, only provides a lot of its full-featured options in the paid licenses).

Basic Railo Installation/Deployment (EAR/WAR)

I'll leave out a lot of the lower level details of my installations, because there are plenty of Railo installation guides out there already (and probably growing). I must, however, mention that a lot of Gary Gilbert's Railo posts were particularly useful in my learning experience.

Using the aforementioned guides I was able to get JBoss AS installed and then deployed Railo 3.0 as a WAR and then also tried the EAR deployment alternative. I was not able to deploy Railo 3.0.2.001 on JBoss AS 5.0.1.GA, but all deployments worked fine for me on JBoss AS 4.2.3.GA. I've noticed other folks comment on being able to deploy Railo on JBoss 5 on Ubuntu 8.04, which is my development OS, but I was not successful. The errors I received appeared to be known JBoss 5 bugs, but who knows!

Adding Apache HTTPD to the Stack

After getting Railo 3.0 running on JBoss 4.2, I then wanted to integrate Apache 2.2, which was relatively straightforward using the mod_jk module for Apache HTTPD (again, this stuff is already well documented). At this point, however, I could either have only one Railo Web root and/or needed to use specific context paths for each Web site/context (e.g., http://localost/app1-context, http://localhost/app2-context, etc.).

Railo on JBoss via Apache, as I really wanted it to be

I then wanted to be able to run multiple Apache virtual hosts as multiple Railo web contexts on the same instance of Railo, but without needing a unique context path for each and without needing to proxy from Apache. After hours of experimentation and searching for help, I just could not find a way to make this happen.

Just as I was about to give up, I was reassured that this could be done when I read a couple installation guides that used Tomcat virtual hosts and a Railo installation using the JARs download only (not an EAR or WAR deployment): this one by James Constable and this one by Gary Gilbert.

These guys were doing exactly what I wanted to do, simply with Tomcat instead of JBoss, and since I knew JBoss AS uses Tomcat as its Web server, I knew there must be a way! I simply needed to identify the JBoss deployment directory in which to locate the Railo jars, and which web.xml and server.xml files to modify within the JBoss deployment directory structure. Here they are:

{JBOSS_HOME}/lib -- Drop the Railo jar files in here.
{JBOSS_HOME}/server/default/lib -- Drop the Railo jar files in here.

{JBOSS_HOME}/server/default/deploy/jboss-web.deployer/conf/web.xml -- Define the Railo servlet, servlet mappings and welcome files in this file.

{JBOSS_HOME}/server/default/deploy/jboss-web.deployer/server.xml -- Define Host entries for each application/virtual host in this file (to match up with Apache virtual hosts).

Next Steps

I would like to learn a bit more about JBoss AS administration and be sure my environment is configured for high performance and sensible security. I'll also want to run JBoss as a daemon that starts automatically at boot. I'm running Ubuntu 8.04 as my main development environment and I found what promises to be a fantastic article on a proper JBoss AS installation on Ubuntu!

I'm also looking for some sort of confirmation that my basic method of configuring this Railo/JBoss/Apache stack makes sense, or whether there's a preferred alternative (using WAR, EAR, proxy, etc.). I hope to get a lot of answers in the near future since Railo just recently joined forces with JBoss (read the Railo announcement here or the JBoss.org announcement here).

cfmailpart order for HTML display in Gmail

It seems that Gmail only renders the HTML part of my multi-part messages from cfmail when the text cfmailpart is before the html cfmailpart.

For example, Gmail will render the text version if I do this:

<cfmail from="#from#" to="#to#" subject="Multi-part, html first">
<cfmailpart type="html"><h1>HTML Message Part</h1></cfmailpart>
<cfmailpart type="text">Text Message Part</cfmailpart>
</cfmail>

But if I just swap the order of the cfmailpart entries, then Gmail renders the HTML version:

<cfmail from="#from#" to="#to#" subject="Multi-part, text first">
<cfmailpart type="text">Text Message Part</cfmailpart>
<cfmailpart type="html"><h1>HTML Message Part</h1></cfmailpart>
</cfmail>

I had a friend test on Outlook and that client appears to show the HTML part, regardless of the ordering of the text/html parts in the message body. Though I haven't tested any other mail clients yet, I'll keep the text part first and html part second in my multi-part e-mails. I know they'll display as intended in both Gmail and Microsoft Outlook (and I'm guessing most other clients behave like Outlook, in that they'll default to an HTML part if one is there).

cfmail using Gmail SMTP

I wanted to have a cfmail tag use my Gmail SMTP to send mail, which was relatively straightforward, but there is some vague language in the Google help doc that didn't immediately translate to cfmail attribute settings. I did find plenty of search results on the topic, but most threads were a little confusing and noted differing experiences between developers. So I've taken a little time to experiment and thought I'd share the results.

From both my gmail.com account and my Google Apps for Your Domain mail (gmail for custom domain name) accounts I was able to find the same help doc for standard POP/SMTP configuration.

We can quickly deduce that the username attribute should be your full e-mail address (including @gmail.com or @your_domain.com), and the password is of course your Gmail password.

The help doc provides the following information for the outgoing/SMTP server configuration:

smtp.gmail.com (use authentication)
Use Authentication: Yes
Use STARTTLS: Yes (some clients call this SSL)
Port: 465 or 587

So, how does the above information translate to relevant cfmail tag attributes (server, port, username, password, useSSL, useTLS)? It's a bit more specific than the Gmail help doc suggests...

[More]

ColdFusion round() function bug when operation performed on argument

UPDATE (July 15, 2009): This "bug" still exists in Adobe ColdFusion 9 beta 1. It also seems to behave the same in OpenBD 1.1. This bug does not seem to exist in Railo (I can't reproduce any similar problems in Railo 3.0 or Railo 3.1). For example, round(4.0005*1000) outputs 4000 from both AdobeCF and OpenBD while Railo outputs the expected 4001. There may very well be other scenarios where a floating point representation causes similar unexpected results in Railo as well, but I have not been able to find it yet (nor have I performed an absolutely thorough test, maybe soon if time permits).

Have you ever used a CFML trick like this to round a number to the nearest hundredth?

<cfoutput>#round(someNumber*100)/100#</cfoutput>

I have, and I never had a problem, until...

<cfscript>
    valueA = 4000.5;
    valueB = 4.0005*1000;
    roundedA = round(valueA);
    roundedB = round(valueB);
</cfscript>

You'd be perfectly sane to expect the first two variables to output as 4000.5 and the second two (rounded) to output 4001. Unfortunately, roundedB is output as 4000, not 4001!

This definitely appears to be a bug, but I do have a rather simple workaround...

[More]

Hello, [blog] world!

Yes, it was probably at least two years ago when I first thought, "I should start blogging," and here, finally, is my first ever post. Since this will be a blog about ColdFusion development and other programming related topics, I couldn't resist a "hello world" style title for my first post. That said, I'd like to share a little about why I decided to start blogging, what I hope to share and what I hope to gain from blogging.

First, my relevant geek background, in a nutshell:

  • First program written in BASIC on a TRS-80 to calculate my baseball batting average at approximately 10 years old.
  • Geeked out in MS-DOS, C programming and a touch of Perl (1989-1994).
  • Finally made the switch from DOS to Windows 95 in 1996.
  • Entered the University of Rochester as a computer science major -- a little too disinterested in many of the non-programming topics -- graduated with a music degree and a minor in mathematics, but also got a good little dose of data structures, Java and C++.
  • HTML, MS Access and other general computer-related gigs for a couple years (1998-1999).
  • Web development using ASP scripting with MS Access and SQL Server databases (1999-2002).
  • Fell in love with ColdFusion around 2001 (using ColdFusion 4.52 at first) and used it to build and maintain dozens of sites (2001-2003).
  • Really started digging in to object oriented CFML development and helped build, grow and maintain a group of large-scale applications primarily running Mach-II and ColdSpring (with a touch of Transfer, Reactor and Model-Glue) (2004-2008).
  • Read on for present-day geekiness...

In October of 2008 I decided to go solo and freelance develop again to have a better opportunity to code and learn and code and learn (as opposed to management and meetings and management and meetings). I've spent the last few months doing nothing but coding and learning, and I'm loving it! My main project right now is www.mortgages.com, which I've built up from a blank slate, using ColdFusion 8 Enterprise on Linux, PostgreSQL 8.3, Model-Glue 3 (Gesture, bleeding edge release), ColdSpring, Transfer ORM, MXUnit, jQuery and and I even wrote a little code myself :) I also decided to ditch Microsoft entirely and I'm running Ubuntu 8.04 on my development laptop, along with a Windows XP VM via VirtualBox virtualization to allow for IE testing (will be looking to setup a Mac testing ground as well). This project has helped me ask and answer a lot of questions around good object oriented design, best practices, using the right tools, etc. Though I feel I've had a great sprint of learning over the past few months, I'm hungry to absorb so much more!

That brings me back to my main point, this blog. From many other bloggers I've learned a lot through finding countless answers, great tips, great examples and tutorials, etc. I've also solved a number of problems either on my own or with the help of tid-bits from various online resources. So, I'd like to have a platform to share when I think I have something worth sharing, and that will be this blog. I will also likely blog about some of my own learning experiences, when I think it might help others embarking on a similar learning path. If I'm lucky, some folks might actually read my blog and share some feedback, which will help me and other readers learn more and better ourselves as programmers.

Well, thanks for reading. Cheers to blogging!

BlogCFC was created by Raymond Camden.