Tuesday, January 12, 2016

ColdFusion WebSocket Proxy and IIS 8+ - 500 Error

Today I ran into an issue in my development environment that was one of those "Duh" moments. If you are using the WebSocket Proxy with IIS we already know the following is required.
  1. IIS 8+ with WebSockets Installed
    • Windows 8+ : Can be found in Control Panel > Programs and Features > Turn Windows Features on or Off > Internet Information Services > World Wide Web Services > Application Development Features > WebSocket Protocol (check it)
    • Windows Server 2012+ : Same as above but the steps are a few more screens. You may also start from the Server Manager (Top Right: Manage > Add Roles and Features)
  2. Run wsconfigproxy.exe (as administrator) which can be found in {{ColdFusionInstallDir}}/cfusion/bin/wsconfigproxy.exe
  3. Set "Use Proxy" in ColdFusion Administrator (restart may be required if not already set)
At this point everything should work without a problem and most of the times it does. I have ran into permission issues, especially when you go thru the lock down guide and you did not set the required permissions on the config/wsproxy directory. If all the above is correct and you still have an issue, like I did today, check one last thing.

Last time I configured the app pool on this app I was testing I had set the .NET CLR Version to "No Managed Code" and when the cfws directory was created it used the parent App Pool. The fix is simple, set the .NET CLR version back to a valid version or create another App Pool with a CLR assigned and bind it to the cfws folder since it is created as a virtual application. Below are some images that show the error I was receiving (after I allowed errors to show on localhost) and how to assign the fix. An easy way to test that they can be connected to is by browsing to the /cfws/ path of your domain. In an http call you should receive a good 200 response.

Do not use a different app pool, just ran into an issue that when I sent a call to WsPublish on the server side it messed with my Session scope. The only fix is to make sure they both use the same App Pool and that it is set to use a .NET CLR. (duh moment #2 of the day)

Bad Request

Causes Error Works Again

Good Request

Wednesday, December 23, 2015

FusionReactor Developer Edition!!!!

I can't express how valuable FusionReactor is for me daily and today on their Holiday mailer I noticed bullet item #8 which stated "Introduced a FusionReactor Developer Edition". This bullet item got my attention, because I have a Developer subscription that is normally available after you have 1 Production license which comes at a lower cost. So I was wondering why it was a bullet item on their newsletter.

This now goes to another reason why I love this company so much, not just because their product is great but because you can reach out to them and they respond almost immediately (we are across the pond from each other). So I reached out to David and he confirmed this was a different and less expensive version than I was currently paying for. Merry Christmas!!!!!!

So here is the low down on this version.
The initial cost for this version is ONLY $199, which includes your very own perpetual license and the first year of updates. Renewing for updates annually is only $99, but if you decide to not renew you still own your license.

This is really great for them to offer for us and the savings over what was previously available even for the developer based subscriptions is HUGE!!!

This company does offer a great product and if you are using it on a production server I would say pay for the correct license as the product pays for itself. 

David will be posting a blog entry soon regarding this edition, until then, you can purchase the developer edition by using the following link.

Keep Calm and Carry On Monitoring :-)
Thanks for the cup at the ColdFusion Summit this year!

Thursday, December 3, 2015

Why does my onError() fail on Request Timeout?

So I guess today has become a day of tuning some things that have always driven me crazy. One of them was that when an error would happen on one of my sites and it was based on a request timeout I would not get my nice little error notification and users or clients would send me a screenshot of an IIS error template with ColdFusion dumping its ugly error in their face. This has always been quite embarrassing for me but then I would get busy doing other things and forget about it.

So this is an example of what I am talking about ...

In validating that we can keep learning something new everyday, I had no idea that in an error I can go ahead and increase the timeout for that request, allowing just enough time for my onError() function to process.

I figured this out because I did an abort as the first line of my onError() function and the error page did not show up, letting me know that it did execute. I then tried to do a writeDump() and the ugly error showed its face again. I then decided to do a cfsetting, thinking it would fail and to my surprise that worked. At this point I was hardcoding a new requesttimeout but I wanted it to not fail even on pages that already had larger request time out settings.

