Coldfusion gateway, problem with application.cfc OnRequestStart - coldfusion

My application.cfc uses the OnRequestStart to check users are logged in
<cfif not isDefined("session.auth.isLoggedIn")>
<cfinclude template="loginForm.cfm">
<cfabort>
</cfif>
and this is mangling my attempts to use a gateway service which errors out with
Error invoking CFC for gateway watchInboundFiles: null {GATEWAYTYPE={FileWatcher},ORIGINATORID={},CFCMETHOD={onDelete},DATA={{FILENAME={C:\temp\New Text Document.txt},TYPE={DELETE}}},CFCPATH={F:\ColdFusion9\wwwroot\watch_dir.cfc},GATEWAYID={watchInboundFiles}}.
If I comment out the OnRequestSTart method the gateway works as expected.
Someone else ran into this before here and a solution is apparently to
add a new application.cfc which
extended my original but overrode the
onRequestStart() - which worked
perfectly.
So how do I do that please?

To answer your question:
Your new Application.cfc will live in another directory but extend your original:
<cfcomponent extends="path.to.my.original.Application">
<cffunction name="onRequestStart">
<!--- No login code here --->
</cffunction>
</cfcomponent>
All other functions are available as usual.
Hoep that helps! More info here.

You could also add something to the application.cfc to see if the call is coming from the gateway. If so then skip the if block.

Related

Coldfusion RESTful API, No Mapping Found error

This shouldn't be too hard to answer, but the discussions and documentation I've found can be rather unclear.
First of all, a little bit of information about my setup:
I'm on a hosted environment, and going through our ColdFusion admin group can be time-consuming. Therefore, I'm using the
restInitApplication function to register my RESTful web service.
My webroot folder (where my Application.cfm is located) is in
"E:\docs\wwwroot". I can only see, add, edit folders/files from
wwwroot down. I have no idea what's in "e:\docs". I believe that up
above where I cannot see there is another Application.cfm that sets
such things as the serverType (development, staging, or production),
that we (and other ColdFusion sites hosted on this server) use in
various places in our application code.
My pdfRestfulAPI.cfc (the component containing my webservice function) is in this folder,
"e:\docs\wwwroot\RESTservices". My component code looks like this:
<cfcomponent rest="true" >
<cffunction name="pdfconvert" access="remote" returntype="binary"
output="false" produces="application/xml" method="get" >
<cfargument name="sourceWebPageURL" type="string" >
<cfset pdfDoc = "" >
<cfdocument name="pdfDoc"
format="PDF"
src="#sourceWebPageURL#"
saveAsName="sample.pdf" >
</cfdocument>
<cfreturn #pdfDoc#>
</cffunction>
</cfcomponent>
The function itself is not an issue. It just converts a web page to pdf--pass a URL, get a PDF version of that web page. When I set it up as non-RESTful API (SOAP/xml) it works just fine.
In my Application.cfm, I am attempting to register my web service using the following code:
<cfset restInitApplication( getDirectoryFromPath(getCurrentTemplatePath())
& "RESTservices" ) >
This gives me a dir_path attribute of "E:\docs\wwwroot\RESTservices", which seems correct to me. I've omitted the optional mapping_name attribute. When the documentation says that this "can be anything", that is not helpful.
The error that I get in my Application.cfm reads:
coldfusion.rest.RestAppAdapter$InvalidApplicationException: No mapping
found for path E:\docs\wwwroot\RESTservices
Hopefully, I've laid out the details in such a way that anyone could try this out and let me know what I'm doing wrong.
Thanks, everyone!

Is there a way Coldfusion can send all errors to a specific email?

I have:
Server Details
Server Product ColdFusion
Version 9,0,1,274733
Edition Standard
Operating System Windows Server 2008
OS Version 6.0
Adobe Driver Version 4.0 (Build 0005)
Is it possible that I can receive all the errors that happen on coldfusion to a specific email?
If you don't want to add a cferror to every page you can add a onError method to your application.cfc this function will be called whenever any page has an error.
<cffunction name="onError">
<!--- The onError method gets two arguments:
An exception structure, which is identical to a cfcatch variable.
The name of the Application.cfc method, if any, in which the error
happened. --->
<cfargument name="Except" required="true"/>
<cfargument type="String" name = "EventName" required="true"/>
error handling goes here
</cffunction>
I also saw you had a question where you were worried about the mail server not working. If you are worried that you will not be able to receive emails about your errors you can log them to a file.
<!--- Log all errors in an application-specific log file. --->
<cflog file="filename" type="error" text="Event Name: #Eventname#" >
<cflog file="filename" type="error" text="Message: #except.message#">
Check out the cferror tag. It is exactly what you need.
You can put cferror in the Application.cfm file, if you are not using Application.cfc, and it will work on every page.
<cferror type="exception"
template="/error.cfm"
mailto="your#email.com"
exception="any">
This is the recommended way to email notification of errors pre CFMX7. It still works in CFMX7 and after but best practice suggests the use the onError() method of Application.cfc
wikidocs.adobe.com/wiki/display/coldfusionen/onError

