aboutsummaryrefslogtreecommitdiff
path: root/Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionStore.cs
diff options
context:
space:
mode:
authorLibravatar vman <public@vaughnnugent.com>2022-11-04 22:12:55 -0400
committerLibravatar vman <public@vaughnnugent.com>2022-11-04 22:12:55 -0400
commitfdb055f4687c59c5bd0859388dace05766f7ce06 (patch)
tree1e98a250a0034622aa469beed9f5957cf5765b55 /Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionStore.cs
parent62203d58bd9a213e613e59841ded5d3007e294d1 (diff)
Jwt/jwk support, runtime provider updates
Diffstat (limited to 'Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionStore.cs')
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionStore.cs91
1 files changed, 40 insertions, 51 deletions
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionStore.cs b/Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionStore.cs
index 15c3002..388f998 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionStore.cs
+++ b/Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionStore.cs
@@ -3,7 +3,6 @@ using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
-using VNLib.Hashing;
using VNLib.Net.Http;
using VNLib.Net.Sessions;
using VNLib.Utils;
@@ -11,10 +10,10 @@ using VNLib.Utils.Async;
using VNLib.Utils.Extensions;
using VNLib.Plugins.Essentials.Extensions;
+#nullable enable
namespace VNLib.Plugins.Essentials.Sessions.Memory
{
-
/// <summary>
/// An <see cref="ISessionProvider"/> for in-process-memory backed sessions
/// </summary>
@@ -23,11 +22,13 @@ namespace VNLib.Plugins.Essentials.Sessions.Memory
private readonly Dictionary<string, MemorySession> SessionsStore;
internal readonly MemorySessionConfig Config;
+ internal readonly SessionIdFactory IdFactory;
public MemorySessionStore(MemorySessionConfig config)
{
Config = config;
SessionsStore = new(config.MaxAllowedSessions, StringComparer.Ordinal);
+ IdFactory = new(config.SessionIdSizeBytes, config.SessionCookieID, config.SessionTimeout);
}
///<inheritdoc/>
@@ -36,11 +37,11 @@ namespace VNLib.Plugins.Essentials.Sessions.Memory
static ValueTask SessionHandleClosedAsync(ISession session, IHttpEvent ev)
{
- return (session as MemorySession).UpdateAndRelease(true, ev);
+ return (session as MemorySession)!.UpdateAndRelease(true, ev);
}
- //Check for previous session cookie
- if (entity.Server.RequestCookies.TryGetNonEmptyValue(Config.SessionCookieID, out string sessionId))
+ //Try to get the id for the session
+ if (IdFactory.TryGetSessionId(entity, out string? sessionId))
{
//Try to get the old record or evict it
ERRNO result = SessionsStore.TryGetOrEvictRecord(sessionId, out MemorySession session);
@@ -50,63 +51,51 @@ namespace VNLib.Plugins.Essentials.Sessions.Memory
await session.WaitOneAsync(cancellationToken);
return new (session, SessionHandleClosedAsync);
}
- //Continue creating a new session
+ else
+ {
+ //try to cleanup expired records
+ GC();
+ //Make sure there is enough room to add a new session
+ if (SessionsStore.Count >= Config.MaxAllowedSessions)
+ {
+ entity.Server.SetNoCache();
+ //Set 503 when full
+ entity.CloseResponse(System.Net.HttpStatusCode.ServiceUnavailable);
+ //Cannot service new session
+ return new(null, FileProcessArgs.VirtualSkip, null);
+ }
+ //Initialze a new session
+ session = new(sessionId, entity.Server.GetTrustedIp(), UpdateSessionId);
+ //Increment the semaphore
+ (session as IWaitHandle).WaitOne();
+ //store the session in cache while holding semaphore, and set its expiration
+ SessionsStore.StoreRecord(session.SessionID, session, Config.SessionTimeout);
+ //Init new session handle
+ return new (session, SessionHandleClosedAsync);
+ }
}
-
- //Dont service non browsers for new sessions
- if (!entity.Server.IsBrowser())
+ else
{
return SessionHandle.Empty;
}
-
- //try to cleanup expired records
- SessionsStore.CollectRecords();
- //Make sure there is enough room to add a new session
- if (SessionsStore.Count >= Config.MaxAllowedSessions)
- {
- entity.Server.SetNoCache();
- //Set 503 when full
- entity.CloseResponse(System.Net.HttpStatusCode.ServiceUnavailable);
- //Cannot service new session
- return new(null, FileProcessArgs.VirtualSkip, null);
- }
- //Initialze a new session
- MemorySession ms = new(entity.Server.GetTrustedIp(), this);
- //Set session cookie
- SetSessionCookie(entity, ms);
- //Increment the semaphore
- (ms as IWaitHandle).WaitOne();
- //store the session in cache while holding semaphore, and set its expiration
- SessionsStore.StoreRecord(ms.SessionID, ms, Config.SessionTimeout);
- //Init new session handle
- return new SessionHandle(ms, SessionHandleClosedAsync);
}
- /// <summary>
- /// Gets a new unique sessionid for sessions
- /// </summary>
- internal string NewSessionID => RandomHash.GetRandomHex((int)Config.SessionIdSizeBytes);
-
- internal void UpdateRecord(string newSessId, MemorySession session)
+ private string UpdateSessionId(IHttpEvent entity, string oldId)
{
+ //Generate and set a new sessionid
+ string newid = IdFactory.GenerateSessionId(entity);
+ //Aquire lock on cache
lock (SessionsStore)
{
- //Remove old record from the store
- SessionsStore.Remove(session.SessionID);
- //Insert the new session
- SessionsStore.Add(newSessId, session);
+ //Change the cache lookup id
+ if (SessionsStore.Remove(oldId, out MemorySession? session))
+ {
+ SessionsStore.Add(newid, session);
+ }
}
+ return newid;
}
- /// <summary>
- /// Sets a standard session cookie for an entity/connection
- /// </summary>
- /// <param name="entity">The entity to set the cookie on</param>
- /// <param name="session">The session attached to the </param>
- internal void SetSessionCookie(IHttpEvent entity, MemorySession session)
- {
- //Set session cookie
- entity.Server.SetCookie(Config.SessionCookieID, session.SessionID, null, "/", Config.SessionTimeout, CookieSameSite.Lax, true, true);
- }
+
/// <summary>
/// Evicts all sessions from the current store
/// </summary>