Sunday, July 3, 2016

About Application.cfc

Pet Peeve: Proper Capitalization Of Application.cfc --- It's kinda nitpicky, but I hate seeing people write application.cfc/cfm. On a windows machine, it won't hurt. But putting that on a case-sensitive system, like Linux, will quickly teach you the difference between application.cfc and Application.cfc. I'm all for consistency. If you make it a habit to write Application.cfc, even when you don't have to, you won't accidentally mis-name the file when you create it.

That said, this is a topic that has been written about ad nauseam over the years, but it's VERY important to grasp the underlying framework of the Application.cfc file.

https://helpx.adobe.com/coldfusion/cfml-reference/application-cfc-reference/application-variables.html

/**
@title "Application.cfc reference in CFScript for Coldfusion 9"
@description "This component includes all Application.cfc methods and variables, set to their default values (if applicable). Please note that default values are not always desirable, and some methods or variables should be modified or removed depending on the situation."
@author "Russ S. (http://cfruss.blogspot.com)"

@dateCreated "November 29, 2009"
@licence "This work is licensed under the Creative Commons Attribution 3.0 United States License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA."

@hint "You implement methods in Application.cfc to handle ColdFusion application events and set variables in the CFC to configure application characteristics."
*/


component output="false" {

/* **************************** APPLICATION VARIABLES **************************** */

// The application name. If you do not set this variable, or set it to the empty string, your CFC applies to the unnamed application scope, which is the ColdFusion J2EE servlet context.
THIS.name = "";

// Life span, as a real number of days, of the application, including all Application scope variables.
THIS.applicationTimeout = createTimeSpan(0, 1, 0, 0);

// Whether the application supports Client scope variables.
THIS.clientManagement = false;

// Where Client variables are stored; can be cookie, registry, or the name of a data source.
THIS.clientStorage = "registry"; //cookie||registry||datasource

// Contains ColdFusion custom tag paths.
THIS.customTagPaths = "";

// The Google Maps API key required to embed Google Maps in your web pages.
THIS.googleMapKey = "";

// Name of the data source from which the query retrieves data.
THIS.datasource = "";

// Whether to store login information in the Cookie scope or the Session scope.
THIS.loginStorage = "cookie"; //cookie||session

// A structure that contains ColdFusion mappings. Each element in the structure consists of a key and a value. The logical path is the key and the absolute path is the value.
THIS.mappings = {};

// Whether to enable validation on cfform fields when the form is submitted.
THIS.serverSideFormValidation = true;

// Whether the application supports Session scope variables.
THIS.sessionManagement = true;

// Life span, as a real number of days, of the user session, including all Session variables.
THIS.sessionTimeout = createTimeSpan(0, 0, 30, 0);

// Whether to send CFID and CFTOKEN cookies to the client browser.
THIS.setClientCookies = true;

// Whether to set CFID and CFTOKEN cookies for a domain (not just a host).
THIS.setDomainCookies = false;

// Whether to protect variables from cross-site scripting attacks.
THIS.scriptProtect = false;

// A Boolean value that specifies whether to add a security prefix in front of the value that a ColdFusion function returns in JSON-format in response to a remote call.
THIS.secureJSON = false;

// The security prefix to put in front of the value that a ColdFusion function returns in JSON-format in response to a remote call if the secureJSON setting is true.
THIS.secureJSONPrefix = "";

// A comma-delimited list of names of files. Tells ColdFusion not to call the onMissingTemplate method if the files are not found.
THIS.welcomeFileList = "";

// A struct that contains the following values: server, username, and password.If no value is specified, takes the value in the administrator.
THIS.smtpServersettings = {};

// Request timeout. Overrides the default administrator settings.
THIS.timeout = 30; // seconds

// A list of ip addresses that need debugging.
THIS.debugipaddress = "";

// Overrides the default administrator settings. It does not report compile-time exceptions.
THIS.enablerobustexception = false;

/* ORM variables */

// Specifies whether ORM should be used for the ColdFusion application.Set the value to true to use ORM. The default is false.
THIS.ormenabled = false;

// The struct that defines all the ORM settings. Documentation: http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSED380324-6CBE-47cb-9E5E-26B66ACA9E81.html
THIS.ormsettings = {};

// note: THIS.datasource applies to cfquery as well as ORM. It is defined on line 31.


/* **************************** APPLICATION METHODS **************************** */


/**
@hint "Runs when an application times out or the server is shutting down."
@ApplicationScope "The application scope."
*/
public void function onApplicationEnd(struct ApplicationScope=structNew()) {

return;
}


/**
@hint "Runs when ColdFusion receives the first request for a page in the application."
*/
public boolean function onApplicationStart() {

return true;
}


/**
@hint "Intercepts any HTTP or AMF calls to an application based on CFC request."
@cfcname "Fully qualified dotted path to the CFC."

@method "The name of the method invoked."
@args "The arguments (struct) with which the method is invoked."
*/
public void function onCFCRequest(required string cfcname, required string method, required string args) {

return;
}


/**
@hint "Runs when an uncaught exception occurs in the application."
@Exception "The ColdFusion Exception object. For information on the structure of this object, see the description of the cfcatch variable in the cfcatch description."
@EventName "The name of the event handler that generated the exception. If the error occurs during request processing and you do not implement an onRequest method, EventName is the empty string."

note: This method is commented out because it should only be used in special cases
*/
/*
public void function onError(required any Exception, required string EventName) {
return;
}
*/


/**
@hint "Runs when a request specifies a non-existent CFML page."
@TargetPage "The path from the web root to the requested CFML page."
note: This method is commented out because it should only be used in special cases
*/
/*
public boolean function onMissingTemplate(required string TargetPage) {
return true;
}
*/


/**
@hint "Runs when a request starts, after the onRequestStart event handler. If you implement this method, it must explicitly call the requested page to process it."
@TargetPage "Path from the web root to the requested page."
note: This method is commented out because it should only be used in special cases
*/
/*
public void function onRequest(required string TargetPage) {
return;
}
*/


/**
@hint "Runs at the end of a request, after all other CFML code."

*/
public void function onRequestEnd() {
return;

}


/**
@hint "Runs when a request starts."
@TargetPage "Path from the web root to the requested page."
*/
public boolean function onRequestStart(required string TargetPage) {

return true;
}


/**
@hint "Runs when a session ends."
@SessionScope "The Session scope"

@ApplicationScope "The Application scope"
*/
public void function onSessionEnd(required struct SessionScope, struct ApplicationScope=structNew()) {

return;
}


/**
@hint "Runs when a session starts."
*/
public void function onSessionStart() {

return;
}

}

