2004-05-05 Gonzalo Paniagua Javier <gonzalo@ximian.com>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Wed, 5 May 2004 18:45:08 +0000 (18:45 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Wed, 5 May 2004 18:45:08 +0000 (18:45 -0000)
* HttpSessionState.cs: added Clone (), which makes and exact copy but
with a cloned SessionDictionary. When EnableSessionState is set to
ReadOnly, we can modify the collection, but changes are not propagated.

* ISessionHandler.cs: changed signature of UpdateContext().

* SessionDictionary.cs: added Clone.

* SessionInProcHandler.cs:
* SessionSQLServerHandler.cs:
* SessionStateServerHandler.cs: don't create a new session if the handler
do not require it. UpdateContext() now returns an HttpSessionState to
the module.

* SessionStateModule.cs: removed IsReadOnly as it is now passed as a
parameter to the session handler. If the session is read-only, clone
it so that it can be changed but changes are not kept.

In short, we don't create session objects when not required and we
honor the ReadOnly sessions.

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

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
mcs/class/System.Web/System.Web.SessionState/SessionDictionary.cs
mcs/class/System.Web/System.Web.SessionState/SessionInProcHandler.cs
mcs/class/System.Web/System.Web.SessionState/SessionSQLServerHandler.cs
mcs/class/System.Web/System.Web.SessionState/SessionStateModule.cs
mcs/class/System.Web/System.Web.SessionState/SessionStateServerHandler.cs

index 4d7706a90ecf91aec388d2c268896843a8d949aa..9fae7d666f53f0dffc0a0b449c9b1bb5fab29ef7 100644 (file)
@@ -1,3 +1,26 @@
+2004-05-05  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * HttpSessionState.cs: added Clone (), which makes and exact copy but
+       with a cloned SessionDictionary. When EnableSessionState is set to
+       ReadOnly, we can modify the collection, but changes are not propagated.
+
+       * ISessionHandler.cs: changed signature of UpdateContext().
+
+       * SessionDictionary.cs: added Clone.
+
+       * SessionInProcHandler.cs:
+       * SessionSQLServerHandler.cs:
+       * SessionStateServerHandler.cs: don't create a new session if the handler
+       do not require it. UpdateContext() now returns an HttpSessionState to
+       the module.
+
+       * SessionStateModule.cs: removed IsReadOnly as it is now passed as a 
+       parameter to the session handler. If the session is read-only, clone
+       it so that it can be changed but changes are not kept.
+
+       In short, we don't create session objects when not required and we
+       honor the ReadOnly sessions.
+
 2004-02-09  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * SessionInProcHandler.cs:
index 0d9e63d73462890d2387a9c96ed8e59782e4cd7c..408582a534339f5ca5caec40fa361887de1c28b2 100644 (file)
@@ -46,6 +46,13 @@ public sealed class HttpSessionState : ICollection, IEnumerable
                _isReadonly = isReadonly;
        }
 
