diff options
Diffstat (limited to 'lib/Net.Http')
-rw-r--r-- | lib/Net.Http/src/Core/ConnectionInfo.cs | 3 | ||||
-rw-r--r-- | lib/Net.Http/src/Core/HttpCookie.cs | 50 | ||||
-rw-r--r-- | lib/Net.Http/src/Core/Response/HttpResponse.cs | 11 | ||||
-rw-r--r-- | lib/Net.Http/src/Helpers/HttpHelpers.cs | 5 |
4 files changed, 40 insertions, 29 deletions
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<HttpCookie> + internal readonly struct HttpCookie(string name) : IStringSerializeable, IEquatable<HttpCookie> { - 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<char> writer) + public readonly void Compile(ref ForwardOnlyWriter<char> 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<char> buffer) + + public readonly ERRNO Compile(Span<char> buffer) { ForwardOnlyWriter<char> 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<HttpCookie> Cookies = []; + const int DefaultCookieCapacity = 2; + + private readonly Dictionary<string, HttpCookie> 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 /// </summary> /// <param name="cookie">Cookie to add</param> [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void AddCookie(HttpCookie cookie) => Cookies.Add(cookie); + internal void AddCookie(in HttpCookie cookie) => Cookies[cookie.Name] = cookie; /// <summary> /// 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); } ///<inheritdoc/> @@ -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<HttpMethod>() //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 /// <returns>True if first 2 bytes of each address match (Big Endian)</returns> public static bool IsLocalSubnet(this IPAddress first, IPAddress other) { + ArgumentNullException.ThrowIfNull(first); + ArgumentNullException.ThrowIfNull(other); + if(first.AddressFamily != other.AddressFamily) { return false; |