aboutsummaryrefslogtreecommitdiff
path: root/VNLib.Plugins.Essentials.Content.Routing
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-01-12 17:47:40 -0500
committerLibravatar vnugent <public@vaughnnugent.com>2023-01-12 17:47:40 -0500
commit551066ed9a255bd47c1c5789ec1998fda64bd5aa (patch)
treed6caceb0e7caa44478c6611903b4b7e120964c89 /VNLib.Plugins.Essentials.Content.Routing
parentb6481038bc6573af30492e9ce52b36d9f64195f3 (diff)
Large project reorder and consolidation
Diffstat (limited to 'VNLib.Plugins.Essentials.Content.Routing')
-rw-r--r--VNLib.Plugins.Essentials.Content.Routing/Model/Route.cs71
-rw-r--r--VNLib.Plugins.Essentials.Content.Routing/Model/RouteStore.cs68
-rw-r--r--VNLib.Plugins.Essentials.Content.Routing/Model/RoutingContext.cs41
-rw-r--r--VNLib.Plugins.Essentials.Content.Routing/PageRouterEntry.cs68
-rw-r--r--VNLib.Plugins.Essentials.Content.Routing/RouteComparer.cs77
-rw-r--r--VNLib.Plugins.Essentials.Content.Routing/Router.cs161
-rw-r--r--VNLib.Plugins.Essentials.Content.Routing/VNLib.Plugins.Essentials.Content.Routing.csproj55
7 files changed, 0 insertions, 541 deletions
diff --git a/VNLib.Plugins.Essentials.Content.Routing/Model/Route.cs b/VNLib.Plugins.Essentials.Content.Routing/Model/Route.cs
deleted file mode 100644
index 8c52725..0000000
--- a/VNLib.Plugins.Essentials.Content.Routing/Model/Route.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-* Copyright (c) 2022 Vaughn Nugent
-*
-* Library: VNLib
-* Package: VNLib.Plugins.Essentials.Content.Routing
-* File: Route.cs
-*
-* Route.cs is part of VNLib.Plugins.Essentials.Content.Routing which is part of the larger
-* VNLib collection of libraries and utilities.
-*
-* VNLib.Plugins.Essentials.Content.Routing 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.Content.Routing 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 System.ComponentModel.DataAnnotations.Schema;
-
-using Microsoft.EntityFrameworkCore;
-
-using VNLib.Plugins.Extensions.Data;
-
-namespace VNLib.Plugins.Essentials.Content.Routing.Model
-{
- [Index(nameof(Id), IsUnique = true)]
- internal class Route : DbModelBase
- {
- public override string Id { get; set; }
- public override DateTime Created { get; set; }
- public override DateTime LastModified { get; set; }
-
- public string Hostname { get; set; }
- public string MatchPath { get; set; }
- [Column("Privilage")]
- public long _privilage
- {
- get => (long)Privilage;
- set => Privilage = (ulong)value;
- }
- [NotMapped]
- public ulong Privilage { get; set; }
-
- public string Alternate { get; set; }
- public FpRoutine Routine { get; set; }
-
- /// <summary>
- /// The processing arguments that match the route
- /// </summary>
- [NotMapped]
- public FileProcessArgs MatchArgs
- {
- get
- {
- return new FileProcessArgs()
- {
- Alternate = this.Alternate,
- Routine = (FpRoutine) Routine
- };
- }
- }
- }
-}
diff --git a/VNLib.Plugins.Essentials.Content.Routing/Model/RouteStore.cs b/VNLib.Plugins.Essentials.Content.Routing/Model/RouteStore.cs
deleted file mode 100644
index e623228..0000000
--- a/VNLib.Plugins.Essentials.Content.Routing/Model/RouteStore.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-* Copyright (c) 2022 Vaughn Nugent
-*
-* Library: VNLib
-* Package: VNLib.Plugins.Essentials.Content.Routing
-* File: RouteStore.cs
-*
-* RouteStore.cs is part of VNLib.Plugins.Essentials.Content.Routing which is part of the larger
-* VNLib collection of libraries and utilities.
-*
-* VNLib.Plugins.Essentials.Content.Routing 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.Content.Routing 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 System.Linq;
-
-using Microsoft.EntityFrameworkCore;
-
-using VNLib.Plugins.Extensions.Data;
-
-namespace VNLib.Plugins.Essentials.Content.Routing.Model
-{
- internal class RouteStore : DbStore<Route>
- {
- private readonly DbContextOptions Options;
-
- public RouteStore(DbContextOptions options)
- {
- Options = options;
- }
-
- public override string RecordIdBuilder => Guid.NewGuid().ToString("N");
-
- protected override IQueryable<Route> GetCollectionQueryBuilder(TransactionalDbContext context, params string[] constraints)
- {
- string hostname = constraints[0];
- return from route in context.Set<Route>()
- where route.Hostname == hostname
- select route;
- }
-
- protected override IQueryable<Route> GetSingleQueryBuilder(TransactionalDbContext context, params string[] constraints)
- {
- string id = constraints[0];
- return from route in context.Set<Route>()
- where route.Id == id
- select route;
- }
-
- public override TransactionalDbContext NewContext() => new RoutingContext(Options);
-
- protected override void OnRecordUpdate(Route newRecord, Route currentRecord)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/VNLib.Plugins.Essentials.Content.Routing/Model/RoutingContext.cs b/VNLib.Plugins.Essentials.Content.Routing/Model/RoutingContext.cs
deleted file mode 100644
index 0cbd90f..0000000
--- a/VNLib.Plugins.Essentials.Content.Routing/Model/RoutingContext.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-* Copyright (c) 2022 Vaughn Nugent
-*
-* Library: VNLib
-* Package: VNLib.Plugins.Essentials.Content.Routing
-* File: RoutingContext.cs
-*
-* RoutingContext.cs is part of VNLib.Plugins.Essentials.Content.Routing which is part of the larger
-* VNLib collection of libraries and utilities.
-*
-* VNLib.Plugins.Essentials.Content.Routing 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.Content.Routing 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 Microsoft.EntityFrameworkCore;
-
-using VNLib.Plugins.Extensions.Data;
-
-namespace VNLib.Plugins.Essentials.Content.Routing.Model
-{
- internal class RoutingContext : TransactionalDbContext
- {
- public DbSet<Route> Routes { get; set; }
-
- public RoutingContext(DbContextOptions options) :base(options)
- {
- }
- }
-}
diff --git a/VNLib.Plugins.Essentials.Content.Routing/PageRouterEntry.cs b/VNLib.Plugins.Essentials.Content.Routing/PageRouterEntry.cs
deleted file mode 100644
index 10b7075..0000000
--- a/VNLib.Plugins.Essentials.Content.Routing/PageRouterEntry.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-* Copyright (c) 2022 Vaughn Nugent
-*
-* Library: VNLib
-* Package: VNLib.Plugins.Essentials.Content.Routing
-* File: PageRouterEntry.cs
-*
-* PageRouterEntry.cs is part of VNLib.Plugins.Essentials.Content.Routing which is part of the larger
-* VNLib collection of libraries and utilities.
-*
-* VNLib.Plugins.Essentials.Content.Routing 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.Content.Routing 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 System.Threading.Tasks;
-using System.Collections.Generic;
-
-using VNLib.Utils.Logging;
-
-namespace VNLib.Plugins.Essentials.Content.Routing
-{
- public sealed class PageRouterEntry : PluginBase, IPageRouter
- {
- public override string PluginName => "Essentials.Router";
-
- private Router PageRouter;
- public ValueTask<FileProcessArgs> RouteAsync(HttpEntity entity) => PageRouter.RouteAsync(entity);
-
- protected override void OnLoad()
- {
- try
- {
- //Init router
- PageRouter = new(this);
- Log.Information("Plugin loaded");
- }
- catch (KeyNotFoundException knf)
- {
- Log.Error("Plugin failed to load, missing required configuration variables {err}", knf.Message);
- }
- }
-
- protected override void OnUnLoad()
- {
- Log.Information("Plugin unloaded");
- }
-
- protected override void ProcessHostCommand(string cmd)
- {
- if(cmd.Contains("reset", StringComparison.OrdinalIgnoreCase))
- {
- PageRouter?.ResetRoutes();
- Log.Information("Routing table reset");
- }
- }
- }
-}
diff --git a/VNLib.Plugins.Essentials.Content.Routing/RouteComparer.cs b/VNLib.Plugins.Essentials.Content.Routing/RouteComparer.cs
deleted file mode 100644
index 189da62..0000000
--- a/VNLib.Plugins.Essentials.Content.Routing/RouteComparer.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-* Copyright (c) 2022 Vaughn Nugent
-*
-* Library: VNLib
-* Package: VNLib.Plugins.Essentials.Content.Routing
-* File: RouteComparer.cs
-*
-* RouteComparer.cs is part of VNLib.Plugins.Essentials.Content.Routing which is part of the larger
-* VNLib collection of libraries and utilities.
-*
-* VNLib.Plugins.Essentials.Content.Routing 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.Content.Routing 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.Collections.Generic;
-
-using VNLib.Plugins.Essentials.Content.Routing.Model;
-
-using static VNLib.Plugins.Essentials.Accounts.AccountManager;
-
-namespace VNLib.Plugins.Essentials.Content.Routing
-{
- /// <summary>
- /// Sorts routing rules based on closest match path/hostname routing along with privilage priority
- /// </summary>
- internal class RouteComparer : IComparer<Route>
- {
- //The idea is that hostnames without wildcards are exact, and hostnames with wildcards are "catch all"
- public int Compare(Route x, Route y)
- {
- int val = 0;
- //If x contains a wildcard in the hostname, then it is less than y
- if (x.Hostname.Contains('*'))
- {
- val--;
- }
- //If y containts a wildcard, then y is less than x
- if (y.Hostname.Contains('*'))
- {
- val++;
- }
- //If there was no wildcard, check paths
- if (val == 0)
- {
- //If x containts a wildcard in the path, then x is less than y
- if (x.MatchPath.Contains('*'))
- {
- val--;
- }
- //If y containts a wildcard in the path, then y is less than x
- if (y.MatchPath.Contains('*'))
- {
- val++;
-
- }
- }
- //If hostnames and paths are stil equal, check privilage level
- if (val == 0)
- {
- //Higher privilage routine is greater than lower privilage
- val = (x.Privilage & LEVEL_MSK) > (y.Privilage & LEVEL_MSK) ? 1 : -1;
- }
- //If both contain (or are) wildcards, then they are equal
- return val;
- }
- }
-}
diff --git a/VNLib.Plugins.Essentials.Content.Routing/Router.cs b/VNLib.Plugins.Essentials.Content.Routing/Router.cs
deleted file mode 100644
index 4dc320a..0000000
--- a/VNLib.Plugins.Essentials.Content.Routing/Router.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-* Copyright (c) 2022 Vaughn Nugent
-*
-* Library: VNLib
-* Package: VNLib.Plugins.Essentials.Content.Routing
-* File: Router.cs
-*
-* Router.cs is part of VNLib.Plugins.Essentials.Content.Routing which is part of the larger
-* VNLib collection of libraries and utilities.
-*
-* VNLib.Plugins.Essentials.Content.Routing 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.Content.Routing 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 System.Linq;
-using System.Buffers;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Collections.Generic;
-using System.Collections.Concurrent;
-using System.Collections.ObjectModel;
-
-using VNLib.Net.Http;
-using VNLib.Utils.Logging;
-using VNLib.Plugins.Extensions.Loading.Sql;
-using VNLib.Plugins.Extensions.Loading.Events;
-using VNLib.Plugins.Essentials.Content.Routing.Model;
-using static VNLib.Plugins.Essentials.Accounts.AccountManager;
-
-namespace VNLib.Plugins.Essentials.Content.Routing
-{
- internal class Router : IPageRouter, IIntervalScheduleable
- {
- private static readonly RouteComparer Comparer = new();
-
- private readonly RouteStore Store;
-
- private readonly ConcurrentDictionary<IWebRoot, Task<ReadOnlyCollection<Route>>> RouteTable;
-
- public Router(PluginBase plugin)
- {
- Store = new(plugin.GetContextOptions());
- plugin.ScheduleInterval(this, TimeSpan.FromSeconds(30));
- RouteTable = new();
- }
-
- ///<inheritdoc/>
- public async ValueTask<FileProcessArgs> RouteAsync(HttpEntity entity)
- {
- ulong privilage = READ_MSK;
- //Only select privilages for logged-in users
- if (entity.Session.IsSet && entity.LoginCookieMatches() || entity.TokenMatches())
- {
- privilage = entity.Session.Privilages;
- }
- //Get the routing table for the current host
- ReadOnlyCollection<Route> routes = await RouteTable.GetOrAdd(entity.RequestedRoot, LoadRoutesAsync);
- //Find the proper routine for the connection
- return FindArgs(routes, entity.RequestedRoot.Hostname, entity.Server.Path, privilage);
- }
-
- /// <summary>
- /// Clears all cached routines from the database
- /// </summary>
- public void ResetRoutes() => RouteTable.Clear();
-
- private async Task<ReadOnlyCollection<Route>> LoadRoutesAsync(IWebRoot root)
- {
- List<Route> collection = new();
- //Load all routes
- _ = await Store.GetPageAsync(collection, 0, int.MaxValue);
- //Select only exact match routes, or wildcard routes
- return (from r in collection
- where r.Hostname.EndsWith(root.Hostname, StringComparison.OrdinalIgnoreCase) || r.Hostname == "*"
- //Orderby path "specificity" longer pathts are generally more specific, so filter order
- orderby r.MatchPath.Length ascending
- select r)
- .ToList()
- .AsReadOnly();
- }
-
-
- private static FileProcessArgs FindArgs(ReadOnlyCollection<Route> routes, string hostname, string path, ulong privilages)
- {
- //Rent an array to sort routes for the current user
- Route[] matchArray = ArrayPool<Route>.Shared.Rent(routes.Count);
- int count = 0;
- //Search for routes that match
- for(int i = 0; i < routes.Count; i++)
- {
- if(Matches(routes[i], hostname, path, privilages))
- {
- //Add to sort array
- matchArray[count++] = routes[i];
- }
- }
- //If no matches are found, return continue routine
- if (count == 0)
- {
- //Return the array to the pool
- ArrayPool<Route>.Shared.Return(matchArray);
- return FileProcessArgs.Continue;
- }
- //Get sorting span for matches
- Span<Route> found = matchArray.AsSpan(0, count);
- //Sort the found rules
- found.Sort(Comparer);
- //Select the last element
- Route selected = found[^1];
- //Return array to pool
- ArrayPool<Route>.Shared.Return(matchArray);
- return selected.MatchArgs;
- }
-
- /// <summary>
- /// Determines if a route can be matched to a hostname, resource path, and a
- /// privilage level
- /// </summary>
- /// <param name="route">The route to test against</param>
- /// <param name="hostname">The hostname to test</param>
- /// <param name="path">The resource path to test</param>
- /// <param name="privilages">The privialge level to search for</param>
- /// <returns>True if the route can be matched to the resource and the privialge level</returns>
- private static bool Matches(Route route, ReadOnlySpan<char> hostname, ReadOnlySpan<char> path, ulong privilages)
- {
- //Get span of hostname to stop string heap allocations during comparisons
- ReadOnlySpan<char> routineHost = route.Hostname;
- ReadOnlySpan<char> routinePath = route.MatchPath;
- //Test if hostname hostname matches exactly (may be wildcard) or hostname begins with a wildcard and ends with the request hostname
- bool hostMatch = routineHost.SequenceEqual(hostname) || (routineHost.Length > 1 && routineHost[0] == '*' && hostname.EndsWith(routineHost[1..]));
- if (!hostMatch)
- {
- return false;
- }
- //Test if path is a wildcard, matches exactly, or if the path is a wildcard path, that the begining of the reqest path matches the routine path
- bool pathMatch = routinePath == "*" || routinePath.SequenceEqual(path) || (routinePath.Length > 1 && routinePath[^1] == '*' && path.StartsWith(routinePath[..^1]));
- if (!pathMatch)
- {
- return false;
- }
- //Test if the level and group privilages match for the current routine
- return (privilages & LEVEL_MSK) >= (route.Privilage & LEVEL_MSK) && (route.Privilage & GROUP_MSK) == (privilages & GROUP_MSK);
- }
-
- Task IIntervalScheduleable.OnIntervalAsync(ILogProvider log, CancellationToken cancellationToken)
- {
- return Task.CompletedTask;
- }
- }
-}
diff --git a/VNLib.Plugins.Essentials.Content.Routing/VNLib.Plugins.Essentials.Content.Routing.csproj b/VNLib.Plugins.Essentials.Content.Routing/VNLib.Plugins.Essentials.Content.Routing.csproj
deleted file mode 100644
index 30c8fd4..0000000
--- a/VNLib.Plugins.Essentials.Content.Routing/VNLib.Plugins.Essentials.Content.Routing.csproj
+++ /dev/null
@@ -1,55 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <TargetFramework>net6.0</TargetFramework>
- <Authors>Vaughn Nugent</Authors>
- <Version>1.0.1.1</Version>
- <Copyright>Copyright © 2022 Vaughn Nugent</Copyright>
- <PackageProjectUrl>https://www.vaughnnugent.com</PackageProjectUrl>
- <AssemblyName>PageRouter</AssemblyName>
- <SignAssembly>True</SignAssembly>
- <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile>
- </PropertyGroup>
-
- <!-- Resolve nuget dll files and store them in the output dir -->
- <PropertyGroup>
- <!--Enable dynamic loading-->
- <EnableDynamicLoading>true</EnableDynamicLoading>
- <Nullable>enable</Nullable>
- <AnalysisLevel>latest-all</AnalysisLevel>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
- <Deterministic>False</Deterministic>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
- <Deterministic>False</Deterministic>
- </PropertyGroup>
- <ItemGroup>
- <PackageReference Include="ErrorProne.NET.CoreAnalyzers" Version="0.1.2">
- <PrivateAssets>all</PrivateAssets>
- <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
- </PackageReference>
- <PackageReference Include="ErrorProne.NET.Structs" Version="0.1.2">
- <PrivateAssets>all</PrivateAssets>
- <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
- </PackageReference>
- </ItemGroup>
-
- <ItemGroup>
- <ProjectReference Include="..\..\Extensions\VNLib.Plugins.Extensions.Data\VNLib.Plugins.Extensions.Data.csproj" />
- <ProjectReference Include="..\..\Extensions\VNLib.Plugins.Extensions.Loading.Sql\VNLib.Plugins.Extensions.Loading.Sql.csproj" />
- <ProjectReference Include="..\..\Extensions\VNLib.Plugins.Extensions.Loading\VNLib.Plugins.Extensions.Loading.csproj" />
- <ProjectReference Include="..\..\PluginBase\VNLib.Plugins.PluginBase.csproj" />
- </ItemGroup>
-
- <ItemGroup>
- <None Update="PageRouter.json">
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- </None>
- </ItemGroup>
-
- <Target Name="PostBuild" AfterTargets="PostBuildEvent">
- <Exec Command="start xcopy &quot;$(TargetDir)&quot; &quot;F:\Programming\Web Plugins\DevPlugins\$(TargetName)&quot; /E /Y /R" />
- </Target>
-
-</Project>