+       internal HttpSessionState Clone ()
+       {
+               return new HttpSessionState (_id, _dict.Clone (), _staticObjects, _timeout, _newSession,
+                                            _isCookieless, _mode, _isReadonly);
+
+       }
+
        public int CodePage {
                get {
                        HttpContext current = HttpContext.Current;
index 418fc08ca833b182d547e0c7db3a2305bf9525de..981ba84bee849024ee97900c7f658b93edcb8688 100644 (file)
@@ -12,10 +12,12 @@ namespace System.Web.SessionState
 {
        internal interface ISessionHandler
        {
-             void Dispose ();
-             void Init (HttpApplication context, SessionConfig config);
-             bool UpdateContext (HttpContext context, SessionStateModule module);
-             void UpdateHandler (HttpContext context, SessionStateModule module);
+               void Dispose ();
+               void Init (HttpApplication context, SessionConfig config);
+               HttpSessionState UpdateContext (HttpContext context, SessionStateModule module, bool required,
+                                               bool read_only, ref bool isNew);
+
+               void UpdateHandler (HttpContext context, SessionStateModule module);
        }
 }
 
index d610569a576b4bdae81373ac7f110f42593bc32d..e4f595245b29b4522b7cb81e9e8ab4882ad3a015 100644 (file)
@@ -21,6 +21,18 @@ internal class SessionDictionary : NameObjectCollectionBase
        {
        }
 
+       internal SessionDictionary Clone ()
+       {
+               SessionDictionary sess = new SessionDictionary ();
+               int last = sess.Count;
+               for (int i = 0; i < last; i++) {
+                       string key = GetKey (i);
+                       sess [key] = this [key];
+               }
+
+               return sess;
+       }
+       
        internal void Clear ()
        {
                _dirty = true;
index e00a672e931d958a61ac8078294dbbbb687d025f..04f461fc23c7d5e2d12742ef193d18c0a8530a9a 100644 (file)
@@ -79,7 +79,8 @@ namespace System.Web.SessionState
                }
 
                //this is the code that actually do stuff.
-               public bool UpdateContext (HttpContext context, SessionStateModule module)
+               public HttpSessionState UpdateContext (HttpContext context, SessionStateModule module,
+                                                       bool required, bool read_only, ref bool isNew)
                {
                        SessionContainer container = null;
                        string id = SessionId.Lookup (context.Request, config.CookieLess);
@@ -90,39 +91,40 @@ namespace System.Web.SessionState
                                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.SetNewSession (false);
+                               if (container != null && container.SessionState != null && 
+                                   !container.SessionState.IsAbandoned) {
+                                       if (required)
+                                               container.SessionState.SetNewSession (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) {
+                                       if (required)
+                                               return container.SessionState;
+
+                                       return null;
+                               } else if (container!=null) {
                                        _sessionTable.Remove (id);
                                }
                        }
 
+                       if (!required)
+                               return null;
+
                        // else we create a new session.
                        string sessionID = SessionId.Create (module.Rng);
-                       container = new SessionContainer (new HttpSessionState (sessionID, // unique identifier
-                                                                               new SessionDictionary(), // dictionary
-                                                                               HttpApplicationFactory.ApplicationState.SessionObjects,
-                                                                               SESSION_LIFETIME, //lifetime befor death.
-                                                                               true, //new session
-                                                                               false, // is cookieless
-                                                                               SessionStateMode.InProc,
-                                                                               module.IsReadOnly)); //readonly
-                       // puts it in the table.
+                       HttpSessionState state = new HttpSessionState (sessionID, // unique identifier
+                                                       new SessionDictionary(), // dictionary
+                                                       HttpApplicationFactory.ApplicationState.SessionObjects,
+                                                       SESSION_LIFETIME, //lifetime before death.
+                                                       true, //new session
+                                                       false, // is cookieless
+                                                       SessionStateMode.InProc,
+                                                       read_only); //readonly
+
+                       container = new SessionContainer (state);
                        _sessionTable [sessionID]=container;
                        AppDomain.CurrentDomain.SetData (".MonoSessionInProc", _sessionTable);
-
-                       // and returns it.
-                       context.SetSession (container.SessionState);
-                       context.Session.SetNewSession (true);
-
-                       // And we're done!
-                       return true;
+                       isNew = true;
+                       return container.SessionState;
                }
        }
 }
