aboutsummaryrefslogtreecommitdiff
path: root/lib/Net.Http/src
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-11-02 21:32:44 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2023-11-02 21:32:44 -0400
commit59599b0f3e57d1881639d482bf1758c7f93d0dc2 (patch)
treeda14ad0c450542e37e2f597db22337343c68e2dc /lib/Net.Http/src
parent9e3dd9be0f0ec7aaef1a719f09f96425e66369df (diff)
Unify memory api and add more tests
Diffstat (limited to 'lib/Net.Http/src')
-rw-r--r--lib/Net.Http/src/Core/Buffering/HttpBufferElement.cs19
-rw-r--r--lib/Net.Http/src/Core/HttpContext.cs2
-rw-r--r--lib/Net.Http/src/Core/Request/HttpRequestExtensions.cs28
-rw-r--r--lib/Net.Http/src/IHttpMemoryPool.cs2
4 files changed, 24 insertions, 27 deletions
diff --git a/lib/Net.Http/src/Core/Buffering/HttpBufferElement.cs b/lib/Net.Http/src/Core/Buffering/HttpBufferElement.cs
index b23bc8f..bffc1c5 100644
--- a/lib/Net.Http/src/Core/Buffering/HttpBufferElement.cs
+++ b/lib/Net.Http/src/Core/Buffering/HttpBufferElement.cs
@@ -35,9 +35,15 @@ namespace VNLib.Net.Http.Core.Buffering
* as we are pinning the block. The block is pinned once for the lifetime
* of the connection, so we have access to the raw memory for faster
* span access.
+ *
+ * It is suggested to use an Unmanaged memory pool for zero-cost memory
+ * pinning
*/
internal abstract class HttpBufferElement : IHttpBuffer
{
+ private MemoryHandle Pinned;
+ private int _size;
+ protected Memory<byte> Buffer;
public virtual void FreeBuffer()
{
@@ -45,7 +51,7 @@ namespace VNLib.Net.Http.Core.Buffering
Pinned.Dispose();
Pinned = default;
Buffer = default;
- Size = 0;
+ _size = 0;
}
public virtual void SetBuffer(Memory<byte> buffer)
@@ -55,18 +61,15 @@ namespace VNLib.Net.Http.Core.Buffering
//Pin buffer and hold handle
Pinned = buffer.Pin();
//Set size to length of buffer
- Size = buffer.Length;
+ _size = buffer.Length;
}
///<inheritdoc/>
- public int Size { get; private set; }
-
- private MemoryHandle Pinned;
- protected Memory<byte> Buffer;
+ public int Size => _size;
///<inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public virtual Span<byte> GetBinSpan() => MemoryUtil.GetSpan<byte>(ref Pinned, Size);
+ public virtual Span<byte> GetBinSpan() => MemoryUtil.GetSpan<byte>(ref Pinned, _size);
///<inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -75,7 +78,7 @@ namespace VNLib.Net.Http.Core.Buffering
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected virtual Span<byte> GetBinSpan(int maxSize)
{
- return maxSize > Size ? throw new ArgumentOutOfRangeException(nameof(maxSize)) : MemoryUtil.GetSpan<byte>(ref Pinned, maxSize);
+ return maxSize > _size ? throw new ArgumentOutOfRangeException(nameof(maxSize)) : MemoryUtil.GetSpan<byte>(ref Pinned, maxSize);
}
}
}
diff --git a/lib/Net.Http/src/Core/HttpContext.cs b/lib/Net.Http/src/Core/HttpContext.cs
index f0cd3f8..feb3df5 100644
--- a/lib/Net.Http/src/Core/HttpContext.cs
+++ b/lib/Net.Http/src/Core/HttpContext.cs
@@ -143,7 +143,7 @@ namespace VNLib.Net.Http.Core
{
_ctx = ctx;
- //Alloc buffers
+ //Alloc buffers during context init incase exception occurs in user-code
Buffers.AllocateBuffer(ParentServer.Config.MemoryPool);
//Init new connection
diff --git a/lib/Net.Http/src/Core/Request/HttpRequestExtensions.cs b/lib/Net.Http/src/Core/Request/HttpRequestExtensions.cs
index dd21707..8fef8dd 100644
--- a/lib/Net.Http/src/Core/Request/HttpRequestExtensions.cs
+++ b/lib/Net.Http/src/Core/Request/HttpRequestExtensions.cs
@@ -157,6 +157,12 @@ namespace VNLib.Net.Http.Core
//Gets the max form data buffer size to help calculate the initial char buffer size
int maxBufferSize = context.ParentServer.Config.BufferConfig.FormDataBufferSize;
+ //Calculate a largest available buffer to read the entire stream or up to the maximum buffer size
+ int bufferSize = (int)Math.Min(request.InputStream.Length, maxBufferSize);
+
+ //Get the form data buffer (should be cost free)
+ Memory<byte> formBuffer = context.Buffers.GetFormDataBuffer();
+
switch (request.ContentType)
{
//CT not supported, dont read it
@@ -164,14 +170,8 @@ namespace VNLib.Net.Http.Core
break;
case ContentType.UrlEncoded:
{
- //Calculate a largest available buffer to read the entire stream or up to the maximum buffer size
- int bufferSize = (int)Math.Min(request.InputStream.Length, maxBufferSize);
-
//Alloc the form data character buffer, this will need to grow if the form data is larger than the buffer
- using MemoryHandle<char> urlbody = pool.AllocFormDataBuffer<char>(bufferSize);
-
- //Get a buffer for the form data
- Memory<byte> formBuffer = context.Buffers.GetFormDataBuffer();
+ using IResizeableMemoryHandle<char> urlbody = pool.AllocFormDataBuffer<char>(bufferSize);
//Load char buffer from stream
int chars = await BufferInputStream(request.InputStream, urlbody, formBuffer, info.Encoding);
@@ -190,14 +190,8 @@ namespace VNLib.Net.Http.Core
break;
}
- //Calculate a largest available buffer to read the entire stream or up to the maximum buffer size
- int bufferSize = (int)Math.Min(request.InputStream.Length, maxBufferSize);
-
//Alloc the form data buffer
- using MemoryHandle<char> formBody = pool.AllocFormDataBuffer<char>(bufferSize);
-
- //Get a buffer for the form data
- Memory<byte> formBuffer = context.Buffers.GetFormDataBuffer();
+ using IResizeableMemoryHandle<char> formBody = pool.AllocFormDataBuffer<char>(bufferSize);
//Load char buffer from stream
int chars = await BufferInputStream(request.InputStream, formBody, formBuffer, info.Encoding);
@@ -223,7 +217,7 @@ namespace VNLib.Net.Http.Core
* We assume the parsing method checked the size of the input stream so we can assume its safe to read
* all of it into memory.
*/
- private static async ValueTask<int> BufferInputStream(Stream stream, MemoryHandle<char> charBuffer, Memory<byte> binBuffer, Encoding encoding)
+ private static async ValueTask<int> BufferInputStream(Stream stream, IResizeableMemoryHandle<char> charBuffer, Memory<byte> binBuffer, Encoding encoding)
{
int length = 0;
do
@@ -361,11 +355,11 @@ namespace VNLib.Net.Http.Core
int bytes = info.Encoding.GetByteCount(data);
//get a buffer from the HTTP heap
- MemoryHandle<byte> buffHandle = pool.AllocFormDataBuffer<byte>(bytes);
+ IResizeableMemoryHandle<byte> buffHandle = pool.AllocFormDataBuffer<byte>(bytes);
try
{
//Convert back to binary
- bytes = info.Encoding.GetBytes(data, buffHandle);
+ bytes = info.Encoding.GetBytes(data, buffHandle.Span);
//Create a new memory stream encapsulating the file data
VnMemoryStream vms = VnMemoryStream.FromHandle(buffHandle, true, bytes, true);
diff --git a/lib/Net.Http/src/IHttpMemoryPool.cs b/lib/Net.Http/src/IHttpMemoryPool.cs
index f0a548e..d58ac5f 100644
--- a/lib/Net.Http/src/IHttpMemoryPool.cs
+++ b/lib/Net.Http/src/IHttpMemoryPool.cs
@@ -47,6 +47,6 @@ namespace VNLib.Net.Http
/// <typeparam name="T"></typeparam>
/// <param name="initialSize">The initial size of the buffer to allocate, which may be expanded as needed</param>
/// <returns>The allocated block of memory</returns>
- MemoryHandle<T> AllocFormDataBuffer<T>(int initialSize) where T: unmanaged;
+ IResizeableMemoryHandle<T> AllocFormDataBuffer<T>(int initialSize) where T: unmanaged;
}
}