public void TestNonExclusiveReadFromSession()
        {
            bool                locked;
            TimeSpan            lockAge;
            object              lockId;
            SessionStateActions actions;

            SessionStateStoreData data =
                m_store.GetItem(null, SESSION_ID, out locked, out lockAge, out lockId, out actions);

            Assert.IsFalse(locked);
            Assert.AreEqual(TimeSpan.Zero, lockAge);
            Assert.IsNull(lockId);
            Assert.AreEqual(SessionStateActions.None, actions);

            ISessionStateItemCollection session = data.Items;

            AssertSessionDefaults(session);
        }
        public async Task SetAndReleaseItemExclusive_NewItemValidItems()
        {
            Utility.SetConfigUtilityToDefault();
            string id = "session-id";
            ChangeTrackingSessionStateItemCollection sessionStateItemCollection = Utility.GetChangeTrackingSessionStateItemCollection();

            sessionStateItemCollection["session-key"] = "session-value";
            SessionStateStoreData sssd = new SessionStateStoreData(sessionStateItemCollection, null, 15);

            var mockCache = A.Fake <ICacheConnection>();
            RedisSessionStateProvider sessionStateStore = new Oriflame.Web.Redis.RedisSessionStateProvider();

            sessionStateStore.cache = mockCache;
            await sessionStateStore.SetAndReleaseItemExclusiveAsync(FakeHttpContext, id, sssd, null, true, CancellationToken.None);

            A.CallTo(() => mockCache.Set(A <ISessionStateItemCollection> .That.Matches(
                                             o => o.Count == 1 && o["session-key"] != null
                                             ), 900)).MustHaveHappened();
        }
        public async Task SetAndReleaseItemExclusive_OldItemRemovedItems()
        {
            Utility.SetConfigUtilityToDefault();
            string id = "session-id";
            ChangeTrackingSessionStateItemCollection sessionStateItemCollection = Utility.GetChangeTrackingSessionStateItemCollection();

            sessionStateItemCollection["session-key"] = "session-val";
            sessionStateItemCollection.Remove("session-key");
            SessionStateStoreData sssd = new SessionStateStoreData(sessionStateItemCollection, null, 15);

            var mockCache = A.Fake <ICacheConnection>();
            RedisSessionStateProvider sessionStateStore = new Oriflame.Web.Redis.RedisSessionStateProvider();

            sessionStateStore.cache = mockCache;
            await sessionStateStore.SetAndReleaseItemExclusiveAsync(FakeHttpContext, id, sssd, 7, false, CancellationToken.None);

            A.CallTo(() => mockCache.TryUpdateAndReleaseLock(A <object> .Ignored,
                                                             A <ChangeTrackingSessionStateItemCollection> .That.Matches(o => o.Count == 0 && o.GetModifiedKeys().Count == 0 && o.GetDeletedKeys().Count == 1), 900)).MustHaveHappened();
        }
示例#4
0
        public void TestExternalAttributeReplacement()
        {
            bool                locked;
            TimeSpan            lockAge;
            object              lockId;
            SessionStateActions actions;

            SessionStateStoreData data =
                m_store.GetItemExclusive(null, SESSION_ID, out locked, out lockAge, out lockId, out actions);

            // replace "large" external attribute with a "small" attribute
            ISessionStateItemCollection session = data.Items;

            session["blob"] = CreateBlob(1);

            m_store.SetAndReleaseItemExclusive(null, SESSION_ID, data, lockId, false);

            Assert.AreEqual(0, m_extAttrCache.Count);
        }
        /// <summary>
        /// Form a hashtable to be added to cache
        /// </summary>
        /// <param name="context"></param>
        /// <param name="data"></param>
        /// <param name="flag"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        private Hashtable InsertContents(HttpContext context, SessionStateStoreData data, SessionStateActions flag, int timeout)
        {
            Hashtable items = new Hashtable(4);

            if (data != null)
            {
                byte[] buffer = SessionSerializationUtil.Serialize(data);
                items.Add(SESSION_DATA, buffer);
                items.Add(TIMEOUT_KEY, (int)data.Timeout);
            }
            else
            {
                items.Add(TIMEOUT_KEY, (int)timeout);
            }

            items.Add(ACTIONS_KEY, flag);

            return(items);
        }
示例#6
0
        public void TestExternalAttributeReadBeforeWrite()
        {
            bool                locked;
            TimeSpan            lockAge;
            object              lockId;
            SessionStateActions actions;

            SessionStateStoreData data =
                m_store.GetItemExclusive(null, SESSION_ID, out locked, out lockAge, out lockId, out actions);

            ISessionStateItemCollection session = data.Items;
            var blob = session["blob"];

            session["blob"] = CreateBlob(1);

            m_store.SetAndReleaseItemExclusive(null, SESSION_ID, data, lockId, false);

            Assert.AreEqual(0, m_extAttrCache.Count);
        }
示例#7
0
        public void GetItemExclusiveCreatesLock()
        {
            _cacheImpl.Setup(cache => cache.Get <byte[]>("Session(THIS_IS_MY_ID, UnitTest)")).Returns(new byte[] { 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF });
            _cacheImpl.Setup(cache => cache.Add("Session(THIS_IS_MY_ID, UnitTest)", (object)It.Is <byte[]>(bytes => bytes[6] == 0x01), It.IsInRange(DateTime.Now.AddMinutes(19), DateTime.Now.AddMinutes(21), Range.Inclusive)));

            bool                locked;
            TimeSpan            lockAge;
            object              lockId;
            SessionStateActions actions;

            SessionStateStoreData data = _provider.GetItemExclusive(_context, "THIS_IS_MY_ID", out locked, out lockAge, out lockId, out actions);

            _cacheImpl.VerifyAll();

            Assert.IsNotNull(data);
            Assert.IsFalse(locked);
            Assert.AreEqual(TimeSpan.Zero, lockAge);
            Assert.AreEqual(SessionStateActions.None, actions);
        }
        /// <summary>
        /// Updates the session-item information in the session-state data store with values from the current request, and clears the lock on the data.
        /// </summary>
        /// <param name="context">The HttpContext for the current request.</param>
        /// <param name="sessionId">The session identifier for the current request.</param>
        /// <param name="item">The SessionStateStoreData object that contains the current session values to be stored.</param>
        /// <param name="lockId">The lock identifier for the current request.</param>
        /// <param name="newItem">true to identify the session item as a new item; false to identify the session item as an existing item.</param>
        public override void SetAndReleaseItemExclusive(HttpContext context,
                                                        string sessionId,
                                                        SessionStateStoreData item,
                                                        object lockId,
                                                        bool newItem)
        {
            LogInfo("SetAndReleaseItemExclusive", sessionId, lockId, newItem, context);

            string serialized = serialize(item.Items as SessionStateItemCollection);

            Document newValues = new Document();

            newValues[ATTRIBUTE_SESSION_ID]            = GetHashKey(sessionId);
            newValues[ATTRIBUTE_LOCKED]                = false;
            newValues[ATTRIBUTE_LOCK_ID]               = null;
            newValues[ATTRIBUTE_LOCK_DATE]             = DateTime.Now;
            newValues[ATTRIBUTE_EXPIRES]               = DateTime.Now.Add(this._timeout);
            newValues[ATTRIBUTE_FLAGS]                 = 0;
            newValues[ATTRIBUTE_SESSION_ITEMS]         = serialized;
            newValues[ATTRIBUTE_RECORD_FORMAT_VERSION] = CURRENT_RECORD_FORMAT_VERSION;

            if (newItem)
            {
                newValues[ATTRIBUTE_CREATE_DATE] = DateTime.Now;
                this._table.PutItem(newValues);
            }
            else
            {
                Document expected = new Document();
                expected[ATTRIBUTE_LOCK_ID] = lockId.ToString();

                // Not really any reason the condition should fail unless we get in some sort of weird
                // app pool reset mode.
                try
                {
                    this._table.UpdateItem(newValues, new UpdateItemOperationConfig()
                    {
                        Expected = expected
                    });
                }
                catch (ConditionalCheckFailedException) { LogInfo("(SetAndReleaseItemExclusive) Conditional check failed for update.", sessionId, context); }
            }
        }
示例#9
0
        /// <inheritdoc />
        public override async Task SetAndReleaseItemExclusiveAsync(
            HttpContextBase context,
            string id,
            SessionStateStoreData item,
            object lockId,
            bool newItem,
            CancellationToken cancellationToken)
        {
            byte[] buf;
            int    length;
            int    lockCookie;

            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            if (id == null)
            {
                throw new ArgumentNullException("id");
            }
            if (id.Length > SessionIDManager.SessionIDMaxLength)
            {
                throw new ArgumentException(SR.Session_id_too_long);
            }
            id = AppendAppIdHash(id);

            try
            {
                SerializeStoreData(item, SqlSessionStateRepositoryUtil.DefaultItemLength, out buf, out length, s_compressionEnabled);
            }
            catch
            {
                if (!newItem)
                {
                    await ReleaseItemExclusiveAsync(context, id, lockId, cancellationToken);
                }
                throw;
            }

            lockCookie = lockId == null ? 0 : (int)lockId;

            await s_sqlSessionStateRepository.CreateOrUpdateSessionStateItemAsync(newItem, id, buf, length, item.Timeout, lockCookie, _rqOrigStreamLen);
        }
        public void TestSessionModification()
        {
            bool                locked;
            TimeSpan            lockAge;
            object              lockId;
            SessionStateActions actions;

            SessionStateStoreData data =
                m_store.GetItemExclusive(null, SESSION_ID, out locked, out lockAge, out lockId, out actions);

            Assert.IsTrue(locked);
            Assert.IsTrue(lockAge >= TimeSpan.Zero);
            Assert.IsNotNull(lockId);
            Assert.AreEqual(SessionStateActions.None, actions);

            ISessionStateItemCollection session = data.Items;

            AssertSessionDefaults(session);

            session["int"]    = 2;
            session["string"] = "modified string";
            session["date"]   = DateTime.Now;
            session["bool"]   = true;
            session["blob"]   = CreateBlob(1024);
            session["person"] = new PortablePerson("Novak Seovic", new DateTime(2007, 12, 28));

            m_store.SetAndReleaseItemExclusive(null, SESSION_ID, data, lockId, false);

            data = m_store.GetItem(null, SESSION_ID, out locked, out lockAge, out lockId, out actions);

            Assert.IsFalse(locked);
            Assert.AreEqual(TimeSpan.Zero, lockAge);
            Assert.IsNull(lockId);
            Assert.AreEqual(SessionStateActions.None, actions);

            session = data.Items;
            Assert.AreEqual(2, session["int"]);
            Assert.AreEqual("modified string", session["string"]);
            Assert.AreNotEqual(DateTime.Today, session["date"]);
            Assert.AreEqual(true, session["bool"]);
            Assert.AreNotEqual(BLOB, session["blob"]);
            Assert.AreNotEqual(PERSON, session["person"]);
        }
        /// <summary>
        /// SessionStateProviderBase.SetAndReleaseItemExclusive
        /// </summary>
        public override void SetAndReleaseItemExclusive(
            HttpContext context,
            string id,
            SessionStateStoreData item,
            object lockId,
            bool newItem)
        {
            BsonArray arraySession = MongoSessionStateStoreHelpers.Serialize(item);

            MongoClient conn = GetConnection();
            var         sessionCollection = GetSessionCollection(conn);

            if (newItem)
            {
                var insertDoc = MongoSessionStateStoreHelpers.GetNewBsonSessionDocument(
                    id: id,
                    applicationName: ApplicationName,
                    created: DateTime.Now.ToUniversalTime(),
                    lockDate: DateTime.Now.ToUniversalTime(),
                    lockId: 0,
                    timeout: item.Timeout,
                    locked: false,
                    jsonSessionItemsArray: arraySession,
                    flags: 0);

                this.UpsertEntireSessionDocument(sessionCollection, insertDoc);
            }
            else
            {
                var filter = Builders <BsonDocument> .Filter.And(
                    Builders <BsonDocument> .Filter.Eq("_id", MongoSessionStateStoreHelpers.GetDocumentSessionId(id, ApplicationName)),
                    Builders <BsonDocument> .Filter.Eq("LockId", (Int32)lockId)
                    );

                var update = Builders <BsonDocument> .Update
                             .Set("Expires", DateTime.Now.AddMinutes(item.Timeout).ToUniversalTime())
                             .Set("SessionItemJSON", arraySession)
                             .Set("Locked", false);

                this.UpdateSessionCollection(sessionCollection, filter, update);
            }
        }
示例#12
0
        /// <summary>
        /// Updates the session-item information in the session-state data store with values
        /// from the current request, and clears the lock on the data
        /// </summary>
        /// <param name="context">HttpContext for the current request</param>
        /// <param name="id">Session ID for the session</param>
        /// <param name="item">The session state item to be stored</param>
        /// <param name="lockId">The lock identifier for the current request</param>
        /// <param name="newItem">True if this is a new session item, false if it is an existing item</param>
        public override void SetAndReleaseItemExclusive(
            HttpContext context,
            string id,
            SessionStateStoreData item,
            object lockId,
            bool newItem)
        {
            SessionStateItem e;

            do
            {
                if (!newItem)
                {
                    var tmp = (ulong)lockId;

                    // Load the entire item with CAS (need the DataCas value also for the save)
                    e = SessionStateItem.Load(_bucket, id, false);

                    // if we're expecting an existing item, but
                    // it's not in the cache
                    // or it's locked by someone else, then quit
                    if (e == null || e.LockId != tmp)
                    {
                        return;
                    }
                }
                else
                {
                    // Create a new item if it requested
                    e = new SessionStateItem();
                }

                // Set the new data and reset the locks
                e.Timeout  = item.Timeout;
                e.Data     = (SessionStateItemCollection)item.Items;
                e.Flag     = SessionStateActions.None;
                e.LockId   = 0;
                e.LockTime = DateTime.MinValue;

                // Attempt to save with CAS and loop around if it fails
            } while (!e.SaveAll(_bucket, id, _exclusiveAccess && !newItem));
        }
        /// <inheritdoc />
        public override async Task RemoveItemAsync(
            HttpContextBase context,
            string id,
            object lockId,
            SessionStateStoreData item,
            CancellationToken cancellationToken)
        {
            if (id == null)
            {
                throw new ArgumentNullException("id");
            }
            if (id.Length > SessionIDManager.SessionIDMaxLength)
            {
                throw new ArgumentException(Resource1.Session_id_too_long);
            }

            id = AppendAppIdHash(id);

            await s_sqlSessionStateRepository.RemoveSessionItemAsync(id, lockId);
        }
示例#14
0
            private static void SerializeSessionStateStoreData(
                SessionStateStoreData item,
                int initialStreamSize,
                out byte[] buffer,
                out int length)
            {
                MemoryStream memoryStream = (MemoryStream)null;

                try
                {
                    memoryStream = new MemoryStream(initialStreamSize);
                    OracleSessionStateStore.Serialize(item, (Stream)memoryStream);
                    buffer = memoryStream.GetBuffer();
                    length = (int)memoryStream.Length;
                }
                finally
                {
                    memoryStream?.Dispose();
                }
            }
示例#15
0
        /// <inheritdoc />
        public override Task RemoveItemAsync(
            HttpContextBase context,
            string id,
            object lockId,
            SessionStateStoreData item,
            CancellationToken cancellationToken)
        {
            if (id == null)
            {
                throw new ArgumentNullException("id");
            }
            if (id.Length > SessionIDManager.SessionIDMaxLength)
            {
                throw new ArgumentException(SR.Session_id_too_long);
            }

            s_store.Remove(id);

            return(Task.CompletedTask);
        }
示例#16
0
        public static byte[] Serialize(SessionStateStoreData sessionData)
        {
            byte         sessionFlag = 0;
            MemoryStream stream      = null;

            byte[] buffer = null;
            try
            {
                stream = new MemoryStream();
                BinaryWriter writer = new BinaryWriter(stream);

                if (sessionData.Items != null)
                {
                    sessionFlag = (byte)(sessionFlag | SESSION_ITEMS);
                }
                if (sessionData.StaticObjects != null && !sessionData.StaticObjects.NeverAccessed)
                {
                    sessionFlag = (byte)(sessionFlag | SESSION_STATIC_ITEMS);
                }
                writer.Write(sessionFlag);

                if ((byte)(sessionFlag & SESSION_ITEMS) == SESSION_ITEMS)
                {
                    ((SessionStateItemCollection)sessionData.Items).Serialize(writer);
                }
                if ((byte)(sessionFlag & SESSION_STATIC_ITEMS) == SESSION_STATIC_ITEMS)
                {
                    sessionData.StaticObjects.Serialize(writer);
                }
                writer.Write(sessionData.Timeout);
            }
            finally
            {
                if (stream != null)
                {
                    buffer = stream.ToArray();
                    stream.Close();
                }
            }
            return(buffer);
        }
        public byte[] Serialize(SessionStateStoreData sessionState)
        {
            var hasItems         = sessionState.Items != null && sessionState.Items.Count > 0;
            var hasStaticObjects = sessionState.StaticObjects != null && !sessionState.StaticObjects.NeverAccessed;
            var stream           = new MemoryStream();
            var writer           = new BinaryWriter(stream);

            writer.Write(sessionState.Timeout);
            writer.Write(hasItems);
            writer.Write(hasStaticObjects);
            if (hasItems)
            {
                ((SessionStateItemCollection)sessionState.Items).Serialize(writer);
            }
            if (hasStaticObjects)
            {
                sessionState.StaticObjects.Serialize(writer);
            }
            writer.Write(byte.MaxValue);
            return(stream.ToArray());
        }
示例#18
0
        /// <summary>
        /// Updates the store data.
        /// </summary>
        private static SessionStateStoreData UpdateStoreData(SessionStateStoreData data)
        {
            data.Timeout = 8;

            data.Items["name1"] = 1;
            data.Items["name2"] = "2";

            var statics = data.StaticObjects;

            // Modification method is internal.
            var method = statics.GetType()
                         .GetMethod("Add", BindingFlags.Instance | BindingFlags.NonPublic);

            Debug.Assert(method != null);

            method.Invoke(statics, new object[] { "int", typeof(int), false });

            CheckStoreData(data);

            return(data);
        }
        public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked,
                                                      out TimeSpan lockAge, out object lockId,
                                                      out SessionStateActions actions)
        {
            // set default out parameters
            locked  = false;
            lockAge = new TimeSpan();
            lockId  = null;
            actions = SessionStateActions.None;
            // try to get the session from cache.
            string sessionString = cache.GetAsync <string>(id).Result;

            if (string.IsNullOrEmpty(sessionString))
            {
                return(null);
            }
            var sessionItems = JsonConvert.DeserializeObject <SessionStateItemCollection>(sessionString);
            var data         = new SessionStateStoreData(sessionItems, null, 60); // todo: set timeout.

            return(data);
        }
示例#20
0
        public void RemoveLockedItemWithNullLockNotRemovesSession()
        {
            string sessionId = GenerateKey();
            SessionStateStoreProvider provider = CreateProvider();

            bool                locked;
            TimeSpan            lockAge;
            object              lockId, lockId2;
            SessionStateActions actions;

            provider.CreateUninitializedItem(null, sessionId, SessionTimeoutInMinutesFromConfig);
            SessionStateStoreData storeData = provider.GetItemExclusive(null, sessionId, out locked, out lockAge,
                                                                        out lockId,
                                                                        out actions);

            provider.RemoveItem(null, sessionId, null, storeData);
            Thread.Sleep(100);
            storeData = provider.GetItem(null, sessionId, out locked, out lockAge, out lockId2, out actions);

            AssertSessionIsLocked(storeData, locked, lockAge, lockId, lockId2, actions);
        }
示例#21
0
        public void TestExternalAttributeReplaceSmall()
        {
            CheckCacheIsReady();

            bool                locked;
            TimeSpan            lockAge;
            object              lockId;
            SessionStateActions actions;

            SessionStateStoreData data =
                m_store.GetItemExclusive(null, SESSION_ID, out locked, out lockAge, out lockId, out actions);

            ISessionStateItemCollection session = data.Items;

            session["blob"]   = CreateBlob(1);
            session["person"] = CreateBlob(1024);

            m_store.SetAndReleaseItemExclusive(null, SESSION_ID, data, lockId, false);

            Assert.AreEqual(1, m_extAttrCache.Count);
        }
        public async void SetAndReleaseItemExclusiveAsync_Should_Release_NonExclsive_SessionItem()
        {
            var provider = CreateProvider();

            provider.Initialize(DefaultProviderName, CreateSessionStateProviderConfig(), CreateSessionStateSection(),
                                createConnectionStringSettings());

            var sessionCollection = new SessionStateItemCollection();
            var now = DateTime.UtcNow;

            sessionCollection["test1"] = "test1";
            sessionCollection["test2"] = now;
            var data = new SessionStateStoreData(sessionCollection, new HttpStaticObjectsCollection(), TestTimeout);

            byte[] buff;
            int    length;

            SqlSessionStateProviderAsync.SerializeStoreData(data, DefaultItemLength, out buff, out length, false);

            var repoMoq = new Mock <ISqlSessionStateRepository>();
            var ssItem  = new SessionItem(buff, false, TimeSpan.Zero, null, SessionStateActions.None);

            repoMoq.Setup(repo => repo.GetSessionStateItemAsync(SqlSessionStateProviderAsync.AppendAppIdHash(TestSessionId), false))
            .Returns(Task.FromResult(ssItem));
            provider.SqlSessionStateRepository = repoMoq.Object;
            var httpContext = CreateMoqHttpContextBase();

            var getItemResult = await provider.GetItemAsync(httpContext, TestSessionId, CancellationToken.None);

            var sessionReleased = false;

            repoMoq.Setup(repo => repo.CreateOrUpdateSessionStateItemAsync(false, SqlSessionStateProviderAsync.AppendAppIdHash(TestSessionId),
                                                                           buff, length, TestTimeout, 0, provider.OrigStreamLen))
            .Returns(Task.CompletedTask)
            .Callback(() => sessionReleased = true);

            await provider.SetAndReleaseItemExclusiveAsync(httpContext, TestSessionId, getItemResult.Item, null, false, CancellationToken.None);

            Assert.True(sessionReleased);
        }
示例#23
0
        public void GetItem_RecordFound()
        {
            Utility.SetConfigUtilityToDefault();
            string              id = "session-id";
            bool                locked;
            TimeSpan            lockAge;
            object              lockId = null;
            SessionStateActions actions;

            ISessionStateItemCollection sessionStateItemCollection = new ChangeTrackingSessionStateItemCollection();

            sessionStateItemCollection["session-key"]         = "session-value";
            sessionStateItemCollection["SessionStateActions"] = SessionStateActions.None;
            SessionStateStoreData sssd = new SessionStateStoreData(sessionStateItemCollection, null, 15);

            ISessionStateItemCollection sessionData = new ChangeTrackingSessionStateItemCollection();

            sessionData["session-key"]         = "session-value";
            sessionData["SessionStateActions"] = SessionStateActions.None;
            ISessionStateItemCollection mockSessionData = null;
            object mockLockId = 0;
            int    mockSessionTimeout;
            int    sessionTimeout = (int)RedisSessionStateProvider.configuration.SessionTimeout.TotalMinutes;
            var    mockCache      = A.Fake <ICacheConnection>();

            A.CallTo(() => mockCache.TryCheckWriteLockAndGetData(out mockLockId, out mockSessionData, out mockSessionTimeout)).Returns(true).AssignsOutAndRefParameters(0, sessionData, (int)RedisSessionStateProvider.configuration.SessionTimeout.TotalMinutes);

            RedisSessionStateProvider sessionStateStore = new RedisSessionStateProvider();

            sessionStateStore.cache = mockCache;
            SessionStateStoreData sessionStateStoreData = sessionStateStore.GetItem(null, id, out locked, out lockAge, out lockId, out actions);

            A.CallTo(() => mockCache.TryCheckWriteLockAndGetData(out mockLockId, out sessionData, out sessionTimeout)).MustHaveHappened();


            Assert.Equal(true, Utility.CompareSessionStateStoreData(sessionStateStoreData, sssd));
            Assert.Equal(false, locked);
            Assert.Equal(TimeSpan.Zero, lockAge);
            Assert.Equal(actions, SessionStateActions.None);
        }
示例#24
0
        public override void SetAndReleaseItemExclusive(HttpContext context,
                                                        string id,
                                                        SessionStateStoreData item,
                                                        object lockId,
                                                        bool newItem)
        {
            var redis         = GetRedisConnection();
            var getLock       = redis.Hashes.Get(0, lockHashKey, id);
            var lockIdAsBytes = (byte[])lockId;
            var ms            = new MemoryStream();
            var writer        = new BinaryWriter(ms);

            if (item.Items as SessionStateItemCollection != null)
            {
                ((SessionStateItemCollection)item.Items).Serialize(writer);
            }

            writer.Close();

            byte[] sessionData     = ms.ToArray();
            var    sessionItemHash = new Dictionary <string, byte[]>();

            sessionItemHash.Add("initialize", new byte[] { 0 });
            sessionItemHash.Add("data", sessionData);
            sessionItemHash.Add("timeoutMinutes", BitConverter.GetBytes(item.Timeout));

            LockData lockData;

            getLock.Wait();
            if (getLock.Result == null)
            {
                redis.Hashes.Set(0, GetKeyForSessionId(id), sessionItemHash, false);
            }
            else if (LockData.TryParse(getLock.Result, out lockData) && Enumerable.SequenceEqual(lockData.LockId, lockIdAsBytes))
            {
                redis.Hashes.Set(0, GetKeyForSessionId(id), sessionItemHash, false);
                redis.Hashes.Remove(0, lockHashKey, id);
            }
        }
示例#25
0
 private static void AssertGotSession(SessionStateStoreData storeData, bool locked, TimeSpan lockAge,
                                      object lockId, bool exclusive = false, object originalLock = null)
 {
     Assert.IsNotNull(storeData);
     Assert.IsFalse(locked);
     Assert.AreEqual(TimeSpan.Zero, lockAge);
     if (exclusive)
     {
         if (originalLock == null)
         {
             Assert.IsNotNull(lockId);
         }
         else
         {
             Assert.AreEqual(originalLock, lockId);
         }
     }
     else
     {
         Assert.IsNull(lockId);
     }
 }
        public void SessionWriteCycle_Valid()
        {
            using (RedisServer redisServer = new RedisServer())
            {
                string sessionId = ResetRedisConnectionWrapperAndConfiguration();

                // Inserting empty session with "SessionStateActions.InitializeItem" flag into redis server
                RedisSessionStateProvider ssp = new RedisSessionStateProvider();
                ssp.CreateUninitializedItem(null, sessionId, (int)RedisSessionStateProvider.configuration.SessionTimeout.TotalMinutes);

                // Get write lock and session from cache
                bool                  locked;
                TimeSpan              lockAge;
                object                lockId;
                SessionStateActions   actions;
                SessionStateStoreData storeData = ssp.GetItemExclusive(null, sessionId, out locked, out lockAge, out lockId, out actions);

                // Get actual connection and varify lock and session timeout
                IDatabase actualConnection = GetRealRedisConnection();
                Assert.Equal(lockId.ToString(), actualConnection.StringGet(ssp.cache.Keys.LockKey).ToString());
                Assert.Equal(((int)RedisSessionStateProvider.configuration.SessionTimeout.TotalSeconds).ToString(), actualConnection.HashGet(ssp.cache.Keys.InternalKey, "SessionTimeout").ToString());

                // setting data as done by any normal session operation
                storeData.Items["key"] = "value";

                // session update
                ssp.SetAndReleaseItemExclusive(null, sessionId, storeData, lockId, false);
                Assert.Equal(1, actualConnection.HashGetAll(ssp.cache.Keys.DataKey).Length);

                // reset sessions timoue
                ssp.ResetItemTimeout(null, sessionId);

                // End request
                ssp.EndRequest(null);

                // remove data and lock from redis
                DisposeRedisConnectionWrapper();
            }
        }
        /// <summary>
        /// 设置并释放项
        /// </summary>
        /// <param name="context"></param>
        /// <param name="id"></param>
        /// <param name="item"></param>
        /// <param name="lockId"></param>
        /// <param name="newItem"></param>
        public void SetAndReleaseItem(System.Web.HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
        {
            MongoDBSessionDo session;

            if (newItem)
            {
                //删除过期的会话信息
                collection.Remove(Query.And(Query.EQ("_id", id), Query.LT("Expired", DateTime.Now)));

                //插入新的会话信息
                session = new MongoDBSessionDo()
                {
                    SessionId   = id,
                    Created     = DateTime.Now,
                    Expired     = DateTime.Now.AddMinutes(sessionStateSection.Timeout.TotalMinutes),
                    LockDate    = DateTime.Now,
                    LockId      = 0,
                    Locked      = false,
                    TimeOut     = item.Timeout,
                    SessionItem = Serialize((SessionStateItemCollection)item.Items),
                    Flags       = (Int32)SessionStateActions.None
                };
                collection.Save(session);
            }
            else
            {
                //更新会话信息
                var query = Query.And(Query.EQ("_id", id), Query.EQ("LockId", (Int32)lockId));
                session             = collection.FindOne(query);
                session.Expired     = DateTime.Now.AddMinutes(item.Timeout);
                session.SessionItem = Serialize((SessionStateItemCollection)item.Items);
                session.Locked      = false;
                var update = Update.Set("Expired", DateTime.Now.AddMinutes(item.Timeout))
                             .Set("SessionItem", Serialize((SessionStateItemCollection)item.Items))
                             .Set("Locked", false);

                collection.Update(query, update);
            }
        }
示例#28
0
        public override void RemoveItem(System.Web.HttpContext context, string id, object lockId,
                                        SessionStateStoreData item)
        {
            var query = Query.And(Query.EQ("_id", id), Query.EQ("App", ApplicationName),
                                  Query.EQ("LockId", (Int32)lockId));

            try
            {
                MongoCollection sessionCollection = GetSessionCollection();
                sessionCollection.Remove(query, writeMode);
            }
            catch (Exception e)
            {
                if (WriteExceptionsToEventLog)
                {
                    WriteToEventLog(e, "RemoveItem");
                    throw new ProviderException(ExceptionMessage);
                }

                throw;
            }
        }
 public override void RemoveItem(HttpContext context, string id, object lockIdObject,
                                 SessionStateStoreData item)
 {
     _log.DebugFormat("RemoveItem({0})", id);
     LogExceptions("RemoveItem()", () =>
     {
         SessionLockEntity lockId = (SessionLockEntity)lockIdObject;
         using (new LifetimeTimer(_log, "RemoveItem", 25))
             using (var transaction = _datastore.BeginTransaction(_callSettings))
             {
                 SessionLockEntity sessionLock = SessionLockFromEntity(
                     transaction.Lookup(_lockKeyFactory.CreateKey(id), _callSettings));
                 if (sessionLock == null || sessionLock.LockCount != lockId.LockCount)
                 {
                     return; // Something else locked it in the meantime.
                 }
                 transaction.Delete(_sessionKeyFactory.CreateKey(id),
                                    _lockKeyFactory.CreateKey(id));
                 transaction.Commit(_callSettings);
             }
     });
 }
示例#30
0
        private SessionStateStoreData DoGet(HttpContext context, string id, bool exclusive, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
        {
            locked      = false;
            lockId      = null;
            lockAge     = TimeSpan.Zero;
            actionFlags = SessionStateActions.None;

            SessionStateStoreData data = null;

            // 优先从缓存中读取Session数据
            if (Initializer.Is64Bit)
            {
                // TODO: 这里可能会有一个缺陷!
                // 假设场景:一个用户有多个并发的请求在服务端同时执行,此时获取到的是同一个Session引用对象,可能会有并发读写问题!
                // 要解决这个问题,需要做对象的克隆,会浪费一些性能,
                // 然则考虑到现实情况,人工点击的操作频率,是不大可能出现线程并发问题的,所以这里暂且不处理。

                data = _cacheStore.DoGet(context, id);
                if (data != null)
                {
                    // 即使缓存中存在Session数据,也要更新Session数据文件的【最后访问时间】,供后面文件加载时判断是否过期
                    FileStore.SetLastAccessTime(id, DateTime.Now);

                    return(data);
                }
            }


            // 缓存中如果不存在,有可能是AP.NET进程重启了,此时要从文件中读取Session数据
            // 读到结果后,再存入缓存,供后续请求使用
            data = _fileStore.DoGet(context, id, true);

            if (data != null)
            {
                _cacheStore.InsertCacheById(id, data);
            }

            return(data);
        }
    } // End of the SetItemExpireCallback method

    /// <summary>
    /// Set and realease a session post
    /// </summary>
    public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
    {
        // Serialize the SessionStateItemCollection as a string.
        string sessItems = Serialize((SessionStateItemCollection)item.Items);

        // Create a webshop session
        WebshopSession webshopSession = new WebshopSession();
        webshopSession.id = id;
        webshopSession.application_name = this.applicationName;
        webshopSession.created_date = DateTime.UtcNow;
        webshopSession.expires_date = DateTime.UtcNow.AddMinutes((Double)item.Timeout);
        webshopSession.lock_date = DateTime.UtcNow;
        webshopSession.lock_id = 0;
        webshopSession.timeout_limit = item.Timeout;
        webshopSession.locked = false;
        webshopSession.session_items = sessItems;
        webshopSession.flags = 0;

        if (newItem == true)
        {
            // Delete the session if it exists
            WebshopSession.DeleteOnId(id, this.applicationName);

            // Add the session
            WebshopSession.Add(webshopSession);

        }
        else
        {
            // Update session values
            webshopSession.lock_id = (Int32)lockId;

            // Update the session
            WebshopSession.UpdateWithLockId(webshopSession);
        }

    } // End of the SetAndReleaseItemExclusive method
示例#32
0
        /// <summary>
        /// This method removes the specified session item from the database
        /// </summary>
        /// <param name="context">The HttpContext object for the current request</param>
        /// <param name="id">The session ID for the current request</param>
        /// <param name="lockId">The lock identifier for the current request.</param>
        /// <param name="item">The session item to remove from the database.</param>
        public override void RemoveItem(System.Web.HttpContext context, string id, object lockId, SessionStateStoreData item)
        {
            try {
                using (MySqlConnection conn = new MySqlConnection(connectionString)) {
                    MySqlCommand cmd = new MySqlCommand("DELETE FROM my_aspnet_sessions " +
              " WHERE SessionId = @SessionId AND ApplicationId = @ApplicationId AND LockId = @LockId",
                        conn);

                    cmd.Parameters.AddWithValue("@SessionId", id);
                    cmd.Parameters.AddWithValue("@ApplicationId", ApplicationKey);
                    cmd.Parameters.AddWithValue("@LockId", lockId);

                    conn.Open();
                    cmd.ExecuteNonQuery();
                }

            } catch (MySqlException e) {
                HandleMySqlException(e, "RemoveItem");
            }
        }
示例#33
0
        /// <summary>
        /// This method updates the session time information in the database with the specified session item,
        /// and releases the lock.
        /// </summary>
        /// <param name="context">The HttpContext object for the current request</param>
        /// <param name="id">The session ID for the current request</param>
        /// <param name="item">The session item containing new values to update the session item in the database with.
        /// </param>
        /// <param name="lockId">The lock identifier for the current request.</param>
        /// <param name="newItem">A Boolean value that indicates whether or not the session item is new in the database.
        /// A false value indicates an existing item.
        /// </param>
        public override void SetAndReleaseItemExclusive(System.Web.HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
        {
            try {
                using (MySqlConnection conn = new MySqlConnection(connectionString)) {
                    // Serialize the SessionStateItemCollection as a byte array
                    byte[] sessItems = Serialize((SessionStateItemCollection)item.Items);
                    MySqlCommand cmd;
                    if (newItem) {
                        //Insert the new session item . If there was expired session
                        //with the same SessionId and Application id, it will be removed

                        cmd = new MySqlCommand(
                            "REPLACE INTO my_aspnet_sessions (SessionId, ApplicationId, Created, Expires," +
                " LockDate, LockId, Timeout, Locked, SessionItems, Flags)" +
                " Values(@SessionId, @ApplicationId, NOW(), NOW() + INTERVAL @Timeout MINUTE, NOW()," +
                " @LockId , @Timeout, @Locked, @SessionItems, @Flags)", conn);
                        cmd.Parameters.AddWithValue("@SessionId", id);
                        cmd.Parameters.AddWithValue("@ApplicationId", ApplicationKey);
                        cmd.Parameters.AddWithValue("@Timeout", item.Timeout);
                        cmd.Parameters.AddWithValue("@LockId", 0);
                        cmd.Parameters.AddWithValue("@Locked", 0);
                        cmd.Parameters.AddWithValue("@SessionItems", sessItems);
                        cmd.Parameters.AddWithValue("@Flags", 0);
                    } else {
                        //Update the existing session item.
                        cmd = new MySqlCommand(
                             "UPDATE my_aspnet_sessions SET Expires = NOW() + INTERVAL @Timeout MINUTE," +
                 " SessionItems = @SessionItems, Locked = @Locked " +
                 " WHERE SessionId = @SessionId AND ApplicationId = @ApplicationId AND LockId = @LockId",
                             conn);

                        cmd.Parameters.AddWithValue("@Timeout", item.Timeout);
                        cmd.Parameters.AddWithValue("@SessionItems", sessItems);
                        cmd.Parameters.AddWithValue("@Locked", 0);
                        cmd.Parameters.AddWithValue("@SessionId", id);
                        cmd.Parameters.AddWithValue("@ApplicationId", ApplicationKey);
                        cmd.Parameters.AddWithValue("@LockId", lockId);
                    }

                    conn.Open();
                    cmd.ExecuteNonQuery();
                }
            } catch (MySqlException e) {
                HandleMySqlException(e, "SetAndReleaseItemExclusive");
            }
        }
 public abstract virtual void RemoveItem(System.Web.HttpContext context, string id, object lockId, SessionStateStoreData item)
 {
 }
    /// <summary>
    /// Updates a locked session and releases the lock.
    /// </summary>
    /// <param name="context">The current request's HttpContext.</param>
    /// <param name="id">The session id for the current request.</param>
    /// <param name="item">The SessionStateStoreData object that contains the current session values to be stored.</param>
    /// <param name="lockId">The lock id for the current request.</param>
    /// <param name="newItem">Whether this is a new item or not.</param>
    public override void SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, object lockId, bool newItem)
    {
        // Set session
        client.Set(GetSessionHash(id), Serialize((SessionStateItemCollection)item.Items), sessionConfig.Timeout);

        // Remove lock (no longer exclusive)
        client.Delete(GetSessionLockHash(id));
    }
    /// <summary>
    /// Deletes a session.
    /// </summary>
    /// <param name="context">The current request's HttpContext.</param>
    /// <param name="id">The session id for the current request.</param>
    /// <param name="lockId">The lock id for the current request.</param>
    /// <param name="item">The SessionStateStoreData to be removed.</param>
    /// <remarks>The SessionStateStoreData is not used in this case since we use the session id to generate the Memcached key.</remarks>
    public override void RemoveItem(HttpContext context, String id, object lockId, SessionStateStoreData item)
    {
        client.Delete(GetSessionHash(id));

        // Notice we're not removing the lock here even though
        // we should, but since session ids are unique there's no reason
        // to waste time waiting for the delete to finish.

        // If you want to delete the lock object anyway uncomment the line below
        //client.Delete(GetSessionLockHash(id));
    }
 public abstract virtual void SetAndReleaseItemExclusive(System.Web.HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
 {
 }
    } // End of the Deserialize method

    #endregion

    #region Delete methods

    /// <summary>
    /// Remove a session item
    /// </summary>
    public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
    {
        // Delete the session post
        WebshopSession.DeleteOnId(id, this.applicationName, (int)lockId);
        
    } // End of the RemoveItem method