Orange is my favorite color

We’re discussing some refactoring before releasing a cfpayment 1.0 and one of the things I’m working on is figuring out when to use ColdFusion’s in-built error handling and when to use HTTP status codes. Currently we use the throwonerror option for CFHTTP which results in issues like 404 throwing an exception. This works but as more and more services expose RESTful APIs which use status codes other than 200 to communicate results, this is not perfect.

That got me to thinking… what status codes does ColdFusion throw an error for when throwonerror is set to yes? Here’s the list for every HTTP status code:

CFHTTP with throwonerror=”yes”

200 Returned normally with status 200 OK
201 Returned normally with status 201 Created
202 Returned normally with status 202 Accepted
203 Returned normally with status 203 Non-Authoritative Information
204 Returned normally with status 204 No Content
205 Returned normally with status 205 Reset Content
206 Returned normally with status 206 Partial Content
207 Returned normally with status 207 Multi-Status
208 Returned normally with status 208 Already Reported
226 Returned normally with status 226 IM Used
300 COM.Allaire.ColdFusion.HTTPMultipleChoices
301 COM.Allaire.ColdFusion.HTTPMovedPermanently
302 COM.Allaire.ColdFusion.HTTPMovedPermanently
303 COM.Allaire.ColdFusion.HTTPSeeOther
304 COM.Allaire.ColdFusion.HTTPNotModified
305 COM.Allaire.ColdFusion.HTTPUseProxy
306 Returned normally with status 306 Switch Proxy
307 Returned normally with status 307 Temporary Redirect
308 Returned normally with status 308 Resume Incomplete
400 COM.Allaire.ColdFusion.HTTPBadRequest
401 Returned normally with status 401 Unauthorized
402 COM.Allaire.ColdFusion.HTTPPaymentRequired
403 COM.Allaire.ColdFusion.HTTPForbidden
404 COM.Allaire.ColdFusion.HTTPNotFound
405 Returned normally with status 405 Method Not Allowed
406 COM.Allaire.ColdFusion.HTTPNotAcceptable
407 COM.Allaire.ColdFusion.HTTPProxyAuthenticationRequired
408 Returned normally with status 408 Request Timeout
409 COM.Allaire.ColdFusion.HTTPConflict
410 COM.Allaire.ColdFusion.HTTPGone
411 COM.Allaire.ColdFusion.HTTPFailure
412 COM.Allaire.ColdFusion.HTTPPreconditionFailed
413 COM.Allaire.ColdFusion.HTTPCFHTTPRequestEntityTooLarge
414 COM.Allaire.ColdFusion.HTTPRequestURITooLarge
415 COM.Allaire.ColdFusion.HTTPUnsupportedMediaType
416 Returned normally with status 416 Requested Range Not Satisfiable
417 Returned normally with status 417 Expectation Failed
418 Returned normally with status 418 I’m a teapot
422 Returned normally with status 422 Unprocessable Entity
423 Returned normally with status 423 Locked
424 Returned normally with status 424 Failed Dependency
425 Returned normally with status 425 Unordered Collection
426 Returned normally with status 426 Upgrade Required
428 Returned normally with status 428 Precondition Required
429 Returned normally with status 429 Too Many Requests
431 Returned normally with status 431 Request Header Fields Too Large
444 Returned normally with status 444 No Response
449 Returned normally with status 449 Retry With
450 Returned normally with status 450 Blocked by Windows Parental Controls
499 Returned normally with status 499 Client Closed Request
500 COM.Allaire.ColdFusion.HTTPServerError
501 COM.Allaire.ColdFusion.HTTPNotImplemented
502 COM.Allaire.ColdFusion.HTTPBadGateway
503 COM.Allaire.ColdFusion.HTTPServiceUnavailable
504 Returned normally with status 504 Gateway Timeout
505 COM.Allaire.ColdFusion.HTTPVersionNotSupported
506 Returned normally with status 506 Variant Also Negotiates
507 Returned normally with status 507 Insufficient Storage
508 Returned normally with status 508 Loop Detected
509 Returned normally with status 509 Bandwidth Limit Exceeded
510 Returned normally with status 510 Not Extended
511 Returned normally with status 511 Network Authentication Required
598 Returned normally with status 598 Network read timeout error
599 Returned normally with status 599 Network connect timeout error
999 Returned normally with status 999 Invalid HTTP status code

I also ran it with throwonerror=”no”, which has almost the results you would expect with the exception of code 411:

CFHTTP with throwonerror=”no”

