diff options
author | vnugent <public@vaughnnugent.com> | 2023-11-02 21:32:44 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-11-02 21:32:44 -0400 |
commit | 59599b0f3e57d1881639d482bf1758c7f93d0dc2 (patch) | |
tree | da14ad0c450542e37e2f597db22337343c68e2dc /lib/Net.Http/src | |
parent | 9e3dd9be0f0ec7aaef1a719f09f96425e66369df (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.cs | 19 | ||||
-rw-r--r-- | lib/Net.Http/src/Core/HttpContext.cs | 2 | ||||
-rw-r--r-- | lib/Net.Http/src/Core/Request/HttpRequestExtensions.cs | 28 | ||||
-rw-r--r-- | lib/Net.Http/src/IHttpMemoryPool.cs | 2 |
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; } } |