2 // System.Web.Compilation.SessionStateItemCollection
5 // Marek Habersack (grendello@gmail.com)
7 // (C) 2006 Marek Habersack
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections.Specialized;
34 using System.Web.Configuration;
35 using System.Runtime.Remoting;
37 namespace System.Web.SessionState
39 internal class SessionStateServerHandler : SessionStateStoreProviderBase
41 private const Int32 lockAcquireTimeout = 30000;
43 SessionStateSection config;
44 RemoteStateServer stateServer;
46 public override SessionStateStoreData CreateNewStoreData (HttpContext context, int timeout)
48 return new SessionStateStoreData (new SessionStateItemCollection (),
49 HttpApplicationFactory.ApplicationState.SessionObjects,
53 public override void CreateUninitializedItem (HttpContext context, string id, int timeout)
55 EnsureGoodId (id, true);
56 stateServer.CreateUninitializedItem (id, timeout);
59 public override void Dispose ()
63 public override void EndRequest (HttpContext context)
67 SessionStateStoreData GetItemInternal (HttpContext context,
72 out SessionStateActions actions,
76 Console.WriteLine ("SessionStateServerHandler.GetItemInternal");
77 Console.WriteLine ("\tid == {0}", id);
78 Console.WriteLine ("\tpath == {0}", context.Request.FilePath);
81 lockAge = TimeSpan.MinValue;
82 lockId = Int32.MinValue;
83 actions = SessionStateActions.None;
88 StateServerItem item = stateServer.GetItem (id,
97 Console.WriteLine ("\titem is null (locked == {0}, actions == {1})", locked, actions);
101 if (actions == SessionStateActions.InitializeItem) {
103 Console.WriteLine ("\titem needs initialization");
105 return CreateNewStoreData (context, item.Timeout);
107 SessionStateItemCollection items = null;
108 HttpStaticObjectsCollection sobjs = null;
109 MemoryStream stream = null;
110 BinaryReader reader = null;
112 if (item.CollectionData != null && item.CollectionData.Length > 0) {
113 stream = new MemoryStream (item.CollectionData);
114 reader = new BinaryReader (stream);
115 items = SessionStateItemCollection.Deserialize (reader);
117 items = new SessionStateItemCollection ();
118 if (item.StaticObjectsData != null && item.StaticObjectsData.Length > 0)
119 sobjs = HttpStaticObjectsCollection.FromByteArray (item.StaticObjectsData);
121 sobjs = new HttpStaticObjectsCollection ();
122 } catch (Exception ex) {
123 throw new HttpException ("Failed to retrieve session state.", ex);
129 return new SessionStateStoreData (items,
134 public override SessionStateStoreData GetItem (HttpContext context,
137 out TimeSpan lockAge,
139 out SessionStateActions actions)
141 EnsureGoodId (id, false);
142 return GetItemInternal (context, id, out locked, out lockAge, out lockId, out actions, false);
145 public override SessionStateStoreData GetItemExclusive (HttpContext context,
148 out TimeSpan lockAge,
150 out SessionStateActions actions)
152 EnsureGoodId (id, false);
153 return GetItemInternal (context, id, out locked, out lockAge, out lockId, out actions, true);
156 public override void Initialize (string name, NameValueCollection config)
159 Console.WriteLine ("SessionStateServerHandler.Initialize");
161 this.config = (SessionStateSection) WebConfigurationManager.GetSection ("system.web/sessionState");
162 if (String.IsNullOrEmpty (name))
163 name = "Session Server handler";
164 RemotingConfiguration.Configure (null);
165 string cons = null, proto = null, server = null, port = null;
166 GetConData (out proto, out server, out port);
167 cons = String.Format ("{0}://{1}:{2}/StateServer", proto, server, port);
168 stateServer = Activator.GetObject (typeof (RemoteStateServer), cons) as RemoteStateServer;
170 base.Initialize (name, config);
173 public override void InitializeRequest (HttpContext context)
175 // nothing to do here
178 public override void ReleaseItemExclusive (HttpContext context,
182 EnsureGoodId (id, true);
183 stateServer.ReleaseItemExclusive (id, lockId);
186 public override void RemoveItem (HttpContext context,
189 SessionStateStoreData item)
191 EnsureGoodId (id, true);
192 stateServer.Remove (id, lockId);
195 public override void ResetItemTimeout (HttpContext context, string id)
197 EnsureGoodId (id, true);
198 stateServer.ResetItemTimeout (id);
201 public override void SetAndReleaseItemExclusive (HttpContext context,
203 SessionStateStoreData item,
207 EnsureGoodId (id, true);
208 byte[] collection_data = null;
209 byte[] sobjs_data = null;
210 MemoryStream stream = null;
211 BinaryWriter writer = null;
214 SessionStateItemCollection items = item.Items as SessionStateItemCollection;
215 if (items != null && items.Count > 0) {
216 stream = new MemoryStream ();
217 writer = new BinaryWriter (stream);
218 items.Serialize (writer);
219 collection_data = stream.GetBuffer ();
221 HttpStaticObjectsCollection sobjs = item.StaticObjects;
222 if (sobjs != null && sobjs.Count > 0)
223 sobjs_data = sobjs.ToByteArray ();
224 } catch (Exception ex) {
225 throw new HttpException ("Failed to store session data.", ex);
231 stateServer.SetAndReleaseItemExclusive (id, collection_data, sobjs_data, lockId, item.Timeout, newItem);
234 public override bool SetItemExpireCallback (SessionStateItemExpireCallback expireCallback)
239 void EnsureGoodId (string id, bool throwOnNull)
243 throw new HttpException ("Session ID is invalid");
247 if (id.Length > SessionIDManager.SessionIDMaxLength)
248 throw new HttpException ("Session ID too long");
251 void GetConData (out string proto, out string server, out string port)
253 string cons = config.StateConnectionString;
254 int ei = cons.IndexOf ('=');
255 int ci = cons.IndexOf (':');
257 if (ei < 0 || ci < 0)
258 throw new HttpException ("Invalid StateConnectionString");
260 proto = cons.Substring (0, ei);
261 server = cons.Substring (ei+1, ci - ei - 1);
262 port = cons.Substring (ci+1, cons.Length - ci - 1);
264 if (proto == "tcpip")