Wednesday, April 16, 2014

IIS 7, Railo and Rewrite Rules (SES)

I recently added the "suggested" SES rewrite rules for my Coldbox app.  I use IIS7 along with Railo Tomcat.  After the rewrite rules were added to my web.config file and uploaded, my Railo admin became (keywords coming:) ugly, unusuable, missing CSS, no style, missing images...just horrible!

You're a developer.  You've been searching for a while.  (Because you didn't find this post sooner.)  You are struggling with getting the Railo Admininistrator screen to look like it ought to.  Everyone says "Oh...sorry, we don't use IIS."  Or those that do say "Oh...sorry, we use Helicon Rewrite engine."  Or even better: "Windows?  Sorry, man..."

I stumbled on a post finally after getting some community attempts at helping, but no real answer.  I don't have the link to the post handy, but at the end of the discussion, the fella said "Okay, well, I'll go back to using Path_Info."   For me, this was for Coldbox and Railo on IIS.  Perhaps you're using CFWheels or another framework where the SES requires rewrite rules.

The rule I had found initially used SCRIPT_NAME.  Not sure if that's an IIS vs. Railo vs. Tomcat problem, but I gave it shot.  It worked!  No more ugly Railo admin screens.  I could actually see what I was doing in there!  (When it doesn't work, and tries to rewrite the Railo links, you might be butchering your error logs for your app, as well as confusing your IIS log files, I'm sure.)

Here's my current rule from my web.config.  (Or you can adapt it for the visual interface in the IIS admin, if you need to.)

<rule name="Application Administration" stopProcessing="true">
<match url="^(.*)$" />
<conditions logicalGrouping="MatchAll">
<add input="{PATH_INFO}" pattern="^/(.*(CFIDE|cfide|CFFormGateway|jrunscripts|railo-context|fckeditor|ckeditor)).*$" ignoreCase="true" />
<action type="None" />

Rules you may have found previously may use SCRIPT_NAME.  Try swapping it out.  Hope you found this and it solved your problem in 5 minutes instead of the week I've been needing an answer.

- Will Belden
April 16, 2014

Monday, April 14, 2014

Coldfusion 8 and Decrypt function

Found an interesting item today in Coldfusion.

Apparently decrypt() in Coldfusion (8, at least) can apparently figure out when you intentionally change an encrypted value and still decrypt it.

Sublime - Key Binding for Toggle Word Wrap

Tired of choosing the View menu, then Word Wrap?  Are you a keyboard person, not a mouse person?

This will save you a little bit of time.  Add this key binding line to your "Key Bindings - User" to eliminate the new for mouse work.

{ "keys": ["ctrl+shift+w"], "command": "toggle_setting", "args": {"setting": "word_wrap"}}

You can certainly change the key combination to your liking.

For me, this is actually replacing the "close window" default binding.  I can hit ALT+F to bring up the file menu and then "x" to Exit the application just fine.  (Been doing that for years.)  Or even ALT+F4.  Or CTRL+W repeatedly (closes files, then the the application when there are no more open documents.)  I simply don't need yet another "exit the application" keyboard shortcut.

- Will Belden
April 14, 2014

Saturday, April 12, 2014

Coldfusion: Easy Timers for your objects

I've been really getting into logging lately.  A good friend of mine, through repeated "Gibbsing", wore me down on it, and I really do like using it.  (We'll talk about unit testing another time.)  It really helps to leave debugging statements in your code, re-enable debugging for that class later and get an insight into what was going on when you haven't looked at the code for a year.

I'm also a big user of Coldbox.  Therefore it is only logical that I also use Logbox, which is heavily modeled on Log4J.  Now, my solution here is really for classes and components (*.cfc files), not so much for *.cfm files.  Though you could easily put this into an application function or anywhere you want that's easy to access.  Would not take much tweaking at all.  In my case, I'm using this in my Service Layer, where 99% of my objects all inherit from a Base.cfc class.  Here are the functions I added to the Base.cfc component.  (I've stripped off some of the hints for clarity here in the post..)

Sorry for the small font, the layout here isn't very conducive.  Just copy to your favorite editor (Sublime?) to view in a larger font.

Coldfusion Code:

<!--- --------------------------------------------------------------------- --->
<!--- Add to your init() or preconstructor:  --->
<!--- --------------------------------------------------------------------- --->
<!--- <cfset variables.stTimers = {} /> --->
<!--- <cfset variables.nTimerTimeoutMS = 600000 > --->
<!--- --------------------------------------------------------------------- --->
<cffunction name="startTimer" access="private" returntype="string" output="false">
<!--- For Railo only, in CF use createUUID --->
<cfset var sHandle = createUniqueID() />

<cfset purgeTimers() />
<cfset variables.stTimers[sHandle] = getTickCount() />
<cfreturn sHandle />

<!--- --------------------------------------------------------------------- --->
<cffunction name="endTimer" access="private" returntype="numeric" output="false">
<cfargument name="handle" type="string" required="true" />

<cfset local.nTimeInMS = -1 />
<cfif structKeyExists(variables.stTimers, arguments.handle)>
<cfset local.nTimeInMS = getTickCount() - variables.stTimers[arguments.handle] />
<cfset structDelete(variables.stTimers, arguments.handle) />

<cfreturn local.nTimeInMS />

<!--- --------------------------------------------------------------------- --->
<cffunction name="purgeTimers" access="private" returntype="void" output="false">
<cfloop collection="#variables.stTimers#" index="local.sPurgeHandle">
<cfif getTickCount() - variables.stTimers[local.sPurgeHandle] GT variables.nTimerTimeoutMS>
<cfset structDelete(variables.stTimers, local.sPurgeHandle) />

Usage within inherited objects, in this case in conjunction with Logbox debug logging:

<cffunction name="myFuncNeedingTiming">
<!--- 'log' is in my component's 'variables' scope --->
<!--- *Always* wrap debugging code with log.canDebug() --->
<cfif log.canDebug()>
<cfset local.sTimerHandle = startTimer() />

<cfset someOperationThatWillTakeSomeTime() />
<cfset anotherOperationThatWillTakeSomeTime() />

<cfif log.canDebug()>
<!--- Sending the handle back, will kill the timer and return the milliseconds --->
<cfset log.debug('myFuncNeedingTimer complete in #endTimer(local.sTimerHandle)# ms') />

Fairly easy to implement, should be mighty fast.  In the case of a transient bean inheriting from your Base class, you could modify to add another variables (or override in your BaseBean/BaseEntity class) for whether purging should be performed or not.  (Or create an override function that does nothing.)

Seemed like an idea worth sharing!

- Will Belden
April 12, 2014