Force coldfusion 8 to reload component cache?

ColdFusion 8 is caching my cfcs. Development is at a stand-still. I don't have access to the admin panel. What are my options?
1) Get access to CF Administrator.
Really. I wouldn't want to host anywhere where I didn't have control over this.
2) Programmatically clear the cache.
Using the Admin API:
createObject("component","cfide.adminapi.runtime").clearTrustedCache()
Of course, if you don't have access to the CFAdmin, you might not have access to this either, but is worth trying.
According to this blog entry from Ray Camden you'll need to login to the admin via the API before running the above command, which of course suggests it's not going to work without already having access.
<cfset API = createObject("component","cfide.adminapi.runtime") />
<cfset API.login(adminPassword="password") />
<cfset API.clearTrustedCache() />
I use application.cfc to clear all of the cfc cache.
<!--- *****************************************************************
Run before the request is processed
************************************************************--->
<cffunction name="onRequestStart" returnType="boolean" output="false">
<cfargument name="thePage" type="string" required="true">
<cfscript>
if (structKeyExists(url,'reinit')) {
structClear(application);
structClear(session);
onApplicationStart();
onSessionStart();
}
</cfscript>
<cfreturn true>
</cffunction>
The idea is to pass a url variable called "reinit". Whenever this variable is defined in the URL, the application is started.
In order to test this:
1. make a change to cfc
2. call a cfm page by xxx.cfm?reinit=1
3. observe the changes in the cfc are reflected.
hope it helps...
I know that this post is old, but I needed to do this for a (more) modern version of ColdFusion (2016) and the answer from Peter wouldn't work on CF 2016. Not looking to be the answer, just a footnote for newer versions of CF.
Here is a version that will work with CF 2016:
<cfscript>
variables['adminPW'] = "my cf admin password";
cfAdminAPIAdmin = createObject("component", "cfide.adminapi.administrator");
cfAdminAPIAdmin.login(variables.adminPW);
cfAdminAPIRuntime = createObject("component", "cfide.adminapi.runtime");
// clear the component and trusted (template) caches
cfAdminAPIRuntime.clearComponentCache();
cfAdminAPIRuntime.clearTrustedCache();
</cfscript>
Adobe appears to have separated the CF admin functionality from the runtime component. That's really the only difference. The version above shows how to clear the component cache too.
NOTE: I had been doing something very similar to CFNinja's answer, but one site (out of about 25 similar sites) just wouldn't clear the application scope components, the old version remained in a cache somehow.

restart application without restarting server?

