From b4b506a4b6c7c1e90b5b0980e4cfe0460e7546a2 Mon Sep 17 00:00:00 2001 From: vnugent Date: Sat, 8 Jun 2024 21:54:52 -0400 Subject: some minor touchups --- .../Core/Buffering/ContextLockedBufferManager.cs | 52 +++++++--------------- .../src/Core/Buffering/SplitHttpBufferElement.cs | 8 ++-- lib/Net.Http/src/Core/HttpContext.cs | 9 ++-- lib/Utils/src/ArgumentList.cs | 26 ++++++++--- lib/Utils/src/IO/ArrayPoolStreamBuffer.cs | 26 +++++------ lib/Utils/src/IO/VnStreamWriter.cs | 36 ++++++--------- 6 files changed, 65 insertions(+), 92 deletions(-) (limited to 'lib') diff --git a/lib/Net.Http/src/Core/Buffering/ContextLockedBufferManager.cs b/lib/Net.Http/src/Core/Buffering/ContextLockedBufferManager.cs index 90bdd8c..d8def92 100644 --- a/lib/Net.Http/src/Core/Buffering/ContextLockedBufferManager.cs +++ b/lib/Net.Http/src/Core/Buffering/ContextLockedBufferManager.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Net.Http @@ -33,40 +33,22 @@ using System; using System.Buffers; +using System.Diagnostics; using VNLib.Utils.Memory; namespace VNLib.Net.Http.Core.Buffering { - internal sealed class ContextLockedBufferManager : IHttpBufferManager + internal sealed class ContextLockedBufferManager(in HttpBufferConfig config, bool chunkingEnabled) : IHttpBufferManager { - private readonly HttpBufferConfig Config; - private readonly int TotalBufferSize; + private readonly HttpBufferConfig Config = config; + private readonly bool _chunkingEnabled = chunkingEnabled; + private readonly int TotalBufferSize = ComputeTotalBufferSize(in config, chunkingEnabled); - private readonly HeaderAccumulatorBuffer _requestHeaderBuffer; - private readonly HeaderAccumulatorBuffer _responseHeaderBuffer; - private readonly ChunkAccBuffer _chunkAccBuffer; - private readonly bool _chunkingEnabled; - - public ContextLockedBufferManager(in HttpBufferConfig config, bool chunkingEnabled) - { - Config = config; - _chunkingEnabled = chunkingEnabled; - - //Compute total buffer size from server config - TotalBufferSize = ComputeTotalBufferSize(in config, chunkingEnabled); - - /* - * Individual instances of the header accumulator buffer are required - * because the user controls the size of the binary buffer for responses - * and requests. The buffer segment is shared between the two instances. - */ - _requestHeaderBuffer = new(config.RequestHeaderBufferSize); - _responseHeaderBuffer = new(config.ResponseHeaderBufferSize); - - _chunkAccBuffer = new(); - } + private readonly HeaderAccumulatorBuffer _requestHeaderBuffer = new(config.RequestHeaderBufferSize); + private readonly HeaderAccumulatorBuffer _responseHeaderBuffer = new(config.ResponseHeaderBufferSize); + private readonly ChunkAccBuffer _chunkAccBuffer = new(); private IMemoryOwner? _handle; private HttpBufferSegments _segments; @@ -76,6 +58,8 @@ namespace VNLib.Net.Http.Core.Buffering /// public void AllocateBuffer(IHttpMemoryPool allocator) { + Debug.Assert(_handle == null, "Memory Leak: new http buffer alloacted when an existing buffer was not freed."); + //Alloc a single buffer for the entire context _handle = allocator.AllocateBufferForContext(TotalBufferSize); @@ -85,11 +69,9 @@ namespace VNLib.Net.Http.Core.Buffering //Header parse buffer is a special case as it will be double the size due to the char buffer int headerParseBufferSize = GetMaxHeaderBufferSize(in Config); - - //Response/form data buffer + int responseAndFormDataSize = ComputeResponseAndFormDataBuffer(in Config); - - //Slice and store the buffer segments + _segments = new() { //Shared header buffer @@ -238,11 +220,9 @@ namespace VNLib.Net.Http.Core.Buffering } - private sealed class HeaderAccumulatorBuffer: SplitHttpBufferElement, IResponseHeaderAccBuffer, IHttpHeaderParseBuffer - { - public HeaderAccumulatorBuffer(int binSize):base(binSize) - { } - } + private sealed class HeaderAccumulatorBuffer(int binSize) : + SplitHttpBufferElement(binSize), IResponseHeaderAccBuffer, IHttpHeaderParseBuffer + { } private sealed class ChunkAccBuffer : HttpBufferElement, IChunkAccumulatorBuffer { } diff --git a/lib/Net.Http/src/Core/Buffering/SplitHttpBufferElement.cs b/lib/Net.Http/src/Core/Buffering/SplitHttpBufferElement.cs index b6d0d39..19a463c 100644 --- a/lib/Net.Http/src/Core/Buffering/SplitHttpBufferElement.cs +++ b/lib/Net.Http/src/Core/Buffering/SplitHttpBufferElement.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Net.Http @@ -30,12 +30,10 @@ using VNLib.Utils.Memory; namespace VNLib.Net.Http.Core.Buffering { - internal abstract class SplitHttpBufferElement : HttpBufferElement, ISplitHttpBuffer + internal abstract class SplitHttpBufferElement(int binSize) : HttpBufferElement, ISplitHttpBuffer { /// - public int BinSize { get; } - - internal SplitHttpBufferElement(int binSize) => BinSize = binSize; + public int BinSize { get; } = binSize; /// public Span GetCharSpan() diff --git a/lib/Net.Http/src/Core/HttpContext.cs b/lib/Net.Http/src/Core/HttpContext.cs index f742e97..dc857b8 100644 --- a/lib/Net.Http/src/Core/HttpContext.cs +++ b/lib/Net.Http/src/Core/HttpContext.cs @@ -106,14 +106,11 @@ namespace VNLib.Net.Http.Core //Init buffer manager, if compression is supported, we need to alloc a buffer for the compressor Buffers = new(server.Config.BufferConfig, _compressor != null); - - //Create new request + Request = new (this, server.Config.MaxUploadsPerRequest); - - //create a new response object + Response = new (this, Buffers); - - //Init response writer + ResponseBody = new ResponseWriter(); } diff --git a/lib/Utils/src/ArgumentList.cs b/lib/Utils/src/ArgumentList.cs index c02ebee..7226b27 100644 --- a/lib/Utils/src/ArgumentList.cs +++ b/lib/Utils/src/ArgumentList.cs @@ -41,18 +41,16 @@ namespace VNLib.Utils /// /// The array of arguments to clone /// - public ArgumentList(string[] args) - { - ArgumentNullException.ThrowIfNull(args); - _args = args.ToList(); - } + [Obsolete("Deprecated in preference to ctor(IEnumerable)")] + public ArgumentList(string[] args) : this(args as IEnumerable) + { } /// /// Initalizes the argument parser by copying the given argument list /// /// The argument list to clone /// - public ArgumentList(IReadOnlyList args) + public ArgumentList(IEnumerable args) { ArgumentNullException.ThrowIfNull(args); _args = args.ToList(); @@ -102,5 +100,21 @@ namespace VNLib.Utils /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + /// Captures the command line arguments from the currently executing process + /// and returns them as an ArgumentList + /// + /// The containing the current process's argument list + public static ArgumentList CaptureCurrentArgs() + { + /* + * Capture the current command line arguments and + * pop the first argument which is always the program + * name + */ + string[] strings = Environment.GetCommandLineArgs(); + return new ArgumentList(strings.Skip(1)); + } } } \ No newline at end of file diff --git a/lib/Utils/src/IO/ArrayPoolStreamBuffer.cs b/lib/Utils/src/IO/ArrayPoolStreamBuffer.cs index b62412f..a943a5b 100644 --- a/lib/Utils/src/IO/ArrayPoolStreamBuffer.cs +++ b/lib/Utils/src/IO/ArrayPoolStreamBuffer.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Utils @@ -28,7 +28,13 @@ using System.Buffers; namespace VNLib.Utils.IO { - internal class ArrayPoolStreamBuffer : ISlindingWindowBuffer + /// + /// Creates a new from the + /// given array instance and it came from. + /// + /// The rented array to use + /// The pool to return the array to when completed + internal class ArrayPoolStreamBuffer(T[] array, ArrayPool pool) : ISlindingWindowBuffer { /// /// The shared instance to allocate buffers @@ -36,20 +42,8 @@ namespace VNLib.Utils.IO /// public static IStreamBufferFactory Shared { get; } = new DefaultFactory(); - private readonly ArrayPool _pool; - private T[] _buffer; - - /// - /// Creates a new from the - /// given array instance and it came from. - /// - /// The rented array to use - /// The pool to return the array to when completed - public ArrayPoolStreamBuffer(T[] array, ArrayPool pool) - { - _pool = pool; - _buffer = array; - } + private readonly ArrayPool _pool = pool; + private T[] _buffer = array; /// public int WindowStartPos { get; set; } diff --git a/lib/Utils/src/IO/VnStreamWriter.cs b/lib/Utils/src/IO/VnStreamWriter.cs index ddebc07..7d43f48 100644 --- a/lib/Utils/src/IO/VnStreamWriter.cs +++ b/lib/Utils/src/IO/VnStreamWriter.cs @@ -41,21 +41,29 @@ namespace VNLib.Utils.IO /// Provides a memory optimized implementation. Optimized for writing /// to network streams /// - public class VnStreamWriter : TextWriter + /// + /// Creates a new that writes encoded data to the base stream + /// and uses the specified buffer. + /// + /// The underlying stream to write data to + /// The to use when writing to the stream + /// The internal to use + /// + public class VnStreamWriter(Stream baseStream, Encoding encoding, ISlindingWindowBuffer buffer) : TextWriter { - private readonly Encoder Enc; + private readonly Encoder Enc = encoding.GetEncoder(); - private readonly ISlindingWindowBuffer _buffer; + private readonly ISlindingWindowBuffer _buffer = buffer ?? throw new ArgumentNullException(nameof(buffer)); private bool closed; /// /// Gets the underlying stream that interfaces with the backing store /// - public virtual Stream BaseStream { get; } + public virtual Stream BaseStream { get; } = baseStream ?? throw new ArgumentNullException(nameof(buffer)); /// - public override Encoding Encoding { get; } + public override Encoding Encoding { get; } = encoding ?? throw new ArgumentNullException(nameof(encoding)); /// /// Line termination to use when writing lines to the output @@ -97,24 +105,6 @@ namespace VNLib.Utils.IO { } - /// - /// Creates a new that writes encoded data to the base stream - /// and uses the specified buffer. - /// - /// The underlying stream to write data to - /// The to use when writing to the stream - /// The internal to use - /// - public VnStreamWriter(Stream baseStream, Encoding encoding, ISlindingWindowBuffer buffer) - { - BaseStream = baseStream ?? throw new ArgumentNullException(nameof(buffer)); - Encoding = encoding ?? throw new ArgumentNullException(nameof(encoding)); - _buffer = buffer ?? throw new ArgumentNullException(nameof(buffer)); - - //Get an encoder - Enc = encoding.GetEncoder(); - } - /// public void Write(byte value) { -- cgit