I have an application that has a strange behavior which I have resolved in the interim, but I don't like my fix so I thought maybe someone else might have a clue as to why this is happening.
First some background:
I have an application which has both secured and unsecured areas, in order to have real online user statistics I'm using the SessionID value as a key in an application variable structure which updates with their current time, and is stored in one variable if they are logged in to the site at all, and one if they are logged into the secure area. This works fine, the problem is with logout. It seems to be random, and only occurs if they log out of a page which had a nested IFRAME window displaying a remote file's content (however it only occurs some of the time, so I don't think the IFRAME is the problem).
When the user selects the LOGOUT link on the page they are passed to a page which has two states, one for while they are still logged in, and one if they are logged out (by checking the Session.UserID value which I store at login). Initially I just walked the session structure and deleted any keys that weren't 'sessionid' or 'urltoken' - however 1 out of every 10 times the user logged out the sessionid value was deleted and the application would crash (since the code in the application.cfm file that updates the appropriate online user counters fails due to a missing Session.sessionid value).
Of course, there is no good way to handle that occurrence without instructing the user to close and reopen their browser to the page - something I want to avoid, since they may want to do something in the unsecured area after loggin out.
I then tried making a list of the keys in the Session structure, deleting the list items with the two necessary values, and then using the list to delete all the other keys from the session structure... again same problem 1 out of 10 times or so.
I finally had to write the following code so that if somehow the key 'sessionid' still gets deleted I just put it back in the variable before refreshing the page. Although this works... I've found that after the user logs out if I dump the session variable... some times the last value in the structure is still present. (Thus now I don't get the missing sessionid problem, but I haven't entirely cleared the session variable of everything unnecessary either). Do I need to sort the structure first, I don't understand this since even though structures are inherently unordered, a list is and I'm using the list of keys I generated as my values. I would really like this to be more optimized than it is if possible. Here is the script I run at logout:
<cfscript>
// Walk session structure and delete all but default key values.
lstSessionKeys = StructKeyList(Session,',')
;
i = 0;
// Set the positions of the default keys from the session variable.
varTokenPos = ListFind(lstSessionKeys,'u
rltoken');
varSessIDPos = ListFind(lstSessionKeys,'s
essionid')
;
// Now we'll use those positions to delete the required keys from the key list.
lstSessionKeys = ListDeleteAt(lstSessionKey
s,varToken
Pos);
lstSessionKeys = ListDeleteAt(lstSessionKey
s,varSessI
DPos);
while (i LT ListLen(lstSessionKeys)) {
i = i + 1;
// Secondary check because it seems to miss the session ID sometimes.
if (ListGetAt(lstSessionKeys,
i) CONTAINS 'sessionid') {
// Well, it must have happened again so just store that value for later use.
varSessionIDHolder = structFind(Session,ListGet
At(lstSess
ionKeys,i)
);
} else {
// Good, we don't have the sessionid so we'll delete this one.
structDelete(session,ListG
etAt(lstSe
ssionKeys,
i));
}
}
// Now a final check to make sure that they have a session ID value.
if (NOT IsDefined("Session.session
id")) {
session.sessionid = varSessionIDHolder;
}
// Now they should be left with only a SessionID and URLToken values.
</cfscript>
Note that I don't actually have a replacement handler for the URLToken key... it never gets missed by the code no matter how I write it... only the sessionid (which is the only one that's absolutely necessary for the session to exist in my application - I don't use URLToken values, but I want to preserve the session in it's initial state as created by the JRUN server through CF.
Although it should be obvious from what I just wrote, the application runs on a JRUN 4 application server as an instance (although at the moment there are no other instances of CF running, but there will be in the future possibly).
Is there something inherent about the sessionid value that might cause this? I'm running CF MX 6.1 so according to Macromedia there is no need to lock the session variable during this action - however, they have been wrong before so is this part of the problem?
If someone can either point me in the right direction, or (preferrably) point out some retardation in my coding - I'd greatly appreciate it. Since this isn't as simple as some CF stuff, I'm giving 500 Points since I'd like an answer asap. Thanks in advance.
Start Free Trial