|
|
@@ -0,0 +1,254 @@
|
|
|
+//
|
|
|
+// System.Web.SessionState.SessionSQLServerHandler
|
|
|
+//
|
|
|
+// Author(s):
|
|
|
+// Jackson Harper ([email protected])
|
|
|
+//
|
|
|
+// (C) 2003 Novell, Inc. (http://www.novell.com), All rights reserved
|
|
|
+//
|
|
|
+
|
|
|
+using System;
|
|
|
+using System.IO;
|
|
|
+using System.Data;
|
|
|
+using System.Reflection;
|
|
|
+using System.Configuration;
|
|
|
+using System.Collections.Specialized;
|
|
|
+
|
|
|
+namespace System.Web.SessionState {
|
|
|
+
|
|
|
+ internal class SessionSQLServerHandler : ISessionHandler
|
|
|
+ {
|
|
|
+ const string CookieName = "ASPSESSION";
|
|
|
+ const int DefTimeout = 600;
|
|
|
+
|
|
|
+ private Type cncType = null;
|
|
|
+ private IDbConnection cnc = null;
|
|
|
+ private SessionConfig config;
|
|
|
+
|
|
|
+ public void Dispose ()
|
|
|
+ {
|
|
|
+ if (cnc != null) {
|
|
|
+ cnc.Close ();
|
|
|
+ cnc = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Init (HttpApplication context, SessionConfig config)
|
|
|
+ {
|
|
|
+ string connectionTypeName;
|
|
|
+ string providerAssemblyName;
|
|
|
+ string cncString;
|
|
|
+
|
|
|
+ this.config = config;
|
|
|
+
|
|
|
+ GetConnectionData (out providerAssemblyName, out connectionTypeName, out cncString);
|
|
|
+ if (cncType == null) {
|
|
|
+ Assembly dbAssembly = Assembly.Load (providerAssemblyName);
|
|
|
+ cncType = dbAssembly.GetType (connectionTypeName, true);
|
|
|
+ if (!typeof (IDbConnection).IsAssignableFrom (cncType))
|
|
|
+ throw new ApplicationException ("The type '" + cncType +
|
|
|
+ "' does not implement IDB Connection.\n" +
|
|
|
+ "Check 'DbConnectionType' in server.exe.config.");
|
|
|
+ }
|
|
|
+
|
|
|
+ cnc = (IDbConnection) Activator.CreateInstance (cncType);
|
|
|
+ cnc.ConnectionString = cncString;
|
|
|
+ try {
|
|
|
+ cnc.Open ();
|
|
|
+ } catch (Exception exc) {
|
|
|
+ cnc = null;
|
|
|
+ throw exc;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void UpdateHandler (HttpContext context)
|
|
|
+ {
|
|
|
+ if (context.Session == null)
|
|
|
+ return;
|
|
|
+
|
|
|
+ string id = context.Session.SessionID;
|
|
|
+ SessionDictionary dict = context.Session.SessionDictionary;
|
|
|
+
|
|
|
+ UpdateSession (id, dict);
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool UpdateContext (HttpContext context)
|
|
|
+ {
|
|
|
+ HttpSessionState session = null;
|
|
|
+ string id = GetId (context);
|
|
|
+
|
|
|
+ if (id != null) {
|
|
|
+ session = SelectSession (id);
|
|
|
+ if (session != null) {
|
|
|
+ context.SetSession (session);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ id = System.Guid.NewGuid ().ToString ();
|
|
|
+ session = new HttpSessionState (id, new SessionDictionary (),
|
|
|
+ new HttpStaticObjectsCollection (), config.Timeout, true,
|
|
|
+ false, SessionStateMode.SQLServer, false);
|
|
|
+
|
|
|
+ InsertSession (session, config.Timeout);
|
|
|
+ context.SetSession (session);
|
|
|
+ context.Session.IsNewSession = true;
|
|
|
+ context.Response.AppendCookie (new HttpCookie (CookieName, id));
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void GetConnectionData (out string providerAssembly,
|
|
|
+ out string cncTypeName, out string cncString)
|
|
|
+ {
|
|
|
+ providerAssembly = null;
|
|
|
+ cncTypeName = null;
|
|
|
+ cncString = null;
|
|
|
+
|
|
|
+ NameValueCollection config = ConfigurationSettings.AppSettings as NameValueCollection;
|
|
|
+ if (config != null) {
|
|
|
+ foreach (string s in config.Keys) {
|
|
|
+ if (0 == String.Compare ("StateDBProviderAssembly", s, true)) {
|
|
|
+ providerAssembly = config [s];
|
|
|
+ } else if (0 == String.Compare ("StateDBConnectionType", s, true)) {
|
|
|
+ cncTypeName = config [s];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ cncString = this.config.SqlConnectionString;
|
|
|
+
|
|
|
+ if (providerAssembly == null || providerAssembly == String.Empty)
|
|
|
+ providerAssembly = "Npgsql.dll";
|
|
|
+
|
|
|
+ if (cncTypeName == null || cncTypeName == String.Empty)
|
|
|
+ cncTypeName = "Npgsql.NpgsqlConnection";
|
|
|
+
|
|
|
+ if (cncString == null || cncString == String.Empty)
|
|
|
+ cncString = "SERVER=127.0.0.1;USER ID=monostate;PASSWORD=monostate;dbname=monostate";
|
|
|
+ }
|
|
|
+
|
|
|
+ private HttpSessionState SelectSession (string id)
|
|
|
+ {
|
|
|
+ HttpSessionState session = null;
|
|
|
+ IDbCommand command = cnc.CreateCommand();
|
|
|
+ IDataReader reader;
|
|
|
+
|
|
|
+ string select = "SELECT * from aspstatetempsessions WHERE SessionID = :SessionID";
|
|
|
+
|
|
|
+ command.CommandText = select;
|
|
|
+
|
|
|
+ command.Parameters.Add (CreateParam (command, DbType.String, ":SessionID", id));
|
|
|
+
|
|
|
+ try {
|
|
|
+ reader = command.ExecuteReader ();
|
|
|
+
|
|
|
+ if (!reader.Read ())
|
|
|
+ return null;
|
|
|
+
|
|
|
+ SessionDictionary dict = null;
|
|
|
+ MemoryStream stream = null;
|
|
|
+ int len = (int) reader.GetBytes (reader.FieldCount-1, 0, null, 0, 0);
|
|
|
+ byte[] data = new byte[len];
|
|
|
+ reader.GetBytes (reader.FieldCount-1, 0, data, 0, len);
|
|
|
+ try {
|
|
|
+ stream = new MemoryStream (data);
|
|
|
+ dict = SessionDictionary.Deserialize (new BinaryReader (stream));
|
|
|
+ } catch {
|
|
|
+ throw;
|
|
|
+ } finally {
|
|
|
+ if (stream != null)
|
|
|
+ stream.Close ();
|
|
|
+ }
|
|
|
+
|
|
|
+ session = new HttpSessionState (id, dict,
|
|
|
+ new HttpStaticObjectsCollection (),
|
|
|
+ 100, true, false,
|
|
|
+ SessionStateMode.SQLServer, false);
|
|
|
+ return session;
|
|
|
+ } catch {
|
|
|
+ throw;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void InsertSession (HttpSessionState session, int timeout)
|
|
|
+ {
|
|
|
+ IDbCommand command = cnc.CreateCommand ();
|
|
|
+ IDataParameterCollection param;
|
|
|
+
|
|
|
+ string insert = "INSERT INTO ASPStateTempSessions VALUES " +
|
|
|
+ "(:SessionID, :Created, :Expires, :Timeout, :SessionData)";
|
|
|
+
|
|
|
+ command.CommandText = insert;
|
|
|
+
|
|
|
+ param = command.Parameters;
|
|
|
+ param.Add (CreateParam (command, DbType.String, ":SessionID", session.SessionID));
|
|
|
+ param.Add (CreateParam (command, DbType.DateTime, ":Created", DateTime.Now));
|
|
|
+ param.Add (CreateParam (command, DbType.DateTime, ":Expires", Tommorow ()));
|
|
|
+ param.Add (CreateParam (command, DbType.Int32, ":Timeout", timeout));
|
|
|
+ param.Add (CreateParam (command, DbType.Binary, ":SessionData",
|
|
|
+ GetDictData (session.SessionDictionary)));
|
|
|
+
|
|
|
+ command.ExecuteNonQuery ();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateSession (string id, SessionDictionary dict)
|
|
|
+ {
|
|
|
+ IDbCommand command = cnc.CreateCommand ();
|
|
|
+ IDataParameterCollection param;
|
|
|
+
|
|
|
+ string update = "UPDATE ASPStateTempSessions SET " +
|
|
|
+ "SessionData = :SessionData WHERE SessionId = :SessionID";
|
|
|
+
|
|
|
+ command.CommandText = update;
|
|
|
+
|
|
|
+ param = command.Parameters;
|
|
|
+ param.Add (CreateParam (command, DbType.String, ":SessionID", id));
|
|
|
+ param.Add (CreateParam (command, DbType.Binary, ":SessionData",
|
|
|
+ GetDictData (dict)));
|
|
|
+
|
|
|
+ command.ExecuteNonQuery ();
|
|
|
+ }
|
|
|
+
|
|
|
+ private IDataParameter CreateParam (IDbCommand command, DbType type,
|
|
|
+ string name, object value)
|
|
|
+ {
|
|
|
+ IDataParameter result = command.CreateParameter ();
|
|
|
+ result.DbType = type;
|
|
|
+ result.ParameterName = name;
|
|
|
+ result.Value = value;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private byte[] GetDictData (SessionDictionary dict)
|
|
|
+ {
|
|
|
+ MemoryStream stream = null;
|
|
|
+ try {
|
|
|
+ stream = new MemoryStream ();
|
|
|
+ dict.Serialize (new BinaryWriter (stream));
|
|
|
+ return stream.GetBuffer ();
|
|
|
+ } catch {
|
|
|
+ throw;
|
|
|
+ } finally {
|
|
|
+ if (stream != null)
|
|
|
+ stream.Close ();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private DateTime Tommorow ()
|
|
|
+ {
|
|
|
+ return DateTime.Now.AddDays (1);
|
|
|
+ }
|
|
|
+
|
|
|
+ private string GetId (HttpContext context)
|
|
|
+ {
|
|
|
+ if (!config.CookieLess &&
|
|
|
+ context.Request.Cookies [CookieName] != null)
|
|
|
+ return context.Request.Cookies [CookieName].Value;
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|