aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Net.Compression/VNLib.Net.CompressionTests/VNLib.Net.CompressionTests.csproj2
-rw-r--r--lib/Net.Http/src/Core/Request/HttpInputStream.cs56
-rw-r--r--lib/Net.Http/src/Helpers/HttpHelpers.cs64
-rw-r--r--lib/Net.Http/src/Helpers/MimeLookups.cs13
4 files changed, 86 insertions, 49 deletions
diff --git a/lib/Net.Compression/VNLib.Net.CompressionTests/VNLib.Net.CompressionTests.csproj b/lib/Net.Compression/VNLib.Net.CompressionTests/VNLib.Net.CompressionTests.csproj
index 56c67ed..53a6155 100644
--- a/lib/Net.Compression/VNLib.Net.CompressionTests/VNLib.Net.CompressionTests.csproj
+++ b/lib/Net.Compression/VNLib.Net.CompressionTests/VNLib.Net.CompressionTests.csproj
@@ -8,7 +8,7 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
<PackageReference Include="coverlet.collector" Version="6.0.0">
diff --git a/lib/Net.Http/src/Core/Request/HttpInputStream.cs b/lib/Net.Http/src/Core/Request/HttpInputStream.cs
index 3f6b2a5..7c010a3 100644
--- a/lib/Net.Http/src/Core/Request/HttpInputStream.cs
+++ b/lib/Net.Http/src/Core/Request/HttpInputStream.cs
@@ -26,6 +26,7 @@ using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
+using System.Diagnostics;
using System.Runtime.CompilerServices;
using VNLib.Utils;
@@ -50,6 +51,7 @@ namespace VNLib.Net.Http.Core
public HttpInputStream(IHttpContextInformation contextInfo) => ContextInfo = contextInfo;
+ private long Remaining => Math.Max(ContentLength - _position, 0);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnComplete()
@@ -82,18 +84,53 @@ namespace VNLib.Net.Http.Core
return ref _initalData;
}
- public override void Close() => throw new NotSupportedException("The HTTP input stream should never be closed!");
- private long Remaining => Math.Max(ContentLength - _position, 0);
+ /// <summary>
+ /// Not a supported method. In debug mode will cause the application to crash with a
+ /// warning to determine the cause.
+ /// </summary>
+ public override void Close() => Debug.Fail("A attempt to close the HTTP input stream was made. The source should be determined.");
+
+ /// <summary>
+ /// Always returns true
+ /// </summary>
public override bool CanRead => true;
+
+ /// <summary>
+ /// Stream is not seekable, but is always true for
+ /// stream compatibility reasons
+ /// </summary>
public override bool CanSeek => true;
+
+ /// <summary>
+ /// Stream is never writable
+ /// </summary>
public override bool CanWrite => false;
+
+ /// <summary>
+ /// Gets the total size of the entity body (aka Content-Length)
+ /// </summary>
public override long Length => ContentLength;
+
+ /// <summary>
+ /// Gets the number of bytes currently read from the entity body, setting the
+ /// position is a NOOP
+ /// </summary>
public override long Position { get => _position; set { } }
+ /// <summary>
+ /// NOOP
+ /// </summary>
public override void Flush() { }
+ ///<inheritdoc/>
public override int Read(byte[] buffer, int offset, int count) => Read(buffer.AsSpan(offset, count));
+ /// <summary>
+ /// Reads as much entity body data as available into the specified buffer as possible
+ /// until the buffer is full or the amount of entity data is reached.
+ /// </summary>
+ /// <param name="buffer">The buffer to copy entity data to</param>
+ /// <returns>The number of bytes read from the transport</returns>
public override int Read(Span<byte> buffer)
{
//Calculate the amount of data that can be read into the buffer
@@ -135,6 +172,7 @@ namespace VNLib.Net.Http.Core
return writer.Written;
}
+
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask();
@@ -221,14 +259,18 @@ namespace VNLib.Net.Http.Core
} while (read != 0);
}
- public override long Seek(long offset, SeekOrigin origin)
- {
- //Ignore seek control
- return _position;
- }
+ /// <summary>
+ /// Seek is not a supported operation, a seek request is ignored and nothin happens
+ /// </summary>
+ /// <param name="offset"></param>
+ /// <param name="origin"></param>
+ /// <returns></returns>
+ public override long Seek(long offset, SeekOrigin origin) => _position;
+ ///<inheritdoc/>
public override void SetLength(long value) => throw new NotSupportedException();
+ ///<inheritdoc/>
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
}
} \ No newline at end of file
diff --git a/lib/Net.Http/src/Helpers/HttpHelpers.cs b/lib/Net.Http/src/Helpers/HttpHelpers.cs
index 198396f..a4486cd 100644
--- a/lib/Net.Http/src/Helpers/HttpHelpers.cs
+++ b/lib/Net.Http/src/Helpers/HttpHelpers.cs
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022 Vaughn Nugent
+* Copyright (c) 2023 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.Net.Http
@@ -25,6 +25,7 @@
using System;
using System.IO;
using System.Net;
+using System.Linq;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Text.RegularExpressions;
@@ -127,7 +128,7 @@ namespace VNLib.Net.Http
* during request parsing)
*
*/
- private static readonly IReadOnlyDictionary<int, HttpRequestHeader> RequestHeaderHashLookup = HashRequestHeaders();
+ private static readonly IReadOnlyDictionary<int, HttpRequestHeader> RequestHeaderHashLookup = ComputeCodeHashLookup(RequestHeaderLookup);
/*
* Provides a constant lookup table for http version hashcodes to an http
@@ -164,42 +165,22 @@ namespace VNLib.Net.Http
private static IReadOnlyDictionary<int, HttpMethod> HashHttpMethods()
{
/*
- * Http methods are hashed at runtime using the HttpMethod enum
- * values, purley for compatability and automation
- */
- Dictionary<int, HttpMethod> methods = new();
- //Add all HTTP methods
- foreach (HttpMethod method in Enum.GetValues<HttpMethod>())
- {
+ * Http methods are hashed at runtime using the HttpMethod enum
+ * values, purley for compatability and automation
+ */
+ return ComputeCodeHashLookup(
+ Enum.GetValues<HttpMethod>()
//Exclude the not supported method
- if (method == HttpMethod.None)
- {
- continue;
- }
- //Store method string's hashcode for faster lookups
- methods[string.GetHashCode(method.ToString(), StringComparison.OrdinalIgnoreCase)] = method;
- }
- return methods;
+ .Except(new HttpMethod[] { HttpMethod.None })
+ .Select(m => KeyValuePair.Create(m.ToString(), m))
+ );
}
- private static IReadOnlyDictionary<int, HttpRequestHeader> HashRequestHeaders()
- {
- /*
- * Pre-compute common headers
- */
- Dictionary<int, HttpRequestHeader> requestHeaderHashes = new();
-
- //Add all HTTP methods
- foreach (string headerValue in RequestHeaderLookup.Keys)
- {
- //Compute the hashcode for the header value
- int hashCode = string.GetHashCode(headerValue, StringComparison.OrdinalIgnoreCase);
- //Store the http header enum value with the hash-code of the string of said header
- requestHeaderHashes[hashCode] = RequestHeaderLookup[headerValue];
- }
- return requestHeaderHashes;
- }
-
+ private static IReadOnlyDictionary<int, T> ComputeCodeHashLookup<T>(IEnumerable<KeyValuePair<string, T>> enumerable)
+ => enumerable.ToDictionary(
+ static kv => string.GetHashCode(kv.Key, StringComparison.OrdinalIgnoreCase),
+ static kv => kv.Value
+ );
/// <summary>
/// Returns an http formatted content type string of a specified content type
@@ -216,6 +197,18 @@ namespace VNLib.Net.Http
/// <returns><see cref="ContentType"/> of request, <see cref="ContentType.NonSupported"/> if unknown</returns>
public static ContentType GetContentType(string type) => MimeToCt.GetValueOrDefault(type, ContentType.NonSupported);
+ /// <summary>
+ /// Returns the <see cref="ContentType"/> enum value from the MIME string
+ /// </summary>
+ /// <param name="type">Content type character span to compute the hashcode of</param>
+ /// <returns><see cref="ContentType"/> of request, <see cref="ContentType.NonSupported"/> if unknown</returns>
+ public static ContentType GetContentType(ReadOnlySpan<char> type)
+ {
+ //Compute hashcode
+ int ctHashCode = string.GetHashCode(type, StringComparison.OrdinalIgnoreCase);
+ return ContentTypeHashLookup.GetValueOrDefault(ctHashCode, ContentType.NonSupported);
+ }
+
//Cache control string using mdn reference
//https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
/// <summary>
@@ -274,7 +267,6 @@ namespace VNLib.Net.Http
/// </summary>
/// <param name="smethod">Http acceptable method type string</param>
/// <returns>Request method, <see cref="HttpMethod.None"/> if method is malformatted or unsupported</returns>
- /// <exception cref="ArgumentNullException"></exception>
public static HttpMethod GetRequestMethod(ReadOnlySpan<char> smethod)
{
//Get the hashcode for the method "string"
diff --git a/lib/Net.Http/src/Helpers/MimeLookups.cs b/lib/Net.Http/src/Helpers/MimeLookups.cs
index 17582bb..c0dd82c 100644
--- a/lib/Net.Http/src/Helpers/MimeLookups.cs
+++ b/lib/Net.Http/src/Helpers/MimeLookups.cs
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022 Vaughn Nugent
+* Copyright (c) 2023 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.Net.Http
@@ -22,11 +22,8 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
-using System;
+
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace VNLib.Net.Http
{
@@ -3234,5 +3231,11 @@ namespace VNLib.Net.Http
{ "application/vnd.zul", ContentType.Zir },
{ "application/vnd.handheld-entertainment+xml", ContentType.Zmm },
};
+
+
+ /*
+ * A string hashcode lookup table for MIME content types
+ */
+ private static readonly IReadOnlyDictionary<int, ContentType> ContentTypeHashLookup = ComputeCodeHashLookup(MimeToCt);
}
}