Tuesday, June 14, 2016

CF_PublicServiceAnnouncement: Updates Galore!

First off, Adobe has released new patches for the ColdFusion products.This includes a Security Hotfix for CF2016, 11 and 10 for a potential XSS issue, so it would probably be a good idea to update.

http://blogs.coldfusion.com/post.cfm/updates-for-coldfusion-2016-coldfusion-builder-2016-coldfusion-11-and-coldfusion-10-released

Also today, Lucee 4.5.3 has been released with a heap of fixes.

http://lucee.org/blog/lucee-4-5-3-release.html


Wednesday, June 8, 2016

ColdFusion Scopes: Part Deux - "Mutually Exclusive" LOCAL and ARGUMENTS

While playing with LOCAL and ARGUMENTS scopes and the scope order bug, I also came across a behavior that I didn't really know about - LOCAL and ARGUMENTS scopes in a CF function are supposed to be "mutually exclusive". Maybe I misunderstand what that phrase means.

https://gist.github.com/shawnoden/ef494ef92ccd3821a189 http://help.adobe.com/en_US/ColdFusion/10.0/Developing/WSc3ff6d0ea77859461172e0811cbec09af4-7ff1.html http://help.adobe.com/en_US/ColdFusion/10.0/Developing/WSc3ff6d0ea77859461172e0811cbec0a66e-7fe2.html http://help.adobe.com/en_US/ColdFusion/10.0/Developing/WSc3ff6d0ea77859461172e0811cbec09af4-7fdf.html

Friday, May 27, 2016

Security+ Certification!

After weeks of study, I am now officially CompTIA Security+ Certified!



This is my happy face >> :-)

Monday, May 2, 2016

Testing: A Confession

I have a confession to make. In the software world, this confession probably ranks right up there with kicking kittens or believing that Firefly deserved to be cancelled, but it's one that I still feel I should make. I've been a developer for over 15 years, and almost all of that time has been spent NOT WRITING TESTS. I have always done the traditional developer QA and smoke testing, but I have spent years making all sorts of excuses as to why I don't actually write tests: I don't have the time to do it. My company's infrastructure isn't set up for it. We have a QA team that does our testing. Or my favorite: We have a mass of legacy code and it's too hard to test.

Those may be some valid "reasons", but they're really just excuses.

I'm a hypocrite, too. I've known the value of testing for most of my career. I've preached that it should be done. But I've never really strongly advocated for it where I've worked. I'm changing that.

I work on a fairly significant code base that doesn't currently have any tests. We constantly make changes and we deploy often. In the last couple of weeks, I've been bitten twice by code that I just created that affected other pieces of my site in ways that I didn't expect. Proper Unit Tests would have picked up those regressions before I ever even checked in my code. So this has given me a bit of a kick to actually start doing something about it. I'm fortunate in that I have a few allies at work who see this need, too. I don't have to be the new guy bucking the system.

We work mostly with ColdFusion and jQuery, so a large hurdle has been just figuring out what the best way to test is. I've chosen Ortus' TestBox for my CF code. It's got great support. It's fairly easy to setup and use. I like it a lot. I've only got a couple dozen tests in place, but I already see several ways that I should have written my code better. I'm seeing some things that appear to be hard to test, but I think that's because I'm just not well-versed in actually testing software like this. I'm determined to get much better at it.

