* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Web / System.Web.SessionState / SessionStateServerHandler.cs
1 //
2 // System.Web.SessionState.SessionStateServerHandler
3 //
4 // Author(s):
5 //  Jackson Harper (jackson@ximian.com)
6 //
7 // (C) 2003 Novell, Inc, (http://www.novell.com)
8 //
9
10 //
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:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
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.
29 //
30
31
32 using System;
33 using System.IO;
34 using System.Reflection;
35 using System.Configuration;
36 using System.Web.Configuration;
37 using System.Runtime.Remoting;
38
39 namespace System.Web.SessionState {
40
41         internal class SessionStateServerHandler : ISessionHandler
42         {
43                 const string CookieName = "ASPSESSION";
44
45                 private RemoteStateServer state_server;
46 #if NET_2_0
47                 private SessionStateSection config;
48 #else
49                 private SessionConfig config;
50 #endif
51                 
52                 public void Dispose ()
53                 {
54                 }
55
56                 public void Init (SessionStateModule module, HttpApplication context,
57 #if NET_2_0
58                                   SessionStateSection config
59 #else
60                                   SessionConfig config
61 #endif
62                                   )
63                 {
64                         this.config = 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);
70                 }
71
72                 public void UpdateHandler (HttpContext context, SessionStateModule module)
73                 {
74                         HttpSessionState session = context.Session;
75                         if (session == null || session.IsReadOnly)
76                                 return;
77                         
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 ());
83                         } else {
84                                 state_server.Remove (id);
85                         }
86                 }
87
88                 public HttpSessionState UpdateContext (HttpContext context, SessionStateModule module,
89                                                         bool required, bool read_only, ref bool isNew)
90                 {
91                         if (!required)
92                                 return null;
93
94                         StateServerItem item = null;
95                         HttpSessionState session = null;
96                         SessionDictionary dict = null;
97                         HttpStaticObjectsCollection sobjs = null;
98                         string id = GetId (context);
99
100                         if (id != null) {
101                                 item = state_server.Get (id);
102                                 if (item != null) {
103                                         dict = SessionDictionary.FromByteArray (item.DictionaryData);
104                                         sobjs = HttpStaticObjectsCollection.FromByteArray (item.StaticObjectsData);
105                                         session = new HttpSessionState (id, dict,
106                                                         HttpApplicationFactory.ApplicationState.SessionObjects,
107 #if NET_2_0
108                                                         (int)config.Timeout.TotalMinutes, // XXX is this right?  we lose some precision here, but since the timeout is in minutes *anyway*...
109 #else
110                                                         config.Timeout,
111 #endif
112                                                         false, config.CookieLess,
113                                                         SessionStateMode.StateServer, read_only);
114
115                                         return session;
116                                 }
117                         }
118                         
119                         id = SessionId.Create (module.Rng);
120                         dict = new SessionDictionary ();
121                         sobjs = HttpApplicationFactory.ApplicationState.SessionObjects;
122                         item = new StateServerItem (dict.ToByteArray (), sobjs.ToByteArray (),
123 #if NET_2_0
124                                                     (int)config.Timeout.TotalMinutes
125 #else
126                                                     config.Timeout
127 #endif
128                                                     );
129                         
130                         state_server.Insert (id, item);
131
132                         session = new HttpSessionState (id, dict, sobjs,
133 #if NET_2_0
134                                                         (int)config.Timeout.TotalMinutes,
135 #else
136                                                         config.Timeout,
137 #endif
138                                                         true,
139                                                         config.CookieLess, SessionStateMode.StateServer,
140                                                         read_only);
141                         
142                         isNew = true;
143                         return session;
144                 }
145
146                 private string GetId (HttpContext context)
147                 {
148                         if (!config.CookieLess &&
149                                         context.Request.Cookies [CookieName] != null)
150                                 return context.Request.Cookies [CookieName].Value;
151                         return null;
152                 }
153
154                 private void GetConData (string cons, out string proto, out string server, out string port)
155                 {
156                         int ei = cons.IndexOf ('=');
157                         int ci = cons.IndexOf (':');
158
159                         if (ei < 0 || ci < 0)
160                                 throw new Exception ("Invalid StateConnectionString");
161                         
162                         proto = cons.Substring (0, ei);
163                         server = cons.Substring (ei+1, ci - ei - 1);
164                         port = cons.Substring (ci+1, cons.Length - ci - 1);
165
166                         if (proto == "tcpip")
167                                 proto = "tcp";
168                 }
169         } 
170 }
171