2 // System.Web.SessionState.SessionStateServerHandler
5 // Jackson Harper (jackson@ximian.com)
7 // (C) 2003 Novell, Inc, (http://www.novell.com)
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.
34 using System.Reflection;
35 using System.Configuration;
36 using System.Web.Configuration;
37 using System.Runtime.Remoting;
39 namespace System.Web.SessionState {
41 internal class SessionStateServerHandler : ISessionHandler
43 const string CookieName = "ASPSESSION";
45 private RemoteStateServer state_server;
47 private SessionStateSection config;
49 private SessionConfig config;
52 public void Dispose ()
56 public void Init (SessionStateModule module, HttpApplication context,
58 SessionStateSection config
65 RemotingConfiguration.Configure (null);
66 string cons, proto, server, port;
67 GetConData (config.StateConnectionString, out proto, out server, out port);
68 cons = String.Format ("{0}://{1}:{2}/StateServer", proto, server, port);
69 state_server = (RemoteStateServer) Activator.GetObject (typeof (RemoteStateServer), cons);
72 public void UpdateHandler (HttpContext context, SessionStateModule module)
74 HttpSessionState session = context.Session;
75 if (session == null || session.IsReadOnly)
78 string id = session.SessionID;
79 if (!session._abandoned) {
80 SessionDictionary dict = session.SessionDictionary;
81 HttpStaticObjectsCollection sobjs = session.StaticObjects;
82 state_server.Update (id, dict.ToByteArray (), sobjs.ToByteArray ());
84 state_server.Remove (id);
88 public HttpSessionState UpdateContext (HttpContext context, SessionStateModule module,
89 bool required, bool read_only, ref bool isNew)
94 StateServerItem item = null;
95 HttpSessionState session = null;
96 SessionDictionary dict = null;
97 HttpStaticObjectsCollection sobjs = null;
98 string id = GetId (context);
101 item = state_server.Get (id);
103 dict = SessionDictionary.FromByteArray (item.DictionaryData);
104 sobjs = HttpStaticObjectsCollection.FromByteArray (item.StaticObjectsData);
105 session = new HttpSessionState (id, dict,
106 HttpApplicationFactory.ApplicationState.SessionObjects,
108 (int)config.Timeout.TotalMinutes, // XXX is this right? we lose some precision here, but since the timeout is in minutes *anyway*...
112 false, config.CookieLess,
113 SessionStateMode.StateServer, read_only);
119 id = SessionId.Create ();
120 dict = new SessionDictionary ();
121 sobjs = HttpApplicationFactory.ApplicationState.SessionObjects;
122 item = new StateServerItem (dict.ToByteArray (), sobjs.ToByteArray (),
124 (int)config.Timeout.TotalMinutes
130 state_server.Insert (id, item);
132 session = new HttpSessionState (id, dict, sobjs,
134 (int)config.Timeout.TotalMinutes,
139 config.CookieLess, SessionStateMode.StateServer,
146 private string GetId (HttpContext context)
148 if (!config.CookieLess &&
149 context.Request.Cookies [CookieName] != null)
150 return context.Request.Cookies [CookieName].Value;
152 return context.Request.Headers [SessionStateModule.HeaderName];
155 private void GetConData (string cons, out string proto, out string server, out string port)
157 int ei = cons.IndexOf ('=');
158 int ci = cons.IndexOf (':');
160 if (ei < 0 || ci < 0)
161 throw new Exception ("Invalid StateConnectionString");
163 proto = cons.Substring (0, ei);
164 server = cons.Substring (ei+1, ci - ei - 1);
165 port = cons.Substring (ci+1, cons.Length - ci - 1);
167 if (proto == "tcpip")