200 Returned normally with status 200 OK
201 Returned normally with status 201 Created
202 Returned normally with status 202 Accepted
203 Returned normally with status 203 Non-Authoritative Information
204 Returned normally with status 204 No Content
205 Returned normally with status 205 Reset Content
206 Returned normally with status 206 Partial Content
207 Returned normally with status 207 Multi-Status
208 Returned normally with status 208 Already Reported
226 Returned normally with status 226 IM Used
300 Returned normally with status 300 Multiple Choices
301 Returned normally with status 301 Moved Permanently
302 Returned normally with status 302 Found
303 Returned normally with status 303 See Other
304 Returned normally with status 304 Not Modified
305 Returned normally with status 305 Use Proxy
306 Returned normally with status 306 Switch Proxy
307 Returned normally with status 307 Temporary Redirect
308 Returned normally with status 308 Resume Incomplete
400 Returned normally with status 400 Bad Request
401 Returned normally with status 401 Unauthorized
402 Returned normally with status 402 Payment Required
403 Returned normally with status 403 Forbidden
404 Returned normally with status 404 Not Found
405 Returned normally with status 405 Method Not Allowed
406 Returned normally with status 406 Not Acceptable
407 Returned normally with status 407 Proxy Authentication Required
408 Returned normally with status 408 Request Timeout
409 Returned normally with status 409 Conflict
410 Returned normally with status 410 Gone
411 Returned normally with status Connection Failure. Status code unavailable.
412 Returned normally with status 412 Precondition Failed
413 Returned normally with status 413 Request Entity Too Large
414 Returned normally with status 414 Request-URI Too Long
415 Returned normally with status 415 Unsupported Media Type
416 Returned normally with status 416 Requested Range Not Satisfiable
417 Returned normally with status 417 Expectation Failed
418 Returned normally with status 418 I’m a teapot
422 Returned normally with status 422 Unprocessable Entity
423 Returned normally with status 423 Locked
424 Returned normally with status 424 Failed Dependency
425 Returned normally with status 425 Unordered Collection
426 Returned normally with status 426 Upgrade Required
428 Returned normally with status 428 Precondition Required
429 Returned normally with status 429 Too Many Requests
431 Returned normally with status 431 Request Header Fields Too Large
444 Returned normally with status 444 No Response
449 Returned normally with status 449 Retry With
450 Returned normally with status 450 Blocked by Windows Parental Controls
499 Returned normally with status 499 Client Closed Request
500 Returned normally with status 500 Internal Server Error
501 Returned normally with status 501 Not Implemented
502 Returned normally with status 502 Bad Gateway
503 Returned normally with status 503 Service Unavailable
504 Returned normally with status 504 Gateway Timeout
505 Returned normally with status 505 HTTP Version Not Supported
506 Returned normally with status 506 Variant Also Negotiates
507 Returned normally with status 507 Insufficient Storage
508 Returned normally with status 508 Loop Detected
509 Returned normally with status 509 Bandwidth Limit Exceeded
510 Returned normally with status 510 Not Extended
511 Returned normally with status 511 Network Authentication Required
598 Returned normally with status 598 Network read timeout error
599 Returned normally with status 599 Network connect timeout error
999 Returned normally with status 999 Invalid HTTP status code

Notice Status Code 411 doesn’t return a numerical status code but rather a string “Connection Failure. Status code unavailable.” The FileContent is set to “Connection Failure” while all other status codes are left blank (assuming that the request doesn’t return any data, as my test script does). Good to know.

How ColdFusion handles Status Code 411

Problematic SSL Certificates

For processing credit cards and payment processing transactions in general, the most insidious error I have run into is the “I/O Exception: peer not authenticated” error. This basically means ColdFusion is unable to read and authenticate the SSL certificate and initiate a secure connection. Generally this is either a self-signed certificate or, these days, a wildcard SSL certificate. Interestingly, ColdFusion handles these scenarios a little bit differently depending on how throwonerror is set:

Test ThrowOnError Status/Message ErrorDetail/Exception
Self-signed SSL Cert Yes Connection Failure: Status code unavailable COM.Allaire.ColdFusion.HTTPFailure
Self-signed SSL Cert No Connection Failure. Status code unavailable. I/O Exception: peer not authenticated
Wildcard SSL Cert Yes Connection Failure: Status code unavailable COM.Allaire.ColdFusion.HTTPFailure
Wildcard SSL Cert No Connection Failure. Status code unavailable. I/O Exception: peer not authenticated

In summary, using throwonerror=no looks reasonably safe but you still must account for the catch-all COM.Allaire.ColdFusion.HTTPFailure. My battle-tested code (which has processed more than $15MM) suggests you also need to check for coldfusion.runtime.RequestTimedOutException which is a different kind of exception when CFHTTP times out or the page times out.