index 2b915848f79baec11ac4bc459ce3e0fd7a491541..871a8106d11d635a8088a946677616674f608849 100644 (file)
@@ -62,7 +62,7 @@ namespace System.Web.SessionState {
 
                public void UpdateHandler (HttpContext context, SessionStateModule module)
                {
-                       if (context.Session == null)
+                       if (context.Session == null || context.Session.IsReadOnly)
                                return;
 
                        string id = context.Session.SessionID;
@@ -71,28 +71,29 @@ namespace System.Web.SessionState {
                        UpdateSession (id, dict);
                }
 
-               public bool UpdateContext (HttpContext context, SessionStateModule module)
+               public HttpSessionState UpdateContext (HttpContext context, SessionStateModule module,
+                                                       bool required, bool read_only, ref bool isNew)
                {
+                       if (!required)
+                               return null;
+
                        HttpSessionState session = null;
                        string id = SessionId.Lookup (context.Request, config.CookieLess);
 
                        if (id != null) {
-                               session = SelectSession (id, module.IsReadOnly);
-                               if (session != null) {
-                                       context.SetSession (session);
-                                       return false;
-                               }
+                               session = SelectSession (id, read_only);
+                               if (session != null)
+                                       return session;
                        }
 
                        id = SessionId.Create (module.Rng);
                        session = new HttpSessionState (id, new SessionDictionary (),
-                                       HttpApplicationFactory.ApplicationState.SessionObjects, config.Timeout, true,
-                                       config.CookieLess, SessionStateMode.SQLServer, module.IsReadOnly);
+                                       HttpApplicationFactory.ApplicationState.SessionObjects, config.Timeout,
+                                       true, config.CookieLess, SessionStateMode.SQLServer, read_only);
 
                        InsertSession (session, config.Timeout);
-                       context.SetSession (session);
-
-                       return true;
+                       isNew = true;
+                       return session;
                }
 
                private void GetConnectionData (out string providerAssembly,
index a6beacaa44c5114bcc71228485afa50bae0f7003..c4fc2c0e55fda5315ae39e6b5ae47dd96580ccd3 100644 (file)
@@ -15,7 +15,6 @@ using System.Security.Cryptography;
 
 namespace System.Web.SessionState
 {
-       [MonoTODO]
        public sealed class SessionStateModule : IHttpModule
        {
                internal static readonly string CookieName = "ASPSESSION";
@@ -24,7 +23,6 @@ namespace System.Web.SessionState
                static SessionConfig config;
                static Type handlerType;
                ISessionHandler handler;
-               bool read_only;
                
                private RandomNumberGenerator rng;
                
@@ -37,18 +35,12 @@ namespace System.Web.SessionState
                        get { return rng; }
                }
 
-               internal bool IsReadOnly
-               {
-                       get { return read_only; }
-               }
-               
                public void Dispose ()
                {
                    if (handler!=null)
                        handler.Dispose();
                }
 
-               [MonoTODO]
                public void Init (HttpApplication app)
                {
                        if (config == null) {
@@ -119,22 +111,34 @@ namespace System.Web.SessionState
                        HttpApplication application = (HttpApplication) o;
                        HttpContext context = application.Context;
 
-                       read_only = (context.Handler is IReadOnlySessionState);
+                       bool required = (context.Handler is IRequiresSessionState);
+                       bool read_only = (context.Handler is IReadOnlySessionState);
                        
                        bool isNew = false;
+                       HttpSessionState session = null;
                        if (handler != null)
-                           isNew = handler.UpdateContext (context, this);
-
-                       if (isNew && config.CookieLess) {
-                               string id = context.Session.SessionID;
-                               context.Request.SetHeader (HeaderName, id);
-                               context.Response.Redirect (UrlUtils.InsertSessionId (id,
-                                               context.Request.FilePath));
-                       } else if (isNew) {
-                               string id = context.Session.SessionID;
-                               HttpCookie cookie = new HttpCookie (CookieName, id);
-                               cookie.Path = UrlUtils.GetDirectory (context.Request.Path);
-                               context.Response.AppendCookie (cookie);
+                               session = handler.UpdateContext (context, this, required, read_only, ref isNew);
+
+                       if (session != null) {
+                               if (isNew)
+                                       session.SetNewSession (true);
+
+                               if (read_only)
+                                       session = session.Clone ();
+                                       
+                               context.SetSession (session);
+
+                               if (isNew && config.CookieLess) {
+                                       string id = context.Session.SessionID;
+                                       context.Request.SetHeader (HeaderName, id);
+                                       context.Response.Redirect (UrlUtils.InsertSessionId (id,
+                                                                  context.Request.FilePath));
+                               } else if (isNew) {
+                                       string id = context.Session.SessionID;
+                                       HttpCookie cookie = new HttpCookie (CookieName, id);
+                                       cookie.Path = UrlUtils.GetDirectory (context.Request.Path);
+                                       context.Response.AppendCookie (cookie);
+                               }
                        }
                        
                        // In the future, we might want to move the Async stuff down to
index c98bf2a2a9507f54199c75822f83f32b4876a9e6..6ab00d00bdf6d979c72eb854558d51b49a1e1097 100644 (file)
@@ -40,7 +40,7 @@ namespace System.Web.SessionState {
 
                public void UpdateHandler (HttpContext context, SessionStateModule module)
                {
-                       if (context.Session == null)
+                       if (context.Session == null || context.Session.IsReadOnly)
                                return;
                        
                        string id = context.Session.SessionID;
@@ -49,8 +49,12 @@ namespace System.Web.SessionState {
                        state_server.Update (id, dict.ToByteArray (), sobjs.ToByteArray ());
                }
 
-               public bool UpdateContext (HttpContext context, SessionStateModule module)
+               public HttpSessionState UpdateContext (HttpContext context, SessionStateModule module,
+                                                       bool required, bool read_only, ref bool isNew)
                {
+                       if (!required)
+                               return null;
+
                        StateServerItem item = null;
                        HttpSessionState session = null;
                        SessionDictionary dict = null;
@@ -62,11 +66,12 @@ namespace System.Web.SessionState {
                                if (item != null) {
                                        dict = SessionDictionary.FromByteArray (item.DictionaryData);
                                        sobjs = HttpStaticObjectsCollection.FromByteArray (item.StaticObjectsData);
-                                       session = new HttpSessionState (id, dict, HttpApplicationFactory.ApplicationState.SessionObjects,
+                                       session = new HttpSessionState (id, dict,
+                                                       HttpApplicationFactory.ApplicationState.SessionObjects,
                                                        config.Timeout, false, config.CookieLess,
-                                                       SessionStateMode.StateServer, module.IsReadOnly);
-                                       context.SetSession (session);
-                                       return false;
+                                                       SessionStateMode.StateServer, read_only);
+
+                                       return session;
                                }
                        }
                        
@@ -77,12 +82,12 @@ namespace System.Web.SessionState {
                        
                        state_server.Insert (id, item);
 
-                       session = new HttpSessionState (id, dict, sobjs, config.Timeout,
-                                       true, config.CookieLess, SessionStateMode.StateServer, module.IsReadOnly);
-                       
-                       context.SetSession (session);
+                       session = new HttpSessionState (id, dict, sobjs, config.Timeout, true,
+                                                       config.CookieLess, SessionStateMode.StateServer,
+                                                       read_only);
                        
-                       return true;
+                       isNew = true;
+                       return session;
                }
 
                private string GetId (HttpContext context)