I needed a way to increase my current timeout setting and apparently executing a createObject could also be done. Thanks to Brian Ghidinelli for this post from 2009 on how to get the current RequestTimeout.

So in the end I did the following and now I do get my nice error notifications and my users never see that ugly error page again!

Disclaimer : The code above is only supported on ColdFusion 11 + as cfsetting is not supported in cfscript prior. If your Application.cfc is written in tags then you should have no problem writing the equivalent and if it is in cfscript you can include a template (also works) that simply has the cfsetting in tag.

Also for anyone that may want to test this on their own code, you can add the following on any template to fire off the request timeout error

Those damn BOTS!

So the other day a friend of mine experienced a high amount of Sessions running on their ColdFusion Server. After some troubleshooting it appeared that the high traffic that was causing issues was based on bot activity. He started working on some ideas on how to handle this and contacted me, which then got me interested in doing something for my servers as well.

Others have blogged about this before and his implementation is based on one of Ben Nadel's post which you can see here.

Now, I am a little less lenient on the thought of bots than my friend so I said "Hey why not block them at the Web Server level before it even hits ColdFusion (or any other language)". So while I may opt to block all bots from a web app that I do not care for them to index, he did not quite feel the same. For a website I can see where you may need to be a little more flexible, so I created a set of rules to block most and allow a selected few in.

The rules below allow for bots from Apple, Google, Bing, Yahoo, and Duck Duck Go to pass GO and collect $200. I have included both for IIS URL Rewrite and Apache mod_rewrite.

IIS 7+ using URL Rewrite

Apache using mod_rewrite

But how about them Sessions? Alex, I'll take killing sessions for $400, please.

Well, now with the rules in place blocking bat bots and only allowing a few in, I decided to run a function at onRequestEnd() that takes advantage of a new function since ColdFusion 10 called sessionInvalidate(). Thanks Charlie Arehart for reminding me of it while having a nice discussion on this topic this past CFSummit. As you can see below it is a simple reFindNoCase() on the same expression I used to allow bots in as defined in the RewriteRules.

ColdFusion 10+

I tested this using my trusty Fusion Reactor and seeing the session count go up 1 and back down 1 immediately was great, gratifying and ultimately validated my logic!

Please note, this will not change your CFID, CFTOKEN or JSESSIONID values, it simply kills the session each time. If you want new values, then you would need to do sessionRotate() as well but I did not see the need for it since as it will be only execute by bots. Also, if you are using J2EE Session Variables and want its ID reset, you will need to execute getPageContext().getSession().invalidate().

If you do have to support ColdFusion 9 or less, or some other ColdFusion engine, you can use something like Ben's solution and apply the logic to overwrite the SessionTimeout value.

Incidentally, my friend set the SessionTimeout to equal a function which then returned the TimeSpan based on his validations, rather than wrapping his validation around the settings like Ben did. I was originally worried about rewriting the SessionTimeout setting per request (which they both do), which is the reason why I opted for my way instead.

If you need to support another language, you can simply use the rules I have provided and based on how the language you are working with handles sessions, you can create a solution. Hope this helps some of you out, I know for me I rest a little better at night knowing that bots are not causing havoc on my apps and/or sites.

ColdFusion Summit 2015 Presentation Slides and Code

A little late to post, but I just wanted to say that  this year was another great experience at the CFSummit. Thank you to everyone involved and all the great feedback and interaction after my presentation, it was a very humbling and gratifying experience. Not to mention it was in the presence of my eldest daughter, so I can only say thank you for making me look cool to her, if it was only for a moment :-).

This year I was able to delve more into SSL and Cluster support with enough time to execute some quick demos. Although, my presentation skills till need a little work so I can get a good pace and get the information within the time allowed, the experience alone gave me the desire to improve and present on more things I find important.

I think I may start working on a subject that is very important to me, which is web performance and I am not talking about backend code alone but more in regards to the things we can do to make sure our requests are served as fast as possible and as small as possible. More to come on that topic later, but for now below are the links to the code and slides for this year's presentation.



Web Analytics