// // System.Web.SessionState.SessionInProcHandler // // Authors: // Stefan Görling (stefan@gorling.se) // // (C) 2003 Stefan Görling // /* This is a rather lazy implementation, but it does the trick for me. TODO: * Remove abandoned sessions., preferably by a worker thread sleeping most of the time. * Increase session security, for example by using UserAgent i hashcode. * Generate SessionID:s in a good (more random) way. */ using System; using System.Collections; namespace System.Web.SessionState { // Container object, containing the current session state and when it was last accessed. internal class SessionContainer { private HttpSessionState _state; private DateTime last_access; public SessionContainer (HttpSessionState state) { _state = state; this.Touch (); } public void Touch () { last_access = DateTime.Now; } public HttpSessionState SessionState { get { //Check if we should abandon it. if (_state != null && last_access.AddMinutes (_state.Timeout) < DateTime.Now) _state.Abandon (); return _state; } set { _state=value; this.Touch (); } } } internal class SessionInProcHandler : ISessionHandler { protected Hashtable _sessionTable; const string COOKIE_NAME = "ASPSESSION"; // The name of the cookie. // The length of a session, in minutes. After this length, it's abandoned due to idle. const int SESSION_LIFETIME = 45; public void Dispose () { _sessionTable = null; } public void Init (HttpApplication context, SessionConfig config) { _sessionTable = new Hashtable(); } public void UpdateHandler (HttpContext context, SessionStateModule module) { } //this is the code that actually do stuff. public bool UpdateContext (HttpContext context, SessionStateModule module) { SessionContainer container = null; //first we try to get the cookie. // if we have a cookie, we look it up in the table. if (context.Request.Cookies [COOKIE_NAME] != null) { container = (SessionContainer) _sessionTable [context.Request.Cookies [COOKIE_NAME].Value]; // if we have a session, and it is not expired, set isNew to false and return it. if (container!=null && container.SessionState!=null && !container.SessionState.IsAbandoned) { // Can we do this? It feels safe, but what do I know. container.SessionState.IsNewSession = false; // update the timestamp. container.Touch (); // Can we do this? It feels safe, but what do I know. context.SetSession (container.SessionState); return false; // and we're done } else if(container!=null) { //A empty or expired session, lets kill it. _sessionTable[context.Request.Cookies[COOKIE_NAME]]=null; } } // else we create a new session. string sessionID = SessionId.Create (module.Rng); container = new SessionContainer (new HttpSessionState (sessionID, // unique identifier new SessionDictionary(), // dictionary new HttpStaticObjectsCollection(), SESSION_LIFETIME, //lifetime befor death. true, //new session false, // is cookieless SessionStateMode.InProc, false)); //readonly // puts it in the table. _sessionTable [sessionID]=container; // and returns it. context.SetSession (container.SessionState); context.Session.IsNewSession = true; // sets the session cookie. We're assuming that session scope is the default mode. context.Response.AppendCookie (new HttpCookie (COOKIE_NAME,sessionID)); // And we're done! return true; } } }