2003-03-31 Stefan G�rling <stefan@gorling.se>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Sun, 30 Mar 2003 22:12:30 +0000 (22:12 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Sun, 30 Mar 2003 22:12:30 +0000 (22:12 -0000)
* list: added new files to System.Web.SessionState
* System.Web.SessionState/HttpSessionState.cs:
* System.Web.SessionState/ISessionHandler.cs:
* System.Web.SessionState/SessionInProcHandler.cs:
* System.Web.SessionState/SessionStateModule.cs: initial implementation
of InProc session.

svn path=/trunk/mcs/; revision=12936

mcs/class/System.Web/System.Web.SessionState/ChangeLog
mcs/class/System.Web/System.Web.SessionState/HttpSessionState.cs
mcs/class/System.Web/System.Web.SessionState/ISessionHandler.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.SessionState/SessionInProcHandler.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.SessionState/SessionStateModule.cs
mcs/class/System.Web/list

index 7af1d3af849614a20d4441971f93928202a4c7ad..8eb0fac0acb96e04a25ee1ba217cc9d4835ac6cc 100644 (file)
@@ -1,3 +1,10 @@
+2003-03-31  Stefan Görling <stefan@gorling.se>
+
+       * HttpSessionState.cs:
+       * ISessionHandler.cs:
+       * SessionInProcHandler.cs:
+       * SessionStateModule.cs: initial implementation of InProc session.
+
 2003-03-13  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * HttpSessionState.cs: implemented CodePage.
index f78fa4717f7e4366c935399d2aa1f8e2b6a2883c..5b39fbf50450d8185a5a34db1f6f6e7d47992433 100644 (file)
@@ -80,6 +80,7 @@ public sealed class HttpSessionState : ICollection, IEnumerable
 
        public bool IsNewSession {
                get { return _newSession; }
+               set { _newSession=value; }
        }
 
        public bool IsReadOnly {
diff --git a/mcs/class/System.Web/System.Web.SessionState/ISessionHandler.cs b/mcs/class/System.Web/System.Web.SessionState/ISessionHandler.cs
new file mode 100644 (file)
index 0000000..b1a0548
--- /dev/null
@@ -0,0 +1,20 @@
+//
+// System.Web.SessionState.ISessionHandler
+//
+// Authors:
+//     Stefan Görling, (stefan@gorling.se)
+//
+// (C) 2003 Stefan Görling
+//
+// This interface is simple, but as it's internal it shouldn't be hard to change it if we need to.
+//
+namespace System.Web.SessionState
+{
+       internal interface ISessionHandler
+       {
+             void Dispose ();
+             void Init (HttpApplication context);
+             void UpdateContext (HttpContext context);
+       }
+}
+
diff --git a/mcs/class/System.Web/System.Web.SessionState/SessionInProcHandler.cs b/mcs/class/System.Web/System.Web.SessionState/SessionInProcHandler.cs
new file mode 100644 (file)
index 0000000..cb8031f
--- /dev/null
@@ -0,0 +1,124 @@
+//
+// 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.
+       public class SessionContainer
+       {
+               private HttpSessionState _state;
+               private long _last_access;
+
+               public SessionContainer (HttpSessionState state)
+               {
+                       _state = state;
+                       this.Touch ();
+               }
+
+               public void Touch ()
+               {
+                       _last_access = DateTime.Now.Millisecond;            
+               }
+
+               public HttpSessionState SessionState {
+                       get {
+                               //Check if we should abandon it.
+                               if (_state != null &&
+                                   (DateTime.Now.Millisecond - _last_access) > (_state.Timeout * 60 * 1000))
+                                       _state.Abandon ();
+
+                               return _state;
+                       }
+                       set {
+                               _state=value;
+                               this.Touch ();
+                       }
+               }
+       }
+
+
+       public 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)
+               {
+                       _sessionTable = new Hashtable();
+               }
+
+
+               //this is the code that actually do stuff.
+               public void UpdateContext (HttpContext context)
+               {
+                       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.Session = container.SessionState;
+                                       return; // 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 = System.Guid.NewGuid ().ToString ();
+                       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.Session = container.SessionState;
+
+
+                       // 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!
+               }
+       }
+}
+
index 01b976109c98225aa8a7a4f27462589625a3ab29..b4d98bdcd192b606c560d541ff5aa21cdf5c62c7 100644 (file)
@@ -3,21 +3,21 @@
 //
 // Authors:
 //     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//      Stefan Görling (stefan@gorling.se)
 //
 // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
-//
+// (C) 2003 Stefan Görling (http://www.gorling.se)
+
 using System.Web;
 
 namespace System.Web.SessionState
 {
        [MonoTODO]
-       public sealed class SessionStateModule : IHttpModule
+       public sealed class SessionStateModule : IHttpModule, IRequiresSessionState
        {
                static SessionConfig config;
                Type handlerType;
-               object handler;
-               
-               class SessionInProcHandler {}
+               ISessionHandler handler;
                
                public SessionStateModule ()
                {
@@ -25,6 +25,8 @@ namespace System.Web.SessionState
 
                public void Dispose ()
                {
+                   if (handler!=null)
+                       handler.Dispose();
                }
 
                [MonoTODO]
@@ -50,8 +52,10 @@ namespace System.Web.SessionState
                                }
                        }
 
-                       if (handlerType != null && handler == null)
-                               handler = Activator.CreateInstance (handlerType);
+                       if (handlerType != null && handler == null) {
+                               handler = (ISessionHandler) Activator.CreateInstance (handlerType);
+                               handler.Init(app); //initialize
+                       }
                }
 
                void OnReleaseRequestState (object o, EventArgs args)
@@ -64,7 +68,21 @@ namespace System.Web.SessionState
 
                IAsyncResult OnBeginAcquireState (object o, EventArgs args, AsyncCallback cb, object data)
                {
-                       return null;
+
+                       HttpApplication application = (HttpApplication) o;
+                       HttpContext context = application.Context;
+
+                       if (handler!=null)
+                           handler.UpdateContext (context);
+                       
+                       // In the future, we might want to move the Async stuff down to
+                       // the interface level, if we're going to support other than
+                       // InProc, we might actually want to do things async, now we
+                       // simply fake it.
+                       HttpAsyncResult result=new HttpAsyncResult (cb,this);
+                       result.Complete (true, o, null);
+
+                       return result;
                }
 
                void OnEndAcquireState (IAsyncResult result)
@@ -76,3 +94,6 @@ namespace System.Web.SessionState
        }
 }
 
+
+
+
index 7be7748130197b31e79f0e791ae239685a33dd7b..11e6cc82c6b9ca475a640b5f5aa5ae56b1f7081a 100755 (executable)
@@ -372,6 +372,8 @@ System.Web.SessionState/SessionDictionary.cs
 System.Web.SessionState/SessionStateMode.cs
 System.Web.SessionState/SessionStateModule.cs
 System.Web.SessionState/SessionStateSectionHandler.cs
+System.Web.SessionState/SessionInProcHandler.cs
+System.Web.SessionState/ISessionHandler.cs
 System.Web.Compilation/AspComponentFoundry.cs
 System.Web.Compilation/AspElements.cs
 System.Web.Compilation/AspGenerator.cs