If you manage a ColdFusion 8 or 9 server, you are likely aware of the complete and total train wreck that is applying security updates from Adobe. Not only are directions vague, but on occasion Adobe likes to go back and modify the security update without changing filenames or rev-ing the version number. It can drive a SysOp to insanity.

So seems to be the mental state of David Epler as he has been driven to build the “Unofficial Updater 2“. It is an Ant script on steroids bundled in a JAR that knows how to go out and fetch all of the updates from Adobe.com and apply them to your CF8 or CF9 server installation.

I’m not going to belabor the awesomness; here’s how to get your server up to date in about 5 minutes:

  1. Start by verifying your current security issues, use Pete Freitag’s HackMyCF.com for a baseline
  2. Backup your /opt/jrun directory (just be safe): tar -cf /opt/jrun4
  3. Download the Unofficial Updater from http://uu2.riaforge.org/
  4. Run it: java -jar Unofficial-Updater2.jar text
  5. Tell it where stuff lives in your installation (it knows how to handle Standalone, Jrun Multi-server and EAR/WAR installs)
  6. Wait about 4 minutes for it to finish grabbing everything and install…
  7. Re-run HackMyCF.com and BOOM! Rest easy, friend.
  8. Proceed to have David Epler’s baby

Please Adobe, please send David a big check so you can take his IP and use it for your next update, mmmm kay?

One of my favorite annual racing events, the NASA 25 Hours of Thunderhill brings racers from all backgrounds and disciplines together to see who can run their racecar the fastest over a 25-hour period. Walking the paddock is like compressing an entire year of friends and conversations into a single weekend and yet, somehow, the on-track action is even better.

This year I was lucky enough to drive with Tiger Racing in their 2006 BMW M3. Compared to the low-horsepower cars I typically drive, this 400+HP car with 10″ slicks and big Brembo brakes was a completely different animal, and it was fast. Even at a comfortable enduro pace to preserve the car and exercise caution when passing, the M3 is capable of running lap times 12-15s/lap faster than my Spec Miata. It also sounds absolutely glorious. :)

Here are a few laps of in-car footage from my stint driving just after sundown into the darkness. Driving at night is one of my favorite times: you settle into a rhythm and just click off the laps (click through to see a larger version and make sure to enable HD):

I was in the car for 2.5 hours until earlier damage created a mechanical issue that forced us to retire. This was the team’s 8th running of the 25 Hour and it’s their first retirement which speaks to the great job they do before the race each year. The car is prepared by Bavarian Tuning in Santa Rosa and TC Design in Milpitas, CA. Big thanks go out to the crew – one of the best in the paddock – and my fellow drivers John Larson, Billy Maher and Tony Colicchio for inviting me to be part of the team!

For some amazing photos, check LifeBlasters.com write-up of the event.

On a recent trip to Mexico I had the chance to use my Spanish (oh I’m quite the Renaissance man) and found that what I lose first is my ability to quickly say “he did X” or “they do Y”. Worse is my need to reverse-engineer what I’m hearing back to an infinitive. If someone says “Ellos me hablaban”, I decipher it like: “hablaban, ok, that is the third person plural for hablaba, which is hablar, which means to speak, so it’s they were speaking.” That probably explains the glassy look in my eyes as I listen to native speakers.

Once home I searched for a database of conjugated verbs to make flash cards that, rather than working with infinitives, would read simple actions like “They walk”, “He used to sing” or “We would have spoken” and the reverse would have the proper Spanish conjugation. Despite my uber Google skills, I was unable to find any non-commercial products. However, I did come across one great resource that had the data I needed.

Fred Jehle, formerly a professor at Indiana University-Purdue University Fort Wayne, published approximately 600 verbs, fully conjugated in all moods and tenses, on his website in 1998. The resource helped students improve their verb use in addition to a variety of notes on other aspects of the language. I contacted Mr. Jehle to inquire if a database of his verbs were behind the scenes but unfortunately only the static web pages exist.

Out of curiosity, I opened up a couple of pages to see what the source HTML looked like and, luckily, it was pretty uniform. I broke out my editor and wrote a script to read in each page, parse out the various conjugations and dump them in to a (PostgreSQL 9.x) database. The roughly 600 verbs converted to 11,467 combinations of moods + tenses.

In coordination with copyright holder Professor Jehle, this data is available free of charge via a Creative Commons license for anyone to use for non-commercial purposes so long as you provide attribution. If you alter, transform or build upon this work then you may distribute the resulting work only under the same license.

My thanks go to Mr. Jehle for quickly answering my questions and allowing me to publish the data for other would-be Spanish students. I recommend that you also check out his website for additional Spanish content at http://users.ipfw.edu/jehle/VERBLIST.HTM.