Chad asks:
I am using a CFC for an AJAX-based shopping cart and it works great. But along comes a customer who is behind a proxy. The proxy is trying to request the CFC through a GET request (instead of a POST). Of course, when you try to access a CFC directly, it redirects the browser to the ColdFusion Component Browser. I have tried everything I know to keep the proxy from trying to access this page directly, but nothing seems to work. Any suggestions?
For folks who don't get what Chad is talking about, ColdFusion has a feature where if you access a CFC in your browser, you get a nicely formatted HTML page that describes the CFC and what it can do. (If you authenticate first.) You only get this if you don't specify a specific method. While this is nice and all, it may not be what you desire. You may - for example, want to share the documentation for a CFC and have it be something you wrote yourself. This way folks don't need your CF Admin password.
So what's cool about this question is that there is a really simple, very trivial solution. Mark Drew used this for his SnipEx code and it's just brilliant. I mean it's obvious - but it never occurred to me! Consider the simple CFC below:
<cfcomponent output="false">
<cffunction name="sayHi" access="remote" returnType="string" output="false">
<cfargument name="name" type="string" required="false" default="Nameless">
<cfreturn "Hello, #arguments.name#">
</cffunction>
</cfcomponent>
If you view this CFC in your browser and do not pass a method in the query string, you will get prompted to authenticate to your CF Admin and then you will get the nice documentation. But now look at this version:
<cfcomponent output="false">
<cfif not structKeyExists(url, "method")>
<cfset url.method = "sayHi">
</cfif>
<cffunction name="sayHi" access="remote" returnType="string" output="false">
<cfargument name="name" type="string" required="false" default="Nameless">
<cfreturn "Hello, #arguments.name#">
</cffunction>
</cfcomponent>
All I've done here is add code to notice the lack of a method in the query string. If it is missing, a default method is specified. Simple, right? Of course this disables the "auto-documentation", but it may be exactly what you want to do.
Archived Comments
For added fun to get around the cf admin to display the cfc data you can always do this below the cfcomponent tag. This will just dump the info about the cfc. It will also give you its dot notation path.
<cfif not structKeyExists(url, "method")>
<CFDUMP VAR="#this#">
<CFABORT>
</cfif>
--Dave
You could also get the descriptor yourself, http://www.cflib.org/udf.cf..., but doing this on every hit would suck. I'd probably run it once - get the PDF, save it, and then link to the PDF from the CFC.
Another way of preventing direct access to a cfc is to put them in a directory that only the localhost has access to.
Of course that may not be the answer to the Ajax problem mentioned here, but then again, put a cfm in between.
@jax - I think in this case though he really does want access to the CFC, just not w/o a method. I maybe should have named the blog entry a bit better. If other folks thought what jax did - let me know and I'll perform an edit.
Hey Ray,
I copied and pasted your just as it is, but a blank screen when I ran it.
Why is that happening?
Anyone else seeing this? What version of CF are you on?
Server Product ColdFusion MX
Version 7,0,2,142559
Edition Developer
Serial Number Developer
Operating System Windows XP
OS Version 5.1
Odd. I know Mark tested his code elsewhere. Can anyone else reproduce this?
It works as advertised for me on both CF8 (mac) and CF7 Enterprise (win).
Let's say you wanted the default behavior to run this sayHi method like you setup, if you really wanted a way to view the documentation could you in turn modify it like this?
<cfif NOT StructKeyExists(URL, "method")>
<cfset URL.method = "sayHi" />
<cfelseif URL.method IS "viewDocs">
<cfset URL.method = "" />
</cfif>
Charles, I haven't tested that - but I bet it would work. Why not try it and let us know. ;)
@Ray:
Right, my bad. I missed the 'remote' part. :-)
My 'solution' then of course makes no sense.