I've confessed my sin. I don't really feel that much better, but let the adventure begin.

Tuesday, April 26, 2016

[REVIEW] Guess What Came In The Mail: Pine64


I am fascinated with tiny computers and the things that a unit like the popular RaspberryPi enables. And when I saw the Pine64 on Kickstarter, I was intrigued. A 64-bit computer for $15!!!! No way!!! I became a backer at the original $15 price (+shipping, but really, at this price shipping doesn't matter).

I watched the Kickstarter move to become a successfully funded project, and then watched some people get frustrated that they didn't get their P64 in February when originally told. Apparently they didn't think about what would happen to an unexpectedly popular and successful Kickstarter campaign. Plus, I guess I value my $15 pledge much less than some of them do. The way I look at Kickstarter, I fund the dreams of other people. When I tell them I'm gonna give them some $, it's a dream that I like, but still a DREAM. If their dream fizzles, then that sucks. I'm still glad I could help them realize their dream. But if they succeed and I get to be part of something cool, then Bonus For Me! I helped make a Veronica Marrs movie, and now I've helped make a $15 computer become a reality. Even if I saw nothing, it was all money well spent.

All that said...  I got a package in the mail today. Guess what it was.....

Guess what came in the mail!
Yup, I am now a proud owner of a 64-bit hand-sized computer with 2gb of memory!

When I first became a web monkey, I was building enterprise-level apps on a Pentium server that wasn't even in the neighborhood of thinking about multiple cores. I still have some "large" 256 MEGABYTE memory chips from those machines. I could build my entire system architecture in virtual machines on my laptop. The power that is now able to be packed into a palm-sized machine is crazy.

Anyway.... back to my mail.

I was an early backer of this thing, and more importantly, a believer. I was a bit giddy when I opened up my mailbox today. I knew what it had to be, but I still felt like a kid in a candy shop. So what did I get....

A PINE64!!! <shamelessPlug>www.pine64.org</shamelessPlug>

For those who haven't hear about this one, it's a VERY tiny computer, a lot like a RaspberryPi, but it's only about 15 bucks. You just can't beat that price. I saw it; I backed it; I bought some accessories: I have it now.
The Package Contents!

Here's my review:

In my former life as a Fulfillment Guy, I would have wanted to use sturdier packaging to prevent damage in transit. I received this thing, with the accessories I ordered, in a normal padded envelope. I would have preferred heftier packaging, but nothing was even remotely damaged, and most importantly, let's not forget that this is essentially A $15 COMPUTER!!!

When I unpacked everything, I assumed that the larger box was the actual unit. WRONG. That was the acrylic case that I ordered. The unit is TINY. To be fair, it's larger than my older model RaspberryPi, but if I hold it up next to another motherboard, I'm not sure this scale is much of an issue.


After getting everything unpacked, I began putting it all together. I bought the acrylic case from the site, and it's a little bit bigger than I thought it would be. I expected something more commensurate with the form-factor of the unit itself. But the size isn't really an issue, because the case looks AWESOME!

Pine64 Acrylic Case
To this point, putting the thing together has been dead simple. The hardest part I've found so far is WHERE ARE ALL MY POWER STRIPS???

Now that I've found power, I need to crank this thing up. But a computer won't do much without some sort of operating system. I was lazy. I went for the first option on the Pine64 Wiki (wiki.pine64.org): Debian Linux with Mate GUI by lenny.raposo. Thank you, Lenny!

  • I used my RasPi tools to prep the SD card for the OS: SDFormatter to prep the disk and then Win32DiskImager to write it. It was a 1.4gb download, but it extracted to an 8gb image. Make sure you have enough SD card for it.
  • Pine64 vs Mobo
  • One very big difference between this and the RasPi is in the size of the card the OS runs on. RaspberryPi runs on a full-sized SD card. The Pine64 runs on a micro-SD card. Many modern SD cards already come with an adapter for a micro-SD to a full-size SD port, but we don't need the adapter here.

RasPi vs Pine64
This unit is tiny. But it's still larger than my older RaspberryPi. However, to put it into perspective, it's not even worth comparing the size to a full motherboard.

Now that we're all hooked up, it's time for the moment of truth: Does this thing power on? Fewer things in life are more disappointing than spending time to carefully put together a computer only to have nothing happen when you finally push the power button.


FLASHY LIGHTS == POWER!!!

Ladies and Gentlemen, here we go......







AND..... BOOTED!!!

WE HAVE SUCCESS!!!!







CONCLUSION: In my very limited experience with small boards like the Pine64 or Raspberry Pi, I can't really give much of a valid comparison yet. However, I will say that I REALLY like the Pine64 so far. The unit itself was $24 for the 2gb model, and all-in-all, I think I spent a grand total of around $80 on this entire setup. And that includes two additional power supplies for my other RasPi units and two HDMI-to-DVI and -VGA adapters. The case is large, but it looks very nice. All-in-all, I am VERY pleased with this purchase.

Now the fun begins... what do I make with this thing?