aboutsummaryrefslogtreecommitdiff
path: root/lib/Net.Http
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Net.Http')
-rw-r--r--lib/Net.Http/src/Core/ConnectionInfo.cs3
-rw-r--r--lib/Net.Http/src/Core/HttpCookie.cs50
-rw-r--r--lib/Net.Http/src/Core/Response/HttpResponse.cs11
-rw-r--r--lib/Net.Http/src/Helpers/HttpHelpers.cs5
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;