| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- //
- // System.Web.SessionState.SessionInProcHandler
- //
- // Authors:
- // Stefan Görling ([email protected])
- //
- // (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.
- */
- using System;
- using System.IO;
- 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;
- // The length of a session, in minutes. After this length, it's abandoned due to idle.
- const int SESSION_LIFETIME = 45;
- private SessionConfig config;
-
- public void Dispose ()
- {
- _sessionTable = null;
- }
- public void Init (HttpApplication context, SessionConfig config)
- {
- this.config = config;
- _sessionTable = (Hashtable) AppDomain.CurrentDomain.GetData (".MonoSessionInProc");
- if (_sessionTable == null)
- _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;
- string id = SessionId.Lookup (context.Request, config.CookieLess);
-
- //first we try to get the cookie.
- // if we have a cookie, we look it up in the table.
- if (id != null) {
- container = (SessionContainer) _sessionTable [id];
- // 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) {
- _sessionTable.Remove (id);
- }
- }
- // 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,
- module.IsReadOnly)); //readonly
- // puts it in the table.
- _sessionTable [sessionID]=container;
- AppDomain.CurrentDomain.SetData (".MonoSessionInProc", _sessionTable);
- // and returns it.
- context.SetSession (container.SessionState);
- context.Session.IsNewSession = true;
- // And we're done!
- return true;
- }
- }
- }
|