Using Adobe cf_scripts in CommandBox behind IIS/Boncode
This post falls in the category of something I hammered out for a client today and I thought to myself, "Wow, that's just obscure enough that no one would probably figure it out on their own." As such, I figured I'd put it into a blog post for Google to index and for me to point people to in the future.
If you use any of the CF UI tags, CFChart, CFForm, or CFAjax functionality, then you need to have some web accessible JS, CSS, etc files for it to function. In older versions of CF, this was under the /CFIDE folder which wasn't very cool since it made it harder to block access to that folder by default. On the most recent versions of Adobe CF, you can hit it as /cf_scripts and the IIS connector has a built in handler that passes those requests through.
So let's talk about CommandBox-powered Adobe ColdFusion sites. CommandBox doesn't use the custom version of Tomcat that Adobe ColdFusion's "standard" installation uses and it also won't work with Adobe's special IIS connector. CommandBox has a powerful (and fast) Java based web server built into it which can service most all of your needs, but if you do want to sit a CommandBox-powered server behind IIS (Be it Adobe CF or Lucee), I recommend using the Boncode AJP IIS connector as it is standards compliant and works very well. The docs for Boncode mention Tomcat a log, but ignore that. Really it works with any AJP listener.
Here is a screencast that I recorded a while back that shows how easy it is to set up an IIS Boncode connector to a CommandBox site.
The /cf_scripts Folder
So now to the point of this post. The cf_scripts folder is available directly on a stock CommandBox ColdFusion 2016+ server in two different places:
Both of those top level folders are special URL aliases that CommandBox creates when it detects it's starting a ColdFusion server. However, neither of those will likely work when you hit your site via IIS. Firstly, you likely have no virtual directory for CFIDE and you shouldn't. That entire folder should be blocked for security. I recommend the following chunk in your site's web.config in fact:
<security> <requestFiltering allowDoubleEscaping="true"> <hiddenSegments> <add segment="CFIDE" /> </hiddenSegments> </requestFiltering> </security>
The second URL also won't work since there's no actual cf_scripts folder in your IIS web root and since the .js files in there aren't a .cfm or .cfc extension, they won't trigger the Boncode handler. Instead, IIS will try to process the request with its default static handler which will give you a 404.
One possible solution would be for you to create a /cf_scripts virtual directory in IIS which will work, but since the actual server home in Command is long and not known until the server starts, that is a difficult option to automate so it "just works". You might be thinking about creating a wildcard handler mapping like cf_scripts/* but it turns out IIS doesn't treat those like you expect and it doesn't work for all sub folders.
The fix is pretty simple, and it is to add this chunk to your web.config file which adds the Boncode handler to the entire cf_scripts folder, which causes IIS to pass these requests along to CommandBox, where it's built-in /cf_scripts alias will direct the request to the correct folder, regardless of where your server home is.
<location path="cf_scripts"> <system.webServer> <handlers> <add name="BonCode-Tomcat-cf_scripts-Handler" verb="*" path="*" type="BonCodeIIS.BonCodeCallHandler"/> </handlers> </system.webServer> </location>
This is much more portable than a virtual directory since it doesn't need to know where your CommandBox server home lives.
So if you're just here looking for the solution and don't' care about the setup, here's my full web.config file that has the default Boncode connectors as well as the section to make the cf_scripts folder work:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <location path="cf_scripts"> <system.webServer> <handlers> <add name="BonCode-Tomcat-cf_scripts-Handler" verb="*" path="*" type="BonCodeIIS.BonCodeCallHandler"/> </handlers> </system.webServer> </location> <system.webServer> <security> <requestFiltering allowDoubleEscaping="true"> <hiddenSegments> <add segment="CFIDE" /> </hiddenSegments> </requestFiltering> </security> <defaultDocument> <files> <add value="index.cfm" /> </files> </defaultDocument> <handlers> <add name="BonCode-Tomcat-CFC-Handler" path="*.cfc" verb="*" type="BonCodeIIS.BonCodeCallHandler" preCondition="integratedMode" /> <add name="BonCode-Tomcat-CFM-Handler" path="*.cfm" verb="*" type="BonCodeIIS.BonCodeCallHandler" preCondition="integratedMode" /> </handlers> </system.webServer> </configuration>