Creating A "Down For Maintenance" Page Using Application.cfc

Posted January 9, 2008 at 9:07 AM by Ben Nadel

Tags: ColdFusion, Search Engine Optimization

As some of you may or may not noticed, my site was down earlier for maintenance (more on that later). None of the ColdFusion pages on my site were available, no matter what URLs you used. Creating a page like this is insanely easy when you are using ColdFusion's Application.cfc component. If you have ever examined the application event methods available in the Application.cfc, you will notice that several of them return a boolean value. This value, while tiny, plays a huge part in the page processing. Anytime that one of the event methods returns false, it kills the rest of the page / application processing.

Using this information, we can easily build our "Down For Maintenance" page directly into the architecture of the Application.cfc component. Since we want to display this page for every request, it feels natural to put this functionality in the OnRequestStart() event method:

  • <cffunction
  • name="OnRequestStart"
  • access="public"
  • returntype="boolean"
  • output="true"
  • hint="Fires at the beginning of a page requested before the requested template is processed.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="TargetPage"
  • type="string"
  • required="true"
  • hint="The template that was requested by the user."
  • />
  •  
  • <!--- Define the local scope. --->
  • <cfset var LOCAL = StructNew() />
  •  
  •  
  • <!--- Set header code. --->
  • <cfheader
  • statuscode="503"
  • statustext="Service Temporarily Unavailable"
  • />
  •  
  • <!--- Set retry time. --->
  • <cfheader
  • name="retry-after"
  • value="3600"
  • />
  •  
  •  
  • <h1>
  • Down For Maintenance
  • </h1>
  •  
  • <p>
  • The web site is current down for maintenance and will
  • be back up shortly. Sorry for the inconvenience.
  • </p>
  •  
  •  
  • <!---
  • By returning false, the rest of the page
  • rendering will hault.
  • --->
  • <cfreturn false />
  • </cffunction>

When creating a Down For Maintenance page, we have to be concerned with more than just the visual aspects; we also want to make sure that search engines such as Google and Yahoo respect that fact that our site is down and don't just assume that our site no longer has content! To do this, we explicitly set the Status Code of the page header to be:

503 - Service Temporarily Unavailable

This will alert the search engine bots and spiders that the site is down and to ignore the pages. But, we also want to take it one step further - we want to reassure the search engine bots that the site will be back up and that the bots should re-index the site shortly. To do this, we set another header value, retry-after. This returns the number of seconds (3,600 in our case) the search engine bots should wait before trying to re-index the site. While I am not sure about this, I have read that if you do NOT return a retry-after header value, the client (browser / bot) should treat this as a 500 - Internal Server Error, so be sure to set this properly!

After our header values, we output our HTML content and then return false. Returning "false" here is a huge point because by returning false, the ColdFusion application server knows not to even bother calling the OnRequest() event method which would have processed the requested template.

If you are using ColdFusion's Application.cfm template instead of Application.cfc, the same thing can be done, but with slightly less elegance. Instead of using any event methods (which don't exist in Application.cfc), you could simply put the header and output code directly into the Applicaiton.cfm:

  • <!--- Set header code. --->
  • <cfheader
  • statuscode="503"
  • statustext="Service Temporarily Unavailable"
  • />
  •  
  • <!--- Set retry time. --->
  • <cfheader
  • name="retry-after"
  • value="3600"
  • />
  •  
  • <h1>
  • Down For Maintenance
  • </h1>
  •  
  • <p>
  • The web site is current down for maintenance and will
  • be back up shortly. Sorry for the inconvenience.
  • </p>
  •  
  • <!--- Abort page. --->
  • <cfabort />

Then, instead of returning false, simply stop the page processing by executing a ColdFusion CFAbort tag.

While we put our output and header logic directly into our Application templates, there is nothing to say that we couldn't wrap this functionality into a template of its own which could then be included in the Application templates.



Reader Comments

Jan 9, 2008 at 3:30 PM // reply »
10,640 Comments

Just testing to make sure this works.


Jan 9, 2008 at 4:30 PM // reply »
211 Comments

