Skip to content

Commit

Permalink
Refactor code and use some new C# 12 stuffs :)
Browse files Browse the repository at this point in the history
  • Loading branch information
daohainam committed Dec 7, 2023
1 parent 989f769 commit ba1af65
Show file tree
Hide file tree
Showing 104 changed files with 286 additions and 746 deletions.
9 changes: 1 addition & 8 deletions Middleware/Authentication/AuthenticationMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,8 @@

namespace MiniWebServer.Authentication
{
public class AuthenticationMiddleware : IMiddleware
public class AuthenticationMiddleware(AuthenticationOptions options) : IMiddleware
{
private readonly AuthenticationOptions options;

public AuthenticationMiddleware(AuthenticationOptions options)
{
this.options = options ?? new();
}

public async Task InvokeAsync(IMiniAppRequestContext context, ICallable next, CancellationToken cancellationToken = default)
{
var authenticationServices = context.Services.GetServices<IAuthenticationService>();
Expand Down
2 changes: 1 addition & 1 deletion Middleware/Authentication/CookieAuthenticationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public Task SignOutAsync(IMiniAppRequestContext context)
return Task.CompletedTask;
}

protected Task<bool> IsValidAuthenticationCookieAsync(string cookieValue)
protected static Task<bool> IsValidAuthenticationCookieAsync(string cookieValue)
{
// todo: validate authentication cookie
return Task.FromResult(false);
Expand Down
9 changes: 2 additions & 7 deletions Middleware/Authentication/JwtAuthenticationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@

namespace MiniWebServer.Authentication
{
public class JwtAuthenticationOptions
public class JwtAuthenticationOptions(TokenValidationParameters tokenValidationParameters)
{
public JwtAuthenticationOptions(TokenValidationParameters tokenValidationParameters)
{
TokenValidationParameters = tokenValidationParameters ?? throw new ArgumentNullException(nameof(tokenValidationParameters));
}

public TokenValidationParameters TokenValidationParameters { get; }
public TokenValidationParameters TokenValidationParameters { get; } = tokenValidationParameters ?? throw new ArgumentNullException(nameof(tokenValidationParameters));
}
}
2 changes: 1 addition & 1 deletion Middleware/Authentication/JwtAuthenticationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public async Task<AuthenticationResult> AuthenticateAsync(IMiniAppRequestContext
}
}

context.User = new GenericPrincipal(result.ClaimsIdentity, roles.ToArray());
context.User = new GenericPrincipal(result.ClaimsIdentity, [.. roles]);
//context.User = new GenericPrincipal(result.ClaimsIdentity, Array.Empty<string>());

return new AuthenticationResult(true, context.User);
Expand Down
11 changes: 2 additions & 9 deletions Middleware/Authorization/AuthorizationMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,9 @@

namespace MiniWebServer.Authorization
{
public class AuthorizationMiddleware : IMiddleware
public class AuthorizationMiddleware(AuthorizationOptions options, IRouteMatcher routeMatcher) : IMiddleware
{
private readonly AuthorizationOptions options;
private readonly IRouteMatcher routeMatcher;

public AuthorizationMiddleware(AuthorizationOptions options, IRouteMatcher routeMatcher)
{
this.options = options ?? new();
this.routeMatcher = routeMatcher;
}
private readonly AuthorizationOptions options = options ?? new();

public async Task InvokeAsync(IMiniAppRequestContext context, ICallable next, CancellationToken cancellationToken = default)
{
Expand Down
4 changes: 2 additions & 2 deletions Middleware/Authorization/AuthorizationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ namespace MiniWebServer.Authorization
{
public class AuthorizationOptions
{
private readonly Dictionary<string, IPolicy> policies = new();
private readonly Dictionary<string, string[]> routes = new();
private readonly Dictionary<string, IPolicy> policies = [];
private readonly Dictionary<string, string[]> routes = [];

public IDictionary<string, IPolicy> Policies => policies;
public IDictionary<string, string[]> Routes => routes;
Expand Down
8 changes: 4 additions & 4 deletions Middleware/Authorization/RouteDictionaryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ public static class RouteDictionaryExtensions
{
public static void Add(this IDictionary<string, string[]> dictionary, string key, string value, params string[]? values)
{
List<string> strings = new()
{
List<string> strings =
[
value
};
];

if (values != null)
{
Expand All @@ -16,7 +16,7 @@ public static void Add(this IDictionary<string, string[]> dictionary, string key
strings.Add(v);
}
}
dictionary[key] = strings.ToArray();
dictionary[key] = [.. strings];
}
}
}
9 changes: 1 addition & 8 deletions Middleware/HstsMiddleware/HstsMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,8 @@

namespace MiniWebServer.HstsMiddleware
{
public class HstsMiddleware : IMiddleware
public class HstsMiddleware(HstsOptions options) : IMiddleware
{
private readonly HstsOptions options;

public HstsMiddleware(HstsOptions options)
{
this.options = options;
}

public async Task InvokeAsync(IMiniAppRequestContext context, ICallable next, CancellationToken cancellationToken = default)
{
StringBuilder sb = new();
Expand Down
11 changes: 2 additions & 9 deletions Middleware/HttpsRedirection/HttpsRedirectionMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,9 @@

namespace MiniWebServer.HttpsRedirection
{
public class HttpsRedirectionMiddleware : IMiddleware
public class HttpsRedirectionMiddleware(HttpsRedirectionOptions options, ILogger<HttpsRedirectionMiddleware>? logger) : IMiddleware
{
private readonly HttpsRedirectionOptions options;
private readonly ILogger<HttpsRedirectionMiddleware> logger;

public HttpsRedirectionMiddleware(HttpsRedirectionOptions options, ILogger<HttpsRedirectionMiddleware>? logger)
{
this.options = options;
this.logger = logger ?? NullLogger<HttpsRedirectionMiddleware>.Instance;
}
private readonly ILogger<HttpsRedirectionMiddleware> logger = logger ?? NullLogger<HttpsRedirectionMiddleware>.Instance;

public async Task InvokeAsync(IMiniAppRequestContext context, ICallable next, CancellationToken cancellationToken = default)
{
Expand Down
15 changes: 4 additions & 11 deletions Middleware/Mvc/LocalAction/LocalAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,10 @@

namespace MiniWebServer.Mvc.LocalAction
{
internal class LocalAction
internal class LocalAction(string route, ActionInfo actionInfo, ActionMethods actionMethods = ActionMethods.All)
{
public LocalAction(string route, ActionInfo actionInfo, ActionMethods actionMethods = ActionMethods.All)
{
Route = route ?? throw new ArgumentNullException(nameof(route));
ActionInfo = actionInfo ?? throw new ArgumentNullException(nameof(actionInfo));
ActionMethods = actionMethods;
}

public string Route { get; }
public ActionInfo ActionInfo { get; }
public ActionMethods ActionMethods { get; }
public string Route { get; } = route ?? throw new ArgumentNullException(nameof(route));
public ActionInfo ActionInfo { get; } = actionInfo ?? throw new ArgumentNullException(nameof(actionInfo));
public ActionMethods ActionMethods { get; } = actionMethods;
}
}
11 changes: 3 additions & 8 deletions Middleware/Mvc/LocalAction/LocalActionFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,11 @@

namespace MiniWebServer.Mvc.LocalAction
{
internal class LocalActionFinder : IActionFinder
internal class LocalActionFinder(LocalActionRegistry registry, IRouteMatcher routeMatcher) : IActionFinder
{
private readonly LocalActionRegistry registry;
private readonly IRouteMatcher routeMatcher;
private readonly LocalActionRegistry registry = registry ?? throw new ArgumentNullException(nameof(registry));
private readonly IRouteMatcher routeMatcher = routeMatcher ?? throw new ArgumentNullException(nameof(routeMatcher));

public LocalActionFinder(LocalActionRegistry registry, IRouteMatcher routeMatcher)
{
this.registry = registry ?? throw new ArgumentNullException(nameof(registry));
this.routeMatcher = routeMatcher ?? throw new ArgumentNullException(nameof(routeMatcher));
}
public ActionInfo? Find(IMiniAppRequestContext context)
{
var key = registry.Actions.Keys.Where(k => routeMatcher.IsMatched(context.Request.Url, k)).FirstOrDefault();
Expand Down
11 changes: 1 addition & 10 deletions Middleware/Mvc/MultipleServiceProvider.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
namespace MiniWebServer.Mvc
{
internal class MultipleServiceProvider : IServiceProvider
internal class MultipleServiceProvider(IServiceProvider parent1, params IServiceProvider[] parents) : IServiceProvider
{
private readonly IServiceProvider parent1;
private readonly IServiceProvider[] parents;

public MultipleServiceProvider(IServiceProvider parent1, params IServiceProvider[] parents)
{
this.parent1 = parent1;
this.parents = parents;
}

public object? GetService(Type serviceType)
{
object? service = parent1.GetService(serviceType);
Expand Down
4 changes: 2 additions & 2 deletions Middleware/Mvc/MvcMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ private async Task<bool> CallActionMethodAsync(IServiceProvider localServiceProv
}
}

var actionResult = actionInfo.MethodInfo.Invoke(controller, actionParameterValues.ToArray());
var actionResult = actionInfo.MethodInfo.Invoke(controller, [.. actionParameterValues]);
if (actionResult != null)
{
// if this is an async function then we will call it asyncly
Expand Down Expand Up @@ -347,7 +347,7 @@ static public async Task<CreateParameterValueResult> TryCreateValueAsync(
{
// looking for a public static bool TryParse method
var tryParseMethod = parameterType.GetMethod("TryParse", BindingFlags.Public | BindingFlags.Static, null,
new Type[] { typeof(string), parameterType.MakeByRefType() },
[typeof(string), parameterType.MakeByRefType()],
null);
if (tryParseMethod != null && tryParseMethod.ReturnType == typeof(bool))
{
Expand Down
9 changes: 2 additions & 7 deletions Middleware/Mvc/MvcOptions.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
namespace MiniWebServer.Mvc
{
public class MvcOptions
public class MvcOptions(IActionFinder actionFinder)
{
public MvcOptions(IActionFinder actionFinder)
{
ActionFinder = actionFinder ?? throw new ArgumentNullException(nameof(actionFinder));
}

public IActionFinder ActionFinder { get; }
public IActionFinder ActionFinder { get; } = actionFinder ?? throw new ArgumentNullException(nameof(actionFinder));
}
}
23 changes: 7 additions & 16 deletions Middleware/OutputCaching/OutputCachePolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,14 @@

namespace MiniWebServer.OutputCaching
{
public class OutputCachePolicy : IOutputCachePolicy
public class OutputCachePolicy(Func<string, bool> pathMatching, IEnumerable<HttpMethod>? methods, IEnumerable<HttpResponseCodes>? httpResponseCodes = null, TimeSpan? expire = null) : IOutputCachePolicy
{
public OutputCachePolicy(Func<string, bool> pathMatching, IEnumerable<HttpMethod>? methods, IEnumerable<HttpResponseCodes>? httpResponseCodes = null, TimeSpan? expire = null)
{
PathMatching = pathMatching ?? throw new ArgumentNullException(nameof(pathMatching));
public IEnumerable<HttpMethod> Methods { get; set; } = methods ?? DefaultHttpMethods;
public Func<string, bool> PathMatching { get; set; } = pathMatching ?? throw new ArgumentNullException(nameof(pathMatching));
public IEnumerable<HttpResponseCodes> HttpResponseCodes { get; set; } = httpResponseCodes ?? DefaultHttpResponseCodes;
public TimeSpan? Expire { get; set; } = expire;

Methods = methods ?? DefaultHttpMethods;
HttpResponseCodes = httpResponseCodes ?? DefaultHttpResponseCodes;
Expire = expire;
}

public IEnumerable<HttpMethod> Methods { get; set; }
public Func<string, bool> PathMatching { get; set; }
public IEnumerable<HttpResponseCodes> HttpResponseCodes { get; set; }
public TimeSpan? Expire { get; set; }

private static readonly HttpResponseCodes[] DefaultHttpResponseCodes = { Abstractions.HttpResponseCodes.OK };
private static readonly HttpMethod[] DefaultHttpMethods = { HttpMethod.Head, HttpMethod.Get };
private static readonly HttpResponseCodes[] DefaultHttpResponseCodes = [Abstractions.HttpResponseCodes.OK];
private static readonly HttpMethod[] DefaultHttpMethods = [HttpMethod.Head, HttpMethod.Get];
}
}
8 changes: 4 additions & 4 deletions Middleware/OutputCaching/OutputCachePolicyBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ namespace MiniWebServer.OutputCaching
public class OutputCachePolicyBuilder : IOutputCachePolicyBuilder
{
private string? name;
private readonly List<HttpResponseCodes> httpResponseCodes = new();
private readonly List<Abstractions.Http.HttpMethod> methods = new();
private readonly List<HttpResponseCodes> httpResponseCodes = [];
private readonly List<Abstractions.Http.HttpMethod> methods = [];
private TimeSpan? expire;
private Func<string, bool>? pathMatching;

Expand Down Expand Up @@ -48,8 +48,8 @@ public IOutputCachePolicy Build()
{
var policy = new OutputCachePolicy(
pathMatching ?? (path => false),
methods.Any() ? methods : null, // null to use default values
httpResponseCodes.Any() ? httpResponseCodes : null,
methods.Count != 0 ? methods : null, // null to use default values
httpResponseCodes.Count != 0 ? httpResponseCodes : null,
expire
);

Expand Down
2 changes: 1 addition & 1 deletion Middleware/Session/DistributedCacheSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class DistributedCacheSession : ISession
{
private const string KeyPrefix = "_#M.S#_";

private readonly Dictionary<string, byte[]> localStore = new();
private readonly Dictionary<string, byte[]> localStore = [];
private SpinLock spinLock = new(); // do not make it readonly, or .NET will create a new shadow instance to keep it immutable
private readonly int waitTimeoutMs = 0;

Expand Down
2 changes: 1 addition & 1 deletion Middleware/Session/SessionMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public async Task InvokeAsync(IMiniAppRequestContext context, ICallable next, Ca
}
else
{
sessionId = null;
//sessionId = null;
}
}
else // session key not found, create one
Expand Down
9 changes: 2 additions & 7 deletions Middleware/Session/SessionOptions.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
namespace MiniWebServer.Session
{
public class SessionOptions
public class SessionOptions(string? sessionIdKey = default)
{
public const string DefaultSessionIdKey = ".miniWeb.SID";

public SessionOptions(string? sessionIdKey = default)
{
SessionIdKey = sessionIdKey ?? DefaultSessionIdKey;
}

public string SessionIdKey { get; } = DefaultSessionIdKey;
public string SessionIdKey { get; } = sessionIdKey ?? DefaultSessionIdKey;
}
}
9 changes: 2 additions & 7 deletions Middleware/StaticFiles/StaticFilesCacheOptions.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
namespace MiniWebServer.StaticFiles
{
public class StaticFilesCacheOptions
public class StaticFilesCacheOptions(long maxAge)
{
public StaticFilesCacheOptions(long maxAge)
{
MaxAge = maxAge;
}

public long MaxAge { get; }
public long MaxAge { get; } = maxAge;
}
}
6 changes: 3 additions & 3 deletions Middleware/StaticFiles/StaticFilesMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ public async Task InvokeAsync(IMiniAppRequestContext context, ICallable next, Ca

if (!url.Contains("..") && directoryInfo.Exists)
{
if (url.StartsWith("/"))
if (url.StartsWith('/'))
{
url = url[1..];
}
url = url.Replace('/', Path.DirectorySeparatorChar);

FileInfo? file = null;
if (string.IsNullOrEmpty(url) && options.DefaultDocuments.Any())
if (string.IsNullOrEmpty(url) && options.DefaultDocuments.Length != 0)
{
foreach (var document in options.DefaultDocuments)
{
Expand All @@ -60,7 +60,7 @@ public async Task InvokeAsync(IMiniAppRequestContext context, ICallable next, Ca
{
var dir = new DirectoryInfo(file.FullName);
file = null;
if (options.DefaultDocuments.Any() && dir.Exists)
if (options.DefaultDocuments.Length != 0 && dir.Exists)
{
foreach (var document in options.DefaultDocuments)
{
Expand Down
6 changes: 3 additions & 3 deletions Middleware/StaticFiles/StaticFilesOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public class StaticFilesOptions
public StaticFilesOptions(string? root = null, string[]? defaultDocuments = null, StaticFilesCacheOptions? cacheOptions = null, bool? useCompression = null, int? minimumFileSizeToCompress = null, int? compressionQuality = null, string[]? fileCompressionMimeTypes = null)
{
Root = root ?? "wwwroot";
DefaultDocuments = defaultDocuments ?? new string[] { "index.htm", "index.html" };
DefaultDocuments = defaultDocuments ?? ["index.htm", "index.html"];
CacheOptions = cacheOptions ?? new StaticFilesCacheOptions(0);
UseCompression = useCompression ?? true;
MinimumFileSizeToCompress = minimumFileSizeToCompress ?? 1024;
Expand All @@ -14,12 +14,12 @@ public StaticFilesOptions(string? root = null, string[]? defaultDocuments = null
{
throw new ArgumentOutOfRangeException(nameof(compressionQuality), "compressionQuality must be from 0 (no compression) to 11 (max compression)");
}
FileCompressionMimeTypes = fileCompressionMimeTypes ?? new string[] {
FileCompressionMimeTypes = fileCompressionMimeTypes ?? [
"text/plain",
"text/html",
"text/css",
"text/javascript"
};
];
}

public string Root { get; }
Expand Down
Loading

0 comments on commit ba1af65

Please sign in to comment.