Wednesday, 5 September 2012

Cookies can actually be set after a CFLOCATION...

G'day:
I seem to have more verbal diarrhoea than usual today.

I was reading a posting on Jason Dean's blog this morning, about being able to set cookies in conjunction with <cflocation>.  Back in the bad old days this wasn't possible because of the way <cflocation> worked, but this has not been the case for some time (which is what Jason is saying in his blog).

One of the comments was asking about whether it was possible to set a cookie after a <cflocation> call, which Jason clarified one could not.  This isn't because of a vagary of cookies and <cflocation>, it's because once a <cflocation> is encountered, ColdFusion stops processing any further code.  It's kinda like a GOTO.



Kinda.

On CF 9.0.1, it actually is possible to set a cookie after a <cflocation>, thanks to a bug introduced into 9.0.1.

Here's a demonstration.


<!--- Application.cfc --->
<cfcomponent>

    <cffunction name="onRequestEnd">
        <cflog file="aftermath" text="onRequestEnd() called">
        <cfcookie name="aftermath_set_in_onrequestend" value="true">
    </cffunction>

</cfcomponent>


<!--- relocate.cfm --->

<cfcookie name="aftermath_set_before_cflocation" value="true">
<cflog file="aftermath" text="top of relocation.cfm">
<cflocation url="/" addtoken="false">
<cflog file="aftermath" text="bottom of relocation.cfm">
<cfcookie name="aftermath_set_after_cflocation" value="true">



<!---dumpCookies.cfm --->
<cfdump var="#cookie#">

If one runs this, we get this in the log:


"top of relocation.cfm"
"onRequestEnd() called"


So what we see is:
  • Processing in relocate.cfm ceases as soon as the <cflocation> is encountered (as predicted): the <cflog> and <cfcookie> calls are not executed;
  • Processing continues in onRequestEnd().
If we now run dumpCookies.cfm, we get this:

struct
AFTERMATH_SET_BEFORE_CFLOCATIONtrue
AFTERMATH_SET_IN_ONREQUESTENDtrue

The cookie set in onRequestEnd() was indeed set fine.

So there you go... today's useless information.

The bug has been fixed in CF10.

--
Adam