Your site kept coming up in my google search for an cfajaxproxy issue I was running into and YOU WERE NOT THERE FOR ME! :( :(

;)


Jan 9, 2008 at 5:08 PM // reply »
10,640 Comments

@Todd,

Switching some name server stuff and it's causing a huge hassle. Never done this before, so trying to figure out how to get it done :)

I think by tomorrow, everything should be propagated and stuff will work smoothly going forward.


Jan 9, 2008 at 5:12 PM // reply »
211 Comments

Yeah, DNS can be tricky. Running a split DNS server at home. Fun fun.


Jan 10, 2008 at 12:10 PM // reply »
18 Comments

This is a nice method, but I prefer to do it at the webserver level, as this obviously only works for coldfusion pages. Just create a second website that points to a page with the Maintenance message (use the 404 handler to do this too), set it up with all the same domains as the original site, stop the original site and start the second site.

Assuming you have access to the webserver.


Jan 10, 2008 at 2:36 PM // reply »
10,640 Comments

@Duncan,

Yeah. I am only recently getting more access to the server / IIS, so until then, this would have been my only option (without having to talk to management).

One of the things that I like about the ColdFusion method is that you can easily put in some logic to allow access from certain IP addresses. I am sure that you can do this via IIS, but I don't know how off-hand.


Jan 10, 2008 at 3:37 PM // reply »
1 Comments

You can also do this in the onRequest method. If you use on request, you can, by default, include the #targetPage# to have it function normally. Then, if you need to repoint, just change the include to the sorry page.

Same idea, different method.


Jan 10, 2008 at 3:42 PM // reply »
10,640 Comments

@Lincoln,

Absolutely. That probably has the cleaner set of code, as well.


Feb 25, 2009 at 11:05 AM // reply »
1 Comments

Hi guys,
I'm new to ColdFusion and perhaps my question will seem a bit stupid -- but why not just replace the index page with an html page with 'temporarily unavailable' text ?


Feb 25, 2009 at 6:57 PM // reply »
10,640 Comments

@Alexander,

The difference is that people might access pages that are NOT the index page. By marshaling the request itself, we can make sure to block all requests - not just that to the index page.


Oct 19, 2009 at 12:15 PM // reply »
6 Comments

This is very helpful. One minor problem I came across is that setting the status code to 503 seems to automatically output "The service is unavailable." to the body of the response as well as the header. Since the site I'm working on has to be down for a significant amount of time, and I have a pretty page to display while it's down, this is inconvenient. I got around this by setting the text color to the same color as the background, but I'm wondering if anyone know how to get ColdFusion to suppress the output in the response body? I'm using ColdFusion 8. Thanks!


Oct 19, 2009 at 1:10 PM // reply »
6 Comments

Well, to follow up on my previous comment ... I tried the same thing on the different server and "The service is unavailable." was not included in the response body. The only significant difference between the two servers that I can think of is that the one displaying the text is Windows 2008, and the other one is Windows 2003. I can only assume at this point that it's IIS7 that is to blame, but I don't really know at this point.


Oct 31, 2009 at 4:48 PM // reply »
10,640 Comments

@David,

I don't think I've ever played with a Windows 2008 server, so there could easily be differences in the IIS versions being used. Thanks for the input.


a
Jan 5, 2010 at 5:23 AM // reply »
1 Comments

Hi guys,
I'm new to ColdFusion and perhaps my question will seem a bit stupid -- but why not just replace the index page with an html page with 'temporarily unavailable' text ?


Jan 5, 2010 at 7:56 AM // reply »
10,640 Comments

@A,

You can do that if you want; but the reason behind a CFM page is that all requests to the server will be routed through the Application.cfc, which can manage the request in any way that it sees fit.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 12, 2012 at 3:37 AM
Learning ColdFusion 8: CFImage Part III - Watermarks And Transparency
Hi Ben, Just to ask currently it is placed bottom right corner, if i need to replace the same rendered image on the bottom left side or in the bottom center, how that can be calculated. bottom ce ... read »
Feb 11, 2012 at 9:29 PM
Use jQuery's SlideDown() With Fixed-Width Elements To Prevent Jumping
I can't say how glad I am that I found your post. Thank you very much. ... read »
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »