/// <summary> /// Checks if any items have changed in the Session, and stores the results to Redis /// </summary> /// <param name="context">The HttpContext of the current web request</param> /// <param name="id">The Session Id and Redis key name</param> /// <param name="item">The Session properties</param> /// <param name="lockId">The object used to exclusively lock the Session (there shouldn't be one)</param> /// <param name="newItem">Whether or not the Session was created in this HttpContext</param> public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { try { string currentRedisHashId = RedisSessionStateStoreProvider.RedisHashIdFromSessionId( new HttpContextWrapper(context), id); LocalSharedSessionDictionary sharedSessDict = new LocalSharedSessionDictionary(); RedisSessionStateItemCollection redisItems = sharedSessDict.GetSessionForEndRequest(currentRedisHashId); if (redisItems != null) { RedisSessionStateStoreProvider.SerializeToRedis( new HttpContextWrapper(context), redisItems, currentRedisHashId, this.SessionTimeout); } } catch (Exception e) { if (RedisSessionConfig.SessionExceptionLoggingDel != null) { RedisSessionConfig.SessionExceptionLoggingDel(e); } } }
/// <summary> /// This method is called when the Session decides that no element has been modified. Due to /// the implementation of Falcon.Libraries.Sessions.RedisSessionStateItemCollection, this method /// is never called (because the .Dirty property always returns true). The reason is because /// we always dirty-check the collection in SetAndReleaseItemExclusive to ensure Session /// correctness. /// </summary> /// <param name="context">The HttpContext of the current web request</param> /// <param name="id">The SessionId of the current request</param> /// <param name="lockId">A lock around the current Session so no other web request can modify it /// simultaneously</param> public override void ReleaseItemExclusive(HttpContext context, string id, object lockId) { // if, for some reason, we are in this method we still want to record that we are no // longer going to use a session in local cache string currentRedisHashId = RedisSessionStateStoreProvider.RedisHashIdFromSessionId( new HttpContextWrapper(context), id); LocalSharedSessionDictionary sharedSessDict = new LocalSharedSessionDictionary(); sharedSessDict.GetSessionForEndRequest(currentRedisHashId); }
/// <summary> /// Deletes an entire Session from Redis by removing the key. /// </summary> /// <param name="context">The HttpContext of the current request</param> /// <param name="id">The Session Id</param> /// <param name="lockId">The object used to lock the Session</param> /// <param name="item">The Session's properties</param> public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item) { RedisConnectionWrapper rConnWrap = RedisSessionStateStoreProvider.RedisConnWrapperFromContext( new HttpContextWrapper(context)); IDatabase redisConn = rConnWrap.GetConnection(); redisConn.KeyDelete( RedisSessionStateStoreProvider.RedisHashIdFromSessionId( new HttpContextWrapper(context), id), CommandFlags.FireAndForget); }
/// <summary> /// Initializes a new instance of the RedisSessionAccessor class, which provides access to a /// local Redis items collection outside of the standard ASP.NET pipeline Session hooks /// </summary> /// <param name="context">The context of the current request</param> public RedisSessionAccessor(HttpContextBase context) { try { this.RequestContext = context; this.SharedSessions = new LocalSharedSessionDictionary(); // if we have the session ID if (this.RequestContext.Request.Cookies[RedisSessionConfig.SessionHttpCookieName] != null) { this.SessionRedisHashKey = RedisSessionStateStoreProvider.RedisHashIdFromSessionId( this.RequestContext, this.RequestContext.Request.Cookies[RedisSessionConfig.SessionHttpCookieName].Value); } if (!string.IsNullOrEmpty(this.SessionRedisHashKey)) { RedisSessionStateItemCollection items = this.SharedSessions.GetSessionForBeginRequest( this.SessionRedisHashKey, (string redisKey) => { return(RedisSessionStateStoreProvider.GetItemFromRedis( redisKey, this.RequestContext, RedisSessionConfig.SessionTimeout)); }); this.Session = new FakeHttpSessionState(items); } } catch (Exception exc) { if (RedisSessionConfig.RedisSessionAccessorExceptionLoggingDel != null) { string errMsg = string.Format( "RedisSessionAccessor unable to get Redis session for id: {0}", this.SessionRedisHashKey); RedisSessionConfig.RedisSessionAccessorExceptionLoggingDel( context, errMsg, exc); } } }
/// <summary> /// Gets a Session from Redis, indicating a non-exclusive lock on the Session. Note that GetItemExclusive /// calls this method internally, meaning we do not support locks at all retrieving the Session. /// </summary> /// <param name="context">The HttpContext of the current request</param> /// <param name="id">The Session Id, which is the key name in Redis</param> /// <param name="locked">Whether or not the Session is locked to exclusive access for a single request /// thread</param> /// <param name="lockAge">The age of the lock</param> /// <param name="lockId">The object used to lock the Session</param> /// <param name="actions">Whether or not to initialize the Session (never)</param> /// <returns>The Session objects wrapped in a SessionStateStoreData object</returns> public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { locked = false; lockAge = new TimeSpan(0); lockId = null; actions = SessionStateActions.None; try { string parsedRedisHashId = RedisSessionStateStoreProvider.RedisHashIdFromSessionId( new HttpContextWrapper(context), id); LocalSharedSessionDictionary sharedSessDict = new LocalSharedSessionDictionary(); RedisSessionStateItemCollection items = sharedSessDict.GetSessionForBeginRequest( parsedRedisHashId, (redisKey) => { return(RedisSessionStateStoreProvider.GetItemFromRedis( redisKey, new HttpContextWrapper(context), this.SessionTimeout)); }); return(new SessionStateStoreData( items, SessionStateUtility.GetSessionStaticObjects(context), Convert.ToInt32(this.SessionTimeout.TotalMinutes))); } catch (Exception e) { if (RedisSessionConfig.SessionExceptionLoggingDel != null) { RedisSessionConfig.SessionExceptionLoggingDel(e); } } return(this.CreateNewStoreData(context, Convert.ToInt32(this.SessionTimeout.TotalMinutes))); }