Apache Ninja Crash Course for Developers - cf.Objective() 2013 - Slides Online
The slides for my cf.Objective() 2013 presentation are now online:
Apache Ninja Crash Course for Developers
Thank you to all who attended!
The slides for my cf.Objective() 2013 presentation are now online:
Apache Ninja Crash Course for Developers
Thank you to all who attended!
Adobe's second ColdFusion Developer Week kicks off today, June 4, and continues through Friday, June 8, 2012. Whether you're a new or experienced CFML developer, there's probably more than one session you'll find very interesting and useful. From basics to advanced language features, as well as frameworks and a focus on the new ColdFusion 10 release, there's just loads of good stuff, all provided via free online Webinars.
Check out the sessions and schedule, and sign up.
Like last year, I'll be presenting Improve Your Apps Through Unit Testing, tomorrow.
I also hope to revive this sleepy blog with some more interesting tid-bits soon, so stay tuned! It's been a busy year, but I've queued a number of topics for blog posts, so hopefully I can catch up a little in the near future.
I often use Tomcat as my servlet container to power my CFML apps (works great for ColdFusion, Open BlueDragon and Railo!). I've been perfectly happy with the power and flexibility of using Apache HTTPD's mod_rewrite with an AJP proxy, as Sean Corfield has detailed. Then, after repeating a lot of rewrite rules in all of my virtual host definitions, I decided to merely place the following in my main Apache configuration file:
That's it! Now, any Apache virtual hosts for CFML application can be defined as simple as this:
I can still easily add URL rewriting to my Apache virtual hosts. For example, when using Mura CMS I often set the properties siteIdInURLs=0 and indexFileInURLs=0 to make super clean looking URLs (with no siteID or index.cfm in the URLs). This then of course requires a rewrite rule to ensure the proper requests are passed to Tomcat, which is as simple as adding these lines to your virtual host (or an .htaccess file in your Web root):
Makes all the configuration I used in this post look a bit silly now :P
Also, if you're interested in a clean, production-worthy server setup running on Ubuntu 10.04 with Railo, Tomcat, Apache and MySQL, I have this fairly well documented in this Google Doc.
I've enjoyed leveraging Apache mod_rewrite and mod_proxy to leverage both the power of URL rewriting and the APJ proxy to proxy CFML requests to Railo running on Tomcat. I allow Apache to still handle requests for static assets (images, javascript, etc.). Today, I ran into a problem when I wanted to slap some basic authentication on a site. Requests handled entirely by Apache (static assets) were challenged for authentication, but CFML requests were proxied to Tomcat without requiring authentication. It makes perfect sense, as did the solution once I found it, but it just didn't occur to me at first.
First, here's a quick example of a basic virtual host that I'd use:
After creating a password file using the htpasswd command, I thought I'd simply add the following inside my VirtualHost to provide basic authentication.
Unfortunately, as I mentioned, this only protected non-proxied requests. Fortunately, I found the tip for my solution relatively quickly at stackoverflow, here. I simply needed to apply the same authentication directives within the Proxy context.
Here's the revised virtual host with basic authentication for both static assets and those proxied to Tomcat:
I find myself doing the same thing with nearly every Web site that I launch on my VPS (and client VPS/dedicated servers). I was to use http://www.domain.com as the primary host and have http://domain.com permanently redirect (301) while keeping the request URI intact.
Today, I decided to simplify this configuration by using a single Apache virtual host to handle all "www redirects." I thought I'd share this simple little tip.
When using name based hosting with Apache, this is very simple with mod_rewrite:
Now, as I add other virtual hosts to the server, I need only add a ServerAlias line to the above virtual host and I'm good to go.
I've discovered a bit of a bug in the way Mura CMS handles 404s and wanted to share my workaround. Valid path_info for Mura pages consist of only letters, numbers, hyphens and forward slashes. If you browse to a path that doesn't exists, Mura properly throws a 404 error -- well, sometimes...
If it's a valid Mura formatted URL, you'll get a 404. For example:
http://www.getmura.com/index.cfm/i-do-not-exist/
...however, if the path_info is not "valid," Mura seems to ignore it and display the home page -- for example:
http://www.getmura.com/index.cfm/i-do-not-exist.html
On some sites, you might not care about this, but Google and other spiders can become very suspicious when non-existent URLs return a 200 response instead of a 404. I discovered this when our SEO/content guru was having trouble getting Google Webmaster tools to verify after I uploaded the specified uniquely-named html file. Google refused to authenticate us, because they were attempting to "test" for a 404 and instead got 200 responses. I assume they just make up a random file name or path and expect a 404. It makes sense that they want to ensure that the site doesn't return a 200 OK for everything, because they can not count on the 200 from the authenticity file/URL to be true.
You can leverage URL rewriting as one workaround, as I have. Based on the standard default site URL format of Mura CMS, you can use something like the following with Apache mod_rewrite to force a Mura 404 when an "invalid" path_info exists:
UPDATE, 8/31/2010: I'm going with a simplified approach these days, as posted here.
I've worked with Apache mod_rewrite quite a bit in the past, but never got into any terribly complex rewrite rules. On average, I've probably leveraged about 2% of the incredible potential power that mod_rewrite offers. More recently I finally had the opportunity to learn a bit more and leverage this handy tool. My rewrite rules evolved over the past couple months as I got into testing out the Railo CFML engine a bit more, and then while setting up my first Mura CMS powered site. I thought I'd share what I've learned, as others may be likely to use some or all of this type of Apache virtual host configuration.
Here's a run-down of the "end goal," if you will, which I will walk through step by step to recap the problems and solutions I discovered along the way:
Please note that the following Apache modules must be activated in your Apache configuration: mod_rewrite, mod_proxy and mod_proxy_ajp.
I'll simply direct you to existing resources for this first bit and then show my basic example virtual hosting configuration. First, I'm running Railo in a multi-web setup on a single instance of Tomcat, which Sean Corfield has nicely outlined here (including a kind nod to a prior blog post of mine :). I learned a very nice means of proxying CFML requests from Apache to Tomcat thanks to this Sean Corfield post, which was prompted by some helpful comments from Barney Boisvert on Sean's prior post.
So here is an example Apache virtual host:
Okay, the above gets Apache proxying standard *.cfm/*.cfc requests to Tomcat for Railo to handle, but a request to http://railocmstest/index.cfm/some-path-info/ will simply throw a 404 error, because Apache finds neither file nor directory at /var/www/railocmstest/webroot/index.cfm/some-path-info/. Plus, the current rewrite rule is not even proxying this type of request to Tomcat, because the regular expression used only looks for any URI that ends with ".cfc" or ".cfm".
Simply change this line:
...to this:
Okay, now if we reload Apache the http://railocmstest/index.cfm/some-path-info/ will indeed be proxied to Tomcat, however, now we just get the 404 error from Tomcat instead of Apache! Not a problem -- I picked up another trick from a comment by Tony Garcia on, again, this Sean Corfield post. In either our Tomcat's conf/server.xml file or in our Web root's WEB-INF/web.xml (you can create one if it doesn't exist) file, add the following servlet mapping:
Just be sure the servlet name you use here matches the one used for Railo, which is CFMLServlet by default, but I change mine to GlobalCFMLServlet in my multi-web setup as explained here.
We can now restart our Tomcat service and http://railocmstest/index.cfm/some-path-info/ is now good to go -- no more 404 error and cgi.path_info will now properly return /some-path-info/.
You may be inclined to try a URL pattern of /*.cfm/* in your servlet mapping, as I was, but it will not work as expected. If you also need URLs ending with /other.cfm/path-info/ and /app/index.cfm/path-info/, for example, you'll have to add two more servlet mappings with URL patterns /other.cfm/* and /app/index.cfm/*.
A simple way to hide your Railo Admin URLs is to use one rewrite rule to forbid access to any paths beginning with /railo-context/admin/ and use some unusual URL to proxy in its place:
After an Apache reload, the above rewrite rules will cause a 403 (Forbidden) error to be thrown at http://railocmstest/railo-context/admin/index.cfm, but you can find what you're looking for at http://railocmstest/SOMETHING-DIFFICULT-TO-GUESS/admin/index.cfm with no problem. In this Railo Google Groop thread Sean Corfield also suggests using a separate virtual host to access your admin, which can listen on an unusual port. You could also use SSL to encrypt transmissions at the admin URLs.
"Out of the box," Mura CMS has relatively friendly, SES URLs of the form http://host/siteid/index.cfm/something-friendly/, but we can do better. In the helpful Mura forums I quickly found the information I needed to make very quick changes to the Mura code to get rid of the /siteid/index.cfm portion of the URLs generated. Since there were two steps, in two different threads, plus one other tweak I found necessary, I posted a summary thread to a Mura forum. The rewrite rule example I provide in the form thread is more generic, intended to work without consideration for Tomcat proxying, Railo Admin hiding, etc., so here's what I've actually done for my first Mura CMS powered site...
I found that I needed to cover a few extra use cases. These four situations must be covered:
...and here it is:
If you're wondering why I have rewrite conditions with %{DOCUMENT_ROOT}%{REQUEST_URI} instead of %{REQUEST_FILENAME} when checking for file/directory existence, it's because the latter just didn't work for me! All examples I've seen suggest the latter, but it just didn't work -- possibly something Ubuntu-specific, or something that I changed elsewhere in my Apache configuration? I don't know, but what I've used should work on any setup.
I've discovered a little bug in Mura CMS regarding the handling of would-be 404 pages, so the last two rewrite rules from above must be changed to be less broad and an additional final rule can be added to still leverage the friendly/skinned Mura 404 page (rather than Apache's default 404):
I've also updated the following Complete Package section to reflect these updates...
So, here is the complete virtual host example, incorporating all of the above:
Cheers!