aboutsummaryrefslogtreecommitdiff
path: root/libs/VNLib.Plugins.Sessions.VNCache/src
diff options
context:
space:
mode:
Diffstat (limited to 'libs/VNLib.Plugins.Sessions.VNCache/src')
-rw-r--r--libs/VNLib.Plugins.Sessions.VNCache/src/IWebSessionIdFactory.cs57
-rw-r--r--libs/VNLib.Plugins.Sessions.VNCache/src/VNLib.Plugins.Sessions.VNCache.csproj39
-rw-r--r--libs/VNLib.Plugins.Sessions.VNCache/src/WebSession.cs125
-rw-r--r--libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionIdFactoryImpl.cs119
-rw-r--r--libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionProvider.cs139
-rw-r--r--libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionProviderEntry.cs82
6 files changed, 561 insertions, 0 deletions
diff --git a/libs/VNLib.Plugins.Sessions.VNCache/src/IWebSessionIdFactory.cs b/libs/VNLib.Plugins.Sessions.VNCache/src/IWebSessionIdFactory.cs
new file mode 100644
index 0000000..f284e00
--- /dev/null
+++ b/libs/VNLib.Plugins.Sessions.VNCache/src/IWebSessionIdFactory.cs
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2022 Vaughn Nugent
+*
+* Library: VNLib
+* Package: VNLib.Plugins.Essentials.Sessions.VNCache
+* File: IWebSessionIdFactory.cs
+*
+* IWebSessionIdFactory.cs is part of VNLib.Plugins.Essentials.Sessions.VNCache which is part of the larger
+* VNLib collection of libraries and utilities.
+*
+* VNLib.Plugins.Essentials.Sessions.VNCache is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as
+* published by the Free Software Foundation, either version 3 of the
+* License, or (at your option) any later version.
+*
+* VNLib.Plugins.Essentials.Sessions.VNCache is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+
+using System.Diagnostics.CodeAnalysis;
+
+using VNLib.Net.Http;
+
+namespace VNLib.Plugins.Sessions.VNCache
+{
+ /// <summary>
+ /// Id factory for <see cref="WebSessionProvider"/>
+ /// </summary>
+ internal interface IWebSessionIdFactory
+ {
+ /// <summary>
+ /// The maxium amount of time a session is valid for. Sessions will be invalidated
+ /// after this time
+ /// </summary>
+ TimeSpan ValidFor { get; }
+
+ /// <summary>
+ /// Gets a new session-id for the connection and manipulates the entity as necessary
+ /// </summary>
+ /// <param name="entity">The connection to generate the new session for</param>
+ /// <returns>The new session-id</returns>
+ string GenerateSessionId(IHttpEvent entity);
+
+ /// <summary>
+ /// Attempts to recover a session id from
+ /// </summary>
+ /// <param name="entity">The entity to get the session-id for</param>
+ /// <param name="sessionId">The found ID for the session if accepted</param>
+ /// <returns>True if a session id was found or set for the session</returns>
+ bool TryGetSessionId(IHttpEvent entity, [NotNullWhen(true)] out string? sessionId);
+ }
+}
diff --git a/libs/VNLib.Plugins.Sessions.VNCache/src/VNLib.Plugins.Sessions.VNCache.csproj b/libs/VNLib.Plugins.Sessions.VNCache/src/VNLib.Plugins.Sessions.VNCache.csproj
new file mode 100644
index 0000000..ddddab5
--- /dev/null
+++ b/libs/VNLib.Plugins.Sessions.VNCache/src/VNLib.Plugins.Sessions.VNCache.csproj
@@ -0,0 +1,39 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net6.0</TargetFramework>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+ <Authors>Vaughn Nugent</Authors>
+ <Copyright>Copyright © 2023 Vaughn Nugent</Copyright>
+ <Version>1.0.1.1</Version>
+ <SignAssembly>False</SignAssembly>
+ <PackageProjectUrl>https://www.vaughnugent.com/resources/software</PackageProjectUrl>
+
+ <EnableDynamicLoading>true</EnableDynamicLoading>
+ <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
+ <GenerateDocumentationFile>True</GenerateDocumentationFile>
+ <AnalysisLevel>latest-all</AnalysisLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Folder Include="Endpoints\" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\..\DataCaching\lib\VNLib.Plugins.Extensions.VNCache\src\VNLib.Plugins.Extensions.VNCache.csproj" />
+ <ProjectReference Include="..\..\..\..\Extensions\lib\VNLib.Plugins.Extensions.Loading\src\VNLib.Plugins.Extensions.Loading.csproj" />
+ <ProjectReference Include="..\..\VNLib.Plugins.Sessions.Cache.Client\src\VNLib.Plugins.Sessions.Cache.Client.csproj" />
+ </ItemGroup>
+
+ <Target Name="PostBuild" AfterTargets="PostBuildEvent">
+ <Exec Command="start xcopy &quot;$(TargetDir)&quot; &quot;F:\Programming\VNLib\devplugins\RuntimeAssets\$(TargetName)&quot; /E /Y /R" />
+ </Target>
+
+ <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
+ <Exec Command="erase &quot;F:\Programming\VNLib\devplugins\RuntimeAssets\$(TargetName)&quot; /q &gt; nul" />
+ </Target>
+
+</Project>
diff --git a/libs/VNLib.Plugins.Sessions.VNCache/src/WebSession.cs b/libs/VNLib.Plugins.Sessions.VNCache/src/WebSession.cs
new file mode 100644
index 0000000..8bd17ef
--- /dev/null
+++ b/libs/VNLib.Plugins.Sessions.VNCache/src/WebSession.cs
@@ -0,0 +1,125 @@
+/*
+* Copyright (c) 2022 Vaughn Nugent
+*
+* Library: VNLib
+* Package: VNLib.Plugins.Essentials.Sessions.VNCache
+* File: WebSession.cs
+*
+* WebSession.cs is part of VNLib.Plugins.Essentials.Sessions.VNCache which is part of the larger
+* VNLib collection of libraries and utilities.
+*
+* VNLib.Plugins.Essentials.Sessions.VNCache is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as
+* published by the Free Software Foundation, either version 3 of the
+* License, or (at your option) any later version.
+*
+* VNLib.Plugins.Essentials.Sessions.VNCache is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+
+using VNLib.Net.Http;
+using VNLib.Plugins.Essentials.Sessions;
+using VNLib.Plugins.Essentials.Extensions;
+using VNLib.Plugins.Sessions.Cache.Client;
+using static VNLib.Plugins.Essentials.Sessions.ISessionExtensions;
+
+namespace VNLib.Plugins.Sessions.VNCache
+{
+ internal class WebSession : RemoteSession
+ {
+ protected const ulong UPGRADE_MSK = 0b0000000000010000UL;
+
+ protected readonly Func<IHttpEvent, string, string> UpdateId;
+ private string? _oldId;
+
+ public WebSession(string sessionId, IRemoteCacheStore client, TimeSpan backgroundTimeOut, Func<IHttpEvent, string, string> UpdateId)
+ : base(sessionId, client, backgroundTimeOut)
+ {
+ this.UpdateId = UpdateId;
+ }
+
+ protected override void IndexerSet(string key, string value)
+ {
+ //Set value
+ base.IndexerSet(key, value);
+ switch (key)
+ {
+ //Set the upgrade flag when token data is modified
+ case LOGIN_TOKEN_ENTRY:
+ case TOKEN_ENTRY:
+ Flags.Set(UPGRADE_MSK);
+ break;
+ }
+ }
+
+ public override async Task WaitAndLoadAsync(IHttpEvent entity, CancellationToken cancellationToken)
+ {
+ //Wait for the session to load
+ await base.WaitAndLoadAsync(entity, cancellationToken);
+ //If the session is new, set to web mode
+ if (IsNew)
+ {
+ SessionType = SessionType.Web;
+ }
+ }
+
+ private async Task ProcessUpgradeAsync()
+ {
+ //Setup timeout cancellation for the update, to cancel it
+ using CancellationTokenSource cts = new(UpdateTimeout);
+ await Client.AddOrUpdateObjectAsync(_oldId!, SessionID, DataStore, cts.Token);
+ _oldId = null;
+ }
+
+ protected override ValueTask<Task?> UpdateResource(bool isAsync, IHttpEvent state)
+ {
+ Task? result = null;
+ //Check flags in priority level, Invalid is highest state priority
+ if (Flags.IsSet(INVALID_MSK))
+ {
+ //Clear all stored values
+ DataStore!.Clear();
+ //Reset ip-address
+ UserIP = state.Server.GetTrustedIp();
+ //Update created time
+ Created = DateTimeOffset.UtcNow;
+ //Init the new session-data
+ this.InitNewSession(state.Server);
+ //Restore session type
+ SessionType = SessionType.Web;
+ //generate new session-id and update the record in the store
+ _oldId = SessionID;
+ //Update the session-id
+ SessionID = UpdateId(state, _oldId);
+ //write update to server
+ result = Task.Run(ProcessUpgradeAsync);
+ }
+ else if (Flags.IsSet(UPGRADE_MSK | REGEN_ID_MSK))
+ {
+ //generate new session-id and update the record in the store
+ _oldId = SessionID;
+ //Update the session-id
+ SessionID = UpdateId(state, _oldId);
+ //Update created time
+ Created = DateTimeOffset.UtcNow;
+ //write update to server
+ result = Task.Run(ProcessUpgradeAsync);
+ }
+ else if (Flags.IsSet(MODIFIED_MSK))
+ {
+ //Send update to server
+ result = Task.Run(ProcessUpdateAsync);
+ }
+
+ //Clear all flags
+ Flags.ClearAll();
+
+ return ValueTask.FromResult<Task?>(null);
+ }
+ }
+}
diff --git a/libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionIdFactoryImpl.cs b/libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionIdFactoryImpl.cs
new file mode 100644
index 0000000..9480dc6
--- /dev/null
+++ b/libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionIdFactoryImpl.cs
@@ -0,0 +1,119 @@
+/*
+* Copyright (c) 2022 Vaughn Nugent
+*
+* Library: VNLib
+* Package: VNLib.Plugins.Essentials.Sessions.VNCache
+* File: WebSessionIdFactoryImpl.cs
+*
+* WebSessionIdFactoryImpl.cs is part of VNLib.Plugins.Essentials.Sessions.VNCache which is part of the larger
+* VNLib collection of libraries and utilities.
+*
+* VNLib.Plugins.Essentials.Sessions.VNCache is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as
+* published by the Free Software Foundation, either version 3 of the
+* License, or (at your option) any later version.
+*
+* VNLib.Plugins.Essentials.Sessions.VNCache is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+
+using System.Diagnostics.CodeAnalysis;
+
+using VNLib.Hashing;
+using VNLib.Net.Http;
+using VNLib.Utils.Memory;
+using VNLib.Utils.Extensions;
+using VNLib.Plugins.Essentials.Extensions;
+
+namespace VNLib.Plugins.Sessions.VNCache
+{
+ /// <summary>
+ /// <see cref="IWebSessionIdFactory"/> implementation, using
+ /// http cookies as session id storage
+ /// </summary>
+ internal sealed class WebSessionIdFactoryImpl : IWebSessionIdFactory
+ {
+ public TimeSpan ValidFor { get; }
+
+ public string GenerateSessionId(IHttpEvent entity)
+ {
+ //Random hex hash
+ string cookie = RandomHash.GetRandomBase32(_tokenSize);
+
+ //Set the session id cookie
+ entity.Server.SetCookie(SessionCookieName, cookie, ValidFor, secure: true, httpOnly: true);
+
+ //return session-id value from cookie value
+ return ComputeSessionIdFromCookie(cookie);
+ }
+
+ public bool TryGetSessionId(IHttpEvent entity, [NotNullWhen(true)] out string? sessionId)
+ {
+ //Get authorization token and make sure its not too large to cause a buffer overflow
+ if (entity.Server.GetCookie(SessionCookieName, out string? cookie) && (cookie.Length + SessionIdPrefix.Length) <= _bufferSize)
+ {
+ //Compute session id from token
+ sessionId = ComputeSessionIdFromCookie(cookie);
+
+ return true;
+ }
+ //Only add sessions for user-agents
+ else if(entity.Server.IsBrowser())
+ {
+ //Get a new session id
+ sessionId = GenerateSessionId(entity);
+
+ return true;
+ }
+ else
+ {
+ sessionId = null;
+ return false;
+ }
+ }
+
+ private readonly string SessionCookieName;
+ private readonly string SessionIdPrefix;
+ private readonly int _bufferSize;
+ private readonly int _tokenSize;
+
+ /// <summary>
+ /// Initialzies a new web session Id factory
+ /// </summary>
+ /// <param name="cookieSize">The size of the cookie in bytes</param>
+ /// <param name="sessionCookieName">The name of the session cookie</param>
+ /// <param name="sessionIdPrefix">The session-id internal prefix</param>
+ /// <param name="validFor">The time the session cookie is valid for</param>
+ public WebSessionIdFactoryImpl(uint cookieSize, string sessionCookieName, string sessionIdPrefix, TimeSpan validFor)
+ {
+ ValidFor = validFor;
+ SessionCookieName = sessionCookieName;
+ SessionIdPrefix = sessionIdPrefix;
+ _tokenSize = (int)cookieSize;
+ //Calc buffer size
+ _bufferSize = Math.Max(32, ((int)cookieSize * 3) + sessionIdPrefix.Length);
+ }
+
+
+ private string ComputeSessionIdFromCookie(string sessionId)
+ {
+ //Buffer to copy data to
+ using UnsafeMemoryHandle<char> buffer = Memory.UnsafeAlloc<char>(_bufferSize, true);
+
+ //Writer to accumulate data
+ ForwardOnlyWriter<char> writer = new(buffer.Span);
+
+ //Append prefix and session id
+ writer.Append(SessionIdPrefix);
+ writer.Append(sessionId);
+
+ //Compute base64 hash of token and
+ return ManagedHash.ComputeBase64Hash(writer.AsSpan(), HashAlg.SHA256);
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionProvider.cs b/libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionProvider.cs
new file mode 100644
index 0000000..44fb936
--- /dev/null
+++ b/libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionProvider.cs
@@ -0,0 +1,139 @@
+/*
+* Copyright (c) 2022 Vaughn Nugent
+*
+* Library: VNLib
+* Package: VNLib.Plugins.Essentials.Sessions.VNCache
+* File: WebSessionProvider.cs
+*
+* WebSessionProvider.cs is part of VNLib.Plugins.Essentials.Sessions.VNCache which is part of the larger
+* VNLib collection of libraries and utilities.
+*
+* VNLib.Plugins.Essentials.Sessions.VNCache is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as
+* published by the Free Software Foundation, either version 3 of the
+* License, or (at your option) any later version.
+*
+* VNLib.Plugins.Essentials.Sessions.VNCache is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+
+using System;
+
+using VNLib.Net.Http;
+using VNLib.Plugins.Essentials;
+using VNLib.Plugins.Essentials.Sessions;
+using VNLib.Plugins.Extensions.Loading;
+using VNLib.Plugins.Sessions.Cache.Client;
+
+namespace VNLib.Plugins.Sessions.VNCache
+{
+ /// <summary>
+ /// The implementation of a VNCache web based session
+ /// </summary>
+ [ConfigurationName("web")]
+ internal sealed class WebSessionProvider : SessionCacheClient, ISessionProvider
+ {
+ static readonly TimeSpan BackgroundUpdateTimeout = TimeSpan.FromSeconds(10);
+
+ private readonly IWebSessionIdFactory factory;
+ private readonly uint MaxConnections;
+
+ /// <summary>
+ /// Initializes a new <see cref="WebSessionProvider"/>
+ /// </summary>
+ /// <param name="client">The cache client to make cache operations against</param>
+ /// <param name="maxCacheItems">The max number of items to store in cache</param>
+ /// <param name="maxWaiting">The maxium number of waiting session events before 503s are sent</param>
+ /// <param name="factory">The session-id factory</param>
+ public WebSessionProvider(IRemoteCacheStore client, int maxCacheItems, uint maxWaiting, IWebSessionIdFactory factory) : base(client, maxCacheItems)
+ {
+ this.factory = factory;
+ MaxConnections = maxWaiting;
+ }
+
+ private string UpdateSessionId(IHttpEvent entity, string oldId)
+ {
+ //Generate and set a new sessionid
+ string newid = factory.GenerateSessionId(entity);
+ //Aquire lock on cache
+ lock (CacheLock)
+ {
+ //Change the cache lookup id
+ if (CacheTable.Remove(oldId, out RemoteSession? session))
+ {
+ CacheTable.Add(newid, session);
+ }
+ }
+ return newid;
+ }
+
+ protected override RemoteSession SessionCtor(string sessionId) => new WebSession(sessionId, Store, BackgroundUpdateTimeout, UpdateSessionId);
+
+ public async ValueTask<SessionHandle> GetSessionAsync(IHttpEvent entity, CancellationToken cancellationToken)
+ {
+ //Callback to close the session when the handle is closeed
+ static ValueTask HandleClosedAsync(ISession session, IHttpEvent entity)
+ {
+ return (session as SessionBase)!.UpdateAndRelease(true, entity);
+ }
+
+ try
+ {
+ //Get session id
+ if (!factory.TryGetSessionId(entity, out string? sessionId))
+ {
+ //Id not allowed/found, so do not attach a session
+ return SessionHandle.Empty;
+ }
+
+ //Limit max number of waiting clients
+ if (WaitingConnections > MaxConnections)
+ {
+ //Set 503 for temporary unavail
+ entity.CloseResponse(System.Net.HttpStatusCode.ServiceUnavailable);
+ return new SessionHandle(null, FileProcessArgs.VirtualSkip, null);
+ }
+
+ //Get session
+ RemoteSession session = await GetSessionAsync(entity, sessionId, cancellationToken);
+
+ //If the session is new (not in cache), then overwrite the session id with a new one as user may have specified their own
+ if (session.IsNew)
+ {
+ session.RegenID();
+ }
+
+ //Make sure the session has not expired yet
+ if (session.Created.Add(factory.ValidFor) < DateTimeOffset.UtcNow)
+ {
+ //Invalidate the session, so its technically valid for this request, but will be cleared on this handle close cycle
+ session.Invalidate();
+ //Clear basic login status
+ session.Token = null;
+ session.UserID = null;
+ session.Privilages = 0;
+ session.SetLoginToken(null);
+ }
+
+ return new SessionHandle(session, HandleClosedAsync);
+ }
+ catch (OperationCanceledException)
+ {
+ throw;
+ }
+ catch (SessionException)
+ {
+ throw;
+ }
+ catch (Exception ex)
+ {
+ throw new SessionException("Exception raised while retreiving or loading Web session", ex);
+ }
+ }
+ }
+}
diff --git a/libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionProviderEntry.cs b/libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionProviderEntry.cs
new file mode 100644
index 0000000..623975f
--- /dev/null
+++ b/libs/VNLib.Plugins.Sessions.VNCache/src/WebSessionProviderEntry.cs
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2022 Vaughn Nugent
+*
+* Library: VNLib
+* Package: VNLib.Plugins.Essentials.Sessions.VNCache
+* File: WebSessionProviderEntry.cs
+*
+* WebSessionProviderEntry.cs is part of VNLib.Plugins.Essentials.Sessions.VNCache which is part of the larger
+* VNLib collection of libraries and utilities.
+*
+* VNLib.Plugins.Essentials.Sessions.VNCache is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as
+* published by the Free Software Foundation, either version 3 of the
+* License, or (at your option) any later version.
+*
+* VNLib.Plugins.Essentials.Sessions.VNCache is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+
+using System.Text.Json;
+
+using VNLib.Net.Http;
+using VNLib.Utils.Logging;
+using VNLib.Utils.Extensions;
+using VNLib.Data.Caching;
+using VNLib.Plugins.Sessions.Cache.Client;
+using VNLib.Plugins.Extensions.Loading;
+using VNLib.Plugins.Extensions.VNCache;
+using VNLib.Plugins.Essentials.Sessions;
+
+namespace VNLib.Plugins.Sessions.VNCache
+{
+ public sealed class WebSessionProviderEntry : ISessionProvider
+ {
+ const string WEB_SESSION_CONFIG = "web";
+
+ private WebSessionProvider? _sessions;
+
+ //Web sessions can always be provided so long as cache is loaded
+ public bool CanProcess(IHttpEvent entity) => _sessions != null;
+
+ ValueTask<SessionHandle> ISessionProvider.GetSessionAsync(IHttpEvent entity, CancellationToken cancellationToken)
+ {
+ return _sessions!.GetSessionAsync(entity, cancellationToken);
+ }
+
+ public void Load(PluginBase plugin, ILogProvider localized)
+ {
+ //Try get vncache config element
+ IReadOnlyDictionary<string, JsonElement> webSessionConfig = plugin.GetConfigForType<WebSessionProvider>();
+
+ uint cookieSize = webSessionConfig["cookie_size"].GetUInt32();
+ string cookieName = webSessionConfig["cookie_name"].GetString() ?? throw new KeyNotFoundException($"Missing required element 'cookie_name' for config '{WEB_SESSION_CONFIG}'");
+ string cachePrefix = webSessionConfig["cache_prefix"].GetString() ?? throw new KeyNotFoundException($"Missing required element 'cache_prefix' for config '{WEB_SESSION_CONFIG}'");
+ int cacheLimit = (int)webSessionConfig["cache_size"].GetUInt32();
+ uint maxConnections = webSessionConfig["max_waiting_connections"].GetUInt32();
+ TimeSpan validFor = webSessionConfig["valid_for_sec"].GetTimeSpan(TimeParseType.Seconds);
+
+ //Init id factory
+ WebSessionIdFactoryImpl idFactory = new(cookieSize, cookieName, cachePrefix, validFor);
+
+ //Get shared global-cache
+ IGlobalCacheProvider globalCache = plugin.GetGlobalCache(localized);
+
+ //Create cache store from global cache
+ GlobalCacheStore cacheStore = new(globalCache);
+
+ //Init provider
+ _sessions = new(cacheStore, cacheLimit, maxConnections, idFactory);
+
+ //Load and run cached sessions on deferred task lib
+ _ = plugin.DeferTask(() => _sessions.CleanupExpiredSessionsAsync(localized, plugin.UnloadToken), 1000);
+
+ localized.Information("Session provider loaded");
+ }
+ }
+} \ No newline at end of file