From 107b058a38d6785b350826c6fb01bb64997c630a Mon Sep 17 00:00:00 2001 From: vnugent Date: Sat, 20 Apr 2024 12:23:40 -0400 Subject: Squashed commit of the following: commit 8c4a45e384accf92b1b6d748530e8d46f7de40d6 Author: vnugent Date: Sat Apr 20 11:10:30 2024 -0400 refactor: Overhaul C libraries and fix builds commit 42ff77080d10b0fc9fecbbc46141e8e23a1d066a Author: vnugent Date: Sat Apr 20 00:45:57 2024 -0400 fix!: Middlware array, multiple cookie set, and cookie check commit 97e82b9d66f387f9e6d21d88ddc7a8ab8693149c Merge: 4ca5791 e07537a Author: vnugent Date: Tue Apr 2 13:34:22 2024 -0400 Merge branch 'main' into develop commit 4ca5791ed67b9834bdbd010206b30373e4705e9b Author: vnugent Date: Tue Apr 2 13:32:12 2024 -0400 fix: Missed ! on null pointer check commit 9b4036377c52200c6488c98180d69a0e63321f97 Author: vnugent Date: Tue Apr 2 13:22:29 2024 -0400 fix: Fix _In_ macro for compression public api commit 53a7b4b5c5b67b4a4e06e1d9098cac4bcd6afd7c Merge: 448a93b 21130c8 Author: vnugent Date: Sun Mar 31 17:01:15 2024 -0400 Merge branch 'main' into develop commit 448a93bb1d18d032087afe2476ffccb98634a54c Author: vnugent Date: Sun Mar 31 16:56:51 2024 -0400 ci: fix third-party dir cleanup commit 9afed1427472da1ea13079f98dbe27339e55ee7d Author: vnugent Date: Sun Mar 31 16:43:15 2024 -0400 perf: Deprecate unsafememoryhandle span extensions commit 3ff90da4f02af47ea6d233fdd4445337ebe36452 Author: vnugent Date: Sat Mar 30 21:36:18 2024 -0400 refactor: Updates, advanced tracing, http optimizations commit 8d6b79b5ae309b36f265ba81529bcef8bfcd7414 Merge: 6c1667b 5585915 Author: vnugent Date: Sun Mar 24 21:01:31 2024 -0400 Merge branch 'main' into develop commit 6c1667be23597513537f8190e2f55d65eb9b7c7a Author: vnugent Date: Fri Mar 22 12:01:53 2024 -0400 refactor: Overhauled native library loading and lazy init commit ebf688f2f974295beabf7b5def7e6f6f150551d0 Author: vnugent Date: Wed Mar 20 22:16:17 2024 -0400 refactor: Update compression header files and macros + Ci build commit 9c7b564911080ccd5cbbb9851a0757b05e1e9047 Author: vnugent Date: Tue Mar 19 21:54:49 2024 -0400 refactor: JWK overhaul & add length getter to FileUpload commit 6d8c3444e09561e5957491b3cc1ae858e0abdd14 Author: vnugent Date: Mon Mar 18 16:13:20 2024 -0400 feat: Add FNV1a software checksum and basic correction tests commit 00d182088cecefc08ca80b1faee9bed3f215f40b Author: vnugent Date: Fri Mar 15 01:05:27 2024 -0400 chore: #6 Use utils filewatcher instead of built-in commit d513c10d9895c6693519ef1d459c6a5a76929436 Author: vnugent Date: Sun Mar 10 21:58:14 2024 -0400 source tree project location updated --- lib/Net.Http/src/Core/ConnectionInfo.cs | 3 +- lib/Net.Http/src/Core/HttpCookie.cs | 50 ++++++++++++++------------ lib/Net.Http/src/Core/Response/HttpResponse.cs | 11 +++--- lib/Net.Http/src/Helpers/HttpHelpers.cs | 5 ++- 4 files changed, 40 insertions(+), 29 deletions(-) (limited to 'lib/Net.Http') diff --git a/lib/Net.Http/src/Core/ConnectionInfo.cs b/lib/Net.Http/src/Core/ConnectionInfo.cs index 3af2b44..bcc5fe7 100644 --- a/lib/Net.Http/src/Core/ConnectionInfo.cs +++ b/lib/Net.Http/src/Core/ConnectionInfo.cs @@ -110,8 +110,9 @@ namespace VNLib.Net.Http Secure = secure | CrossOrigin, HttpOnly = httpOnly }; + //Set the cookie - Context.Response.AddCookie(cookie); + Context.Response.AddCookie(in cookie); } internal ConnectionInfo(HttpContext ctx) diff --git a/lib/Net.Http/src/Core/HttpCookie.cs b/lib/Net.Http/src/Core/HttpCookie.cs index e19aaec..b805e3e 100644 --- a/lib/Net.Http/src/Core/HttpCookie.cs +++ b/lib/Net.Http/src/Core/HttpCookie.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Net.Http @@ -30,44 +30,43 @@ using VNLib.Utils.Extensions; namespace VNLib.Net.Http.Core { - internal sealed class HttpCookie : IStringSerializeable, IEquatable + internal readonly struct HttpCookie(string name) : IStringSerializeable, IEquatable { - public string Name { get; } - public string? Value { get; init; } - public string? Domain { get; init; } - public string? Path { get; init; } - public TimeSpan MaxAge { get; init; } - public CookieSameSite SameSite { get; init; } - public bool Secure { get; init; } - public bool HttpOnly { get; init; } - public bool IsSession { get; init; } - - public HttpCookie(string name) => Name = name; - - public string Compile() - { - throw new NotImplementedException(); - } + public readonly string Name { get; } = name; + public readonly string? Value { get; init; } + public readonly string? Domain { get; init; } + public readonly string? Path { get; init; } + public readonly TimeSpan MaxAge { get; init; } + public readonly CookieSameSite SameSite { get; init; } + public readonly bool Secure { get; init; } + public readonly bool HttpOnly { get; init; } + public readonly bool IsSession { get; init; } + + public readonly string Compile() => throw new NotImplementedException(); - public void Compile(ref ForwardOnlyWriter writer) + public readonly void Compile(ref ForwardOnlyWriter writer) { //set the name of the cookie writer.Append(Name); writer.Append('='); + //set name writer.Append(Value); + //Only set the max age parameter if the cookie is not a session cookie if (!IsSession) { writer.Append("; Max-Age="); writer.Append((int)MaxAge.TotalSeconds); } + //Make sure domain is set if (!string.IsNullOrWhiteSpace(Domain)) { writer.Append("; Domain="); writer.Append(Domain); } + //Check and set path if (!string.IsNullOrWhiteSpace(Path)) { @@ -75,7 +74,9 @@ namespace VNLib.Net.Http.Core writer.Append("; Path="); writer.Append(Path); } + writer.Append("; SameSite="); + //Set the samesite flag based on the enum value switch (SameSite) { @@ -90,28 +91,31 @@ namespace VNLib.Net.Http.Core writer.Append("Lax"); break; } + //Set httponly flag if (HttpOnly) { writer.Append("; HttpOnly"); } + //Set secure flag if (Secure) { writer.Append("; Secure"); } } - public ERRNO Compile(Span buffer) + + public readonly ERRNO Compile(Span buffer) { ForwardOnlyWriter writer = new(buffer); Compile(ref writer); return writer.Written; } - public override int GetHashCode() => Name.GetHashCode(); + public readonly override int GetHashCode() => string.GetHashCode(Name, StringComparison.OrdinalIgnoreCase); - public override bool Equals(object? obj) => obj is HttpCookie other && Equals(other); + public readonly override bool Equals(object? obj) => obj is HttpCookie other && Equals(other); - public bool Equals(HttpCookie? other) => other != null && Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase); + public readonly bool Equals(HttpCookie other) => Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase); } } \ No newline at end of file diff --git a/lib/Net.Http/src/Core/Response/HttpResponse.cs b/lib/Net.Http/src/Core/Response/HttpResponse.cs index 06f114c..1340dac 100644 --- a/lib/Net.Http/src/Core/Response/HttpResponse.cs +++ b/lib/Net.Http/src/Core/Response/HttpResponse.cs @@ -44,7 +44,9 @@ namespace VNLib.Net.Http.Core.Response , IStringSerializeable #endif { - private readonly HashSet Cookies = []; + const int DefaultCookieCapacity = 2; + + private readonly Dictionary Cookies = new(DefaultCookieCapacity, StringComparer.OrdinalIgnoreCase); private readonly DirectStream ReusableDirectStream = new(); private readonly ChunkedStream ReusableChunkedStream = new(manager.ChunkAccumulatorBuffer, ContextInfo); private readonly HeaderDataAccumulator Writer = new(manager.ResponseHeaderBuffer, ContextInfo); @@ -86,7 +88,7 @@ namespace VNLib.Net.Http.Core.Response /// /// Cookie to add [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void AddCookie(HttpCookie cookie) => Cookies.Add(cookie); + internal void AddCookie(in HttpCookie cookie) => Cookies[cookie.Name] = cookie; /// /// Compiles and flushes all headers to the header accumulator ready for sending @@ -132,7 +134,7 @@ namespace VNLib.Net.Http.Core.Response //Write cookies if any are set if (Cookies.Count > 0) { - foreach (HttpCookie cookie in Cookies) + foreach (HttpCookie cookie in Cookies.Values) { writer.Append("Set-Cookie: "); @@ -298,6 +300,7 @@ namespace VNLib.Net.Http.Core.Response { ReusableChunkedStream.OnRelease(); ReusableDirectStream.OnRelease(); + Cookies.TrimExcess(DefaultCookieCapacity); } /// @@ -428,7 +431,7 @@ namespace VNLib.Net.Http.Core.Response } //Enumerate and write - foreach (HttpCookie cookie in Cookies) + foreach (HttpCookie cookie in Cookies.Values) { writer.Append("Set-Cookie: "); diff --git a/lib/Net.Http/src/Helpers/HttpHelpers.cs b/lib/Net.Http/src/Helpers/HttpHelpers.cs index 86511a5..86616f8 100644 --- a/lib/Net.Http/src/Helpers/HttpHelpers.cs +++ b/lib/Net.Http/src/Helpers/HttpHelpers.cs @@ -172,7 +172,7 @@ namespace VNLib.Net.Http return ComputeCodeHashLookup( Enum.GetValues() //Exclude the not supported method - .Except(new HttpMethod[] { HttpMethod.None }) + .Except([ HttpMethod.None ]) .Select(m => KeyValuePair.Create(m.ToString(), m)) ).ToFrozenDictionary(); } @@ -284,6 +284,9 @@ namespace VNLib.Net.Http /// True if first 2 bytes of each address match (Big Endian) public static bool IsLocalSubnet(this IPAddress first, IPAddress other) { + ArgumentNullException.ThrowIfNull(first); + ArgumentNullException.ThrowIfNull(other); + if(first.AddressFamily != other.AddressFamily) { return false; -- cgit