Is there a way to restart a ColdFusion application without restarting the entire server?
There are two ColdFusion applications running on a server and I only want to restart one of them.
If you are using Application.cfc, you can update it so that you can force a call to onApplicationStart() if something specific is passed in the url, or something similar. Simply place a check for that magic token in onRequestStart(), and call onApplicationStart() if it is.
If you are not, you can try #Marcos's suggestion. I'm not sure what ramifications that may have in your application. What I would suggest is actually renaming your application, so it starts as a new app.
If you're on CF9, run ApplicationStop() https://cfdocs.org/applicationstop
Here you go, my CF7/8 version of CF9's ApplicationStop. I believe this is thread safe, noting Sean's comment.
<cffunction name="ApplicationStop" returntype="boolean" output="false">
<cfif IsDefined('application')>
<cftry>
<!--- This is just in case there's no app scope but variables.application --->
<cfset CreateObject('java', 'coldfusion.runtime.ApplicationScopeTracker').cleanUp(application) />
<cfreturn true />
<cfcatch type="any"></cfcatch>
</cftry>
</cfif>
<cfreturn false />
</cffunction>
As mentioned by Henry, he's my blog post on the subject:
http://misterdai.wordpress.com/2010/06/14/cf-flag-application-to-run-onapplicationstart-part-2/
A less invasive way of ending your app is to temporarily set the ApplicationTimeout to something very short.
Here is an example from an application.cfc file where the app is set to timeout in 10 seconds, which is plenty short for making a change and then checking back:
<cfcomponent displayname="Application">
<cfscript>
this.name = "myAppName";
this.setclientcookies="yes";
this.sessionmanagement="yes";
this.sessiontimeout= CreateTimeSpan(0,0,60,0);
this.applicationTimeout= CreateTimeSpan(0,0,0,10);
</cfscript>
...
</cfcomponent>
You might need to limit the session, too. See this article by Ben Nadel for an in-depth look at Application and Session timeouts.
If you are using application.cfc, stick this at the top of your onRequestStart function:
<!--- RESET APP? --->
<cfif isdefined("url.reinit")>
<cfset OnApplicationStart()>
<cfset OnSessionStart()>
</cfif>
Then you can pass a url var to any cfm and the app will reset.
<cfset structClear(application) />
I usually put a reference to each user's session into a struct in my Application scope to monitor what's going on in the app. Maybe doing something similar in the Server scope could help here. Try:
<cfset server.runningApplications["myApp"] = Application />
Then you'd have a reference to the actual Application object outside the scope of that application. You could try all manner of destructive things to get rid of it. Try this at your own risk!!! And do it on a dev server before you do it on your production box. ;)
Use cfinvoke.
<cfinvoke method="onApplicationEnd" component="Application">
<cfinvokeargument name="ApplicationScope" value="#application#" />
</cfinvoke>

Forcing HttpOnly cookies with JRun/ColdFusion

We need to ensure that all cookies on a CF7 site are set as HttpOnly.
We are using jsessionid to control our sessions, and JRun does not create this as HttpOnly.
Whilst it is possible to modify an existing cookie to add this setting, we need to have it set to HttpOnly from the start.
Any suggestions?
Related Question: Setting Secure flag for HTTPS cookies.
From: http://www.petefreitag.com/item/764.cfm
Running CF 8 or Lower and using Application.cfc
<cfcomponent>
<cfset this.sessionmanagement = true>
<cfset this.setclientcookies = false>
<cffunction name="onSessionStart">
<cfheader name="Set-Cookie" value="CFID=#session.CFID#;path=/;HTTPOnly">
<cfheader name="Set-Cookie" value="CFTOKEN=#session.CFTOKEN#;path=/;HTTPOnly">
</cffunction>
<cfcomponent>
Make sure you have setclientcookies = false specified.
If Using Application.cfm
If you are still using an Application.cfm file, you can use the following:
<cfapplication setclientcookies="false" sessionmanagement="true" name="test">
<cfif NOT IsDefined("cookie.cfid") OR NOT IsDefined("cookie.cftoken")>
<cfheader name="Set-Cookie" value="CFID=#session.CFID#;path=/;HTTPOnly">
<cfheader name="Set-Cookie" value="CFTOKEN=#session.CFTOKEN#;path=/;HTTPOnly">
</cfif>
First, a warm welcome to all PCI DSS refugees! Appscan, Webinspect, Hailstorm and NTOSpider fugitives are also invited. Take a seat right over here, I have cake for you:
While too late for Peter, it is in fact possible to have JRun generate HTTPOnly (and secure) cookies from the start as he asked. Look for the jrun-web.xml file. It will probably be in a directory like
C:\JRun4\servers\servername\cfusion-ear\cfusion-war\WEB-INF\.
You have to add the following to the cookie-config section:
<cookie-config>
<cookie-path>/;HttpOnly</cookie-path>
</cookie-config>
If your site is HTTPS, you should also enable the secure cookie option. But be careful, its server wide, not application specific. So it may not be suitable for your shared environment:
<cookie-config>
<cookie-secure>true</cookie-secure>
<cookie-path>/;HttpOnly</cookie-path>
</cookie-config>
If you are not stuck in MX7 or CF8, there is an official setting for this in CF9.01 Dcoldfusion.sessioncookie.httponly
I've tested this on ColdFusion MX7 and it works as expected. Dodged Appscan I did.
The goal is for the first request to be secure (and pass the scanning), so if this post covers that then it will solve the problem.
Correct me if I'm wrong, but it sounds like you need to redirect to HTTPS if a request comes in over HTTP. Can you not catch this with a URL rewriting rule, before the request is sent to ColdFusion at all?