diff --git a/API/Content/Authentication/IUser.cs b/API/Content/Authentication/IUser.cs
index 39e9d7b0..f4fb9925 100644
--- a/API/Content/Authentication/IUser.cs
+++ b/API/Content/Authentication/IUser.cs
@@ -1,19 +1,16 @@
-namespace GenHTTP.Api.Content.Authentication
+namespace GenHTTP.Api.Content.Authentication;
+
+///
+/// Information about an user that is associated with
+/// the currently handled request.
+///
+public interface IUser
{
-
+
///
- /// Information about an user that is associated with
- /// the currently handled request.
+ /// The name of the user as it should be shown on
+ /// the UI (e.g. a rendered, themed page).
///
- public interface IUser
- {
-
- ///
- /// The name of the user as it should be shown on
- /// the UI (e.g. a rendered, themed page).
- ///
- string DisplayName { get; }
-
- }
+ string DisplayName { get; }
}
diff --git a/API/Content/Caching/ICache.cs b/API/Content/Caching/ICache.cs
index 5dc48b93..07bb8973 100644
--- a/API/Content/Caching/ICache.cs
+++ b/API/Content/Caching/ICache.cs
@@ -2,50 +2,47 @@
using System.IO;
using System.Threading.Tasks;
-namespace GenHTTP.Api.Content.Caching
+namespace GenHTTP.Api.Content.Caching;
+
+///
+/// Saves intermediate results for fast access.
+///
+/// The type of the results to be cached
+public interface ICache
{
///
- /// Saves intermediate results for fast access.
+ /// Fetches all entries that are stored in the
+ /// cache with the given key.
///
- /// The type of the results to be cached
- public interface ICache
- {
-
- ///
- /// Fetches all entries that are stored in the
- /// cache with the given key.
- ///
- /// The key to look up
- /// The entries stored for this key
- ValueTask GetEntriesAsync(string key);
-
- ///
- /// Attempts to fetch a single entry with the given key
- /// and variation.
- ///
- /// The key of the entry to be fetched
- /// The variation to be fetched
- /// The requested entry, if any
- ValueTask GetEntryAsync(string key, string variation);
+ /// The key to look up
+ /// The entries stored for this key
+ ValueTask GetEntriesAsync(string key);
- ///
- /// Stores the given entry in the cache.
- ///
- /// The key of the entry (should be file system compatible)
- /// The variation specification of the entry
- /// The entry to be stored (or to be deleted, if null)
- ValueTask StoreAsync(string key, string variation, T? entry);
+ ///
+ /// Attempts to fetch a single entry with the given key
+ /// and variation.
+ ///
+ /// The key of the entry to be fetched
+ /// The variation to be fetched
+ /// The requested entry, if any
+ ValueTask GetEntryAsync(string key, string variation);
- ///
- /// Exposes the stream which can be written to to
- /// update the specified entry.
- ///
- /// The key of the entry to be written (should be file system compatible)
- /// The variation specification of the entry
- /// A callback that allows to write the entry to the target stream
- ValueTask StoreDirectAsync(string key, string variation, Func asyncWriter);
+ ///
+ /// Stores the given entry in the cache.
+ ///
+ /// The key of the entry (should be file system compatible)
+ /// The variation specification of the entry
+ /// The entry to be stored (or to be deleted, if null)
+ ValueTask StoreAsync(string key, string variation, T? entry);
- }
+ ///
+ /// Exposes the stream which can be written to to
+ /// update the specified entry.
+ ///
+ /// The key of the entry to be written (should be file system compatible)
+ /// The variation specification of the entry
+ /// A callback that allows to write the entry to the target stream
+ ValueTask StoreDirectAsync(string key, string variation, Func asyncWriter);
}
diff --git a/API/Content/Concerns.cs b/API/Content/Concerns.cs
index 6b10ad0a..2caca27f 100644
--- a/API/Content/Concerns.cs
+++ b/API/Content/Concerns.cs
@@ -1,38 +1,37 @@
using System;
using System.Collections.Generic;
-namespace GenHTTP.Api.Content
+namespace GenHTTP.Api.Content;
+
+///
+/// Utility class to work with concerns.
+///
+public static class Concerns
{
///
- /// Utility class to work with concerns.
+ /// Creates a handler chain to wrap the specified handler into the
+ /// specified concerns.
///
- public static class Concerns
+ ///
+ /// Use this utility within the handler builders to add concerns
+ /// to the resulting handler instance. The last concern added
+ /// to the list of concerns will be the root handler returned by
+ /// this method.
+ ///
+ /// The parent handler of the chain
+ /// The concerns that should be wrapped around the inner handler
+ /// The logic creating the actual handler to be chained
+ /// The outermost handler or root of the chain
+ public static IHandler Chain(IHandler parent, IEnumerable concerns, Func factory)
{
-
- ///
- /// Creates a handler chain to wrap the specified handler into the
- /// specified concerns.
- ///
- ///
- /// Use this utility within the handler builders to add concerns
- /// to the resulting handler instance. The last concern added
- /// to the list of concerns will be the root handler returned by
- /// this method.
- ///
- /// The parent handler of the chain
- /// The concerns that should be wrapped around the inner handler
- /// The logic creating the actual handler to be chained
- /// The outermost handler or root of the chain
- public static IHandler Chain(IHandler parent, IEnumerable concerns, Func factory)
- {
var stack = new Stack(concerns);
return Chain(parent, stack, factory);
}
- private static IHandler Chain(IHandler parent, Stack remainders, Func factory)
- {
+ private static IHandler Chain(IHandler parent, Stack remainders, Func factory)
+ {
if (remainders.Count > 0)
{
var concern = remainders.Pop();
@@ -43,6 +42,4 @@ private static IHandler Chain(IHandler parent, Stack remainders
return factory(parent);
}
- }
-
}
diff --git a/API/Content/IConcern.cs b/API/Content/IConcern.cs
index abc390ec..018fcfa0 100644
--- a/API/Content/IConcern.cs
+++ b/API/Content/IConcern.cs
@@ -1,18 +1,15 @@
-namespace GenHTTP.Api.Content
+namespace GenHTTP.Api.Content;
+
+///
+/// Functionality that wraps around a regular handler to add a
+/// concern such as response compression.
+///
+public interface IConcern : IHandler
{
///
- /// Functionality that wraps around a regular handler to add a
- /// concern such as response compression.
+ /// The actual handler the concern is added to.
///
- public interface IConcern : IHandler
- {
-
- ///
- /// The actual handler the concern is added to.
- ///
- IHandler Content { get; }
-
- }
+ IHandler Content { get; }
}
diff --git a/API/Content/IConcernBuilder.cs b/API/Content/IConcernBuilder.cs
index 31669605..254db5e4 100644
--- a/API/Content/IConcernBuilder.cs
+++ b/API/Content/IConcernBuilder.cs
@@ -1,22 +1,19 @@
using System;
-namespace GenHTTP.Api.Content
+namespace GenHTTP.Api.Content;
+
+///
+/// Interface which needs to be implementd by factories providing concern instances.
+///
+public interface IConcernBuilder
{
///
- /// Interface which needs to be implementd by factories providing concern instances.
+ /// Builds the concern and sets the inner handler of it.
///
- public interface IConcernBuilder
- {
-
- ///
- /// Builds the concern and sets the inner handler of it.
- ///
- /// The parent of the resulting concern handler instance
- /// A method providing the content of the concern
- /// The newly created concern instance
- IConcern Build(IHandler parent, Func contentFactory);
-
- }
+ /// The parent of the resulting concern handler instance
+ /// A method providing the content of the concern
+ /// The newly created concern instance
+ IConcern Build(IHandler parent, Func contentFactory);
}
diff --git a/API/Content/IErrorMapper.cs b/API/Content/IErrorMapper.cs
index 65fe085c..76be7ff5 100644
--- a/API/Content/IErrorMapper.cs
+++ b/API/Content/IErrorMapper.cs
@@ -3,34 +3,31 @@
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Api.Content
+namespace GenHTTP.Api.Content;
+
+///
+/// Can be used with the error handling module to generate custom
+/// responses for exceptions thrown during request handling.
+///
+/// The type of exception to be mapped (others will not be handled)
+public interface IErrorMapper where T : Exception
{
///
- /// Can be used with the error handling module to generate custom
- /// responses for exceptions thrown during request handling.
+ /// Generates a HTTP response to be sent for the given exception.
///
- /// The type of exception to be mapped (others will not be handled)
- public interface IErrorMapper where T : Exception
- {
-
- ///
- /// Generates a HTTP response to be sent for the given exception.
- ///
- /// The request which caused the error
- /// The handler which catched the exception
- /// The actual exception to be mapped
- /// A HTTP response to be sent or null, if the error should be handled as not found by the next error handler in the chain
- ValueTask Map(IRequest request, IHandler handler, T error);
-
- ///
- /// Generates a HTTP response for a resource that has not been found.
- ///
- /// The currently handled request
- /// The inner handler of the error handling concern
- /// A HTTP response to be sent or null, if the error should be handled as not found by the next error handler in the chain
- ValueTask GetNotFound(IRequest request, IHandler handler);
+ /// The request which caused the error
+ /// The handler which catched the exception
+ /// The actual exception to be mapped
+ /// A HTTP response to be sent or null, if the error should be handled as not found by the next error handler in the chain
+ ValueTask Map(IRequest request, IHandler handler, T error);
- }
+ ///
+ /// Generates a HTTP response for a resource that has not been found.
+ ///
+ /// The currently handled request
+ /// The inner handler of the error handling concern
+ /// A HTTP response to be sent or null, if the error should be handled as not found by the next error handler in the chain
+ ValueTask GetNotFound(IRequest request, IHandler handler);
}
diff --git a/API/Content/IHandler.cs b/API/Content/IHandler.cs
index af1555b9..1ba3ab21 100644
--- a/API/Content/IHandler.cs
+++ b/API/Content/IHandler.cs
@@ -2,46 +2,43 @@
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Api.Content
+namespace GenHTTP.Api.Content;
+
+///
+/// Content provider that is able to handle a request and return a HTTP
+/// response to it.
+///
+public interface IHandler
{
///
- /// Content provider that is able to handle a request and return a HTTP
- /// response to it.
+ /// The parent of this handler within the routing tree.
///
- public interface IHandler
- {
-
- ///
- /// The parent of this handler within the routing tree.
- ///
- IHandler Parent { get; }
+ IHandler Parent { get; }
- ///
- /// Invoked to perform computation heavy or IO bound work
- /// that initializes the handler before handling the
- /// first requests.
- ///
- ///
- /// Intended to keep the response time for the first
- /// requests low. Handlers should relay this call to dependent
- /// child handlers to initialize the whole handler chain.
- /// May be called multiple times depending on the setup
- /// the handler is used in.
- ///
- ValueTask PrepareAsync();
-
- ///
- /// Handles the given request and returns a response, if applicable.
- ///
- ///
- /// Not returning a response causes the server to respond with a not found
- /// response code.
- ///
- /// The request to be handled
- /// The response to be sent to the requesting client
- ValueTask HandleAsync(IRequest request);
+ ///
+ /// Invoked to perform computation heavy or IO bound work
+ /// that initializes the handler before handling the
+ /// first requests.
+ ///
+ ///
+ /// Intended to keep the response time for the first
+ /// requests low. Handlers should relay this call to dependent
+ /// child handlers to initialize the whole handler chain.
+ /// May be called multiple times depending on the setup
+ /// the handler is used in.
+ ///
+ ValueTask PrepareAsync();
- }
+ ///
+ /// Handles the given request and returns a response, if applicable.
+ ///
+ ///
+ /// Not returning a response causes the server to respond with a not found
+ /// response code.
+ ///
+ /// The request to be handled
+ /// The response to be sent to the requesting client
+ ValueTask HandleAsync(IRequest request);
}
diff --git a/API/Content/IHandlerBuilder.cs b/API/Content/IHandlerBuilder.cs
index ac85706f..bbaf9ce4 100644
--- a/API/Content/IHandlerBuilder.cs
+++ b/API/Content/IHandlerBuilder.cs
@@ -1,34 +1,31 @@
-namespace GenHTTP.Api.Content
+namespace GenHTTP.Api.Content;
+
+///
+/// Allows to create a handler instance.
+///
+public interface IHandlerBuilder
{
///
- /// Allows to create a handler instance.
+ /// Creates the configured handler instance.
///
- public interface IHandlerBuilder
- {
-
- ///
- /// Creates the configured handler instance.
- ///
- /// The parent of the handler to be created
- /// The newly created handler instance
- IHandler Build(IHandler parent);
+ /// The parent of the handler to be created
+ /// The newly created handler instance
+ IHandler Build(IHandler parent);
- }
-
- public interface IHandlerBuilder : IHandlerBuilder where TBuilder : IHandlerBuilder
- {
+}
- ///
- /// Adds the given concern to the resulting handler.
- ///
- ///
- /// The first concern added to the builder will be the new root
- /// of the chain returned by the builder.
- ///
- /// The concern to be added to the resulting handler
- TBuilder Add(IConcernBuilder concern);
+public interface IHandlerBuilder : IHandlerBuilder where TBuilder : IHandlerBuilder
+{
- }
+ ///
+ /// Adds the given concern to the resulting handler.
+ ///
+ ///
+ /// The first concern added to the builder will be the new root
+ /// of the chain returned by the builder.
+ ///
+ /// The concern to be added to the resulting handler
+ TBuilder Add(IConcernBuilder concern);
}
diff --git a/API/Content/IO/ICompressionAlgorithm.cs b/API/Content/IO/ICompressionAlgorithm.cs
index ec4add1b..e65107aa 100644
--- a/API/Content/IO/ICompressionAlgorithm.cs
+++ b/API/Content/IO/ICompressionAlgorithm.cs
@@ -3,37 +3,34 @@
using GenHTTP.Api.Infrastructure;
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Api.Content.IO
+namespace GenHTTP.Api.Content.IO;
+
+///
+/// The implementation of an algorithm allowing to transfer content
+/// in a compressed form to the client.
+///
+public interface ICompressionAlgorithm
{
///
- /// The implementation of an algorithm allowing to transfer content
- /// in a compressed form to the client.
+ /// The name of the algorithm as specified by the client in the
+ /// "Accept-Encoding" HTTP header.
///
- public interface ICompressionAlgorithm
- {
-
- ///
- /// The name of the algorithm as specified by the client in the
- /// "Accept-Encoding" HTTP header.
- ///
- string Name { get; }
+ string Name { get; }
- ///
- /// The priority of the algorithm. The algorithm with the highest
- /// priority will be selected if mutliple algorithms can be applied
- /// to a response.
- ///
- Priority Priority { get; }
-
- ///
- /// Returns a content instance allowing the server to stream the compressed content.
- ///
- /// The content of the response to be compressed
- /// The compression level to be applied
- /// A result representing the compressed content
- IResponseContent Compress(IResponseContent content, CompressionLevel level);
+ ///
+ /// The priority of the algorithm. The algorithm with the highest
+ /// priority will be selected if mutliple algorithms can be applied
+ /// to a response.
+ ///
+ Priority Priority { get; }
- }
+ ///
+ /// Returns a content instance allowing the server to stream the compressed content.
+ ///
+ /// The content of the response to be compressed
+ /// The compression level to be applied
+ /// A result representing the compressed content
+ IResponseContent Compress(IResponseContent content, CompressionLevel level);
}
diff --git a/API/Content/IO/IResource.cs b/API/Content/IO/IResource.cs
index 41d6c198..154f3b0d 100644
--- a/API/Content/IO/IResource.cs
+++ b/API/Content/IO/IResource.cs
@@ -3,68 +3,65 @@
using System.Threading.Tasks;
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Api.Content.IO
+namespace GenHTTP.Api.Content.IO;
+
+///
+/// Allows content providers to access a resource without the need
+/// to know the actual way of access (such as database, web, or
+/// file system).
+///
+///
+/// As resources may change (e.g. if an user changes the file that
+/// is provided as a resource), content providers must not
+/// cache the results of a method call.
+///
+public interface IResource
{
///
- /// Allows content providers to access a resource without the need
- /// to know the actual way of access (such as database, web, or
- /// file system).
+ /// The name of this resource, if known.
///
- ///
- /// As resources may change (e.g. if an user changes the file that
- /// is provided as a resource), content providers must not
- /// cache the results of a method call.
- ///
- public interface IResource
- {
-
- ///
- /// The name of this resource, if known.
- ///
- string? Name { get; }
-
- ///
- /// The point in time, when the resource was last modified, if known.
- ///
- DateTime? Modified { get; }
+ string? Name { get; }
- ///
- /// The content type of this resource, if known.
- ///
- FlexibleContentType? ContentType { get; }
+ ///
+ /// The point in time, when the resource was last modified, if known.
+ ///
+ DateTime? Modified { get; }
- ///
- /// The number of bytes provided by this resource.
- ///
- ///
- /// This field will not be used to control the HTTP flow, but
- /// just as meta information (e.g. to be rendered by the
- /// directory listing handler). For optimzed data transfer,
- /// the stream provided by this resource should be seekable
- /// and return a sane length.
- ///
- ulong? Length { get; }
+ ///
+ /// The content type of this resource, if known.
+ ///
+ FlexibleContentType? ContentType { get; }
- ///
- /// Calculates the checksum of the resource.
- ///
- /// The checksum of the resource
- ValueTask CalculateChecksumAsync();
+ ///
+ /// The number of bytes provided by this resource.
+ ///
+ ///
+ /// This field will not be used to control the HTTP flow, but
+ /// just as meta information (e.g. to be rendered by the
+ /// directory listing handler). For optimzed data transfer,
+ /// the stream provided by this resource should be seekable
+ /// and return a sane length.
+ ///
+ ulong? Length { get; }
- ///
- /// Returns the read-only stream of the resource to be accessed.
- ///
- /// The resource to be accessed
- ValueTask GetContentAsync();
+ ///
+ /// Calculates the checksum of the resource.
+ ///
+ /// The checksum of the resource
+ ValueTask CalculateChecksumAsync();
- ///
- /// Writes the content of the resource to the given stream.
- ///
- /// The stream to write to
- /// The buffer size to be used for the operation
- ValueTask WriteAsync(Stream target, uint bufferSize);
+ ///
+ /// Returns the read-only stream of the resource to be accessed.
+ ///
+ /// The resource to be accessed
+ ValueTask GetContentAsync();
- }
+ ///
+ /// Writes the content of the resource to the given stream.
+ ///
+ /// The stream to write to
+ /// The buffer size to be used for the operation
+ ValueTask WriteAsync(Stream target, uint bufferSize);
}
diff --git a/API/Content/IO/IResourceBuilder.cs b/API/Content/IO/IResourceBuilder.cs
index 26e3e691..8769fade 100644
--- a/API/Content/IO/IResourceBuilder.cs
+++ b/API/Content/IO/IResourceBuilder.cs
@@ -3,46 +3,43 @@
using GenHTTP.Api.Infrastructure;
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Api.Content.IO
+namespace GenHTTP.Api.Content.IO;
+
+///
+/// When implemented by builders providing resource instances,
+/// this interface allows to configure common properties of
+/// resources in an unified way.
+///
+public interface IResourceBuilder : IBuilder where T : IResourceBuilder
{
///
- /// When implemented by builders providing resource instances,
- /// this interface allows to configure common properties of
- /// resources in an unified way.
+ /// Sets the name of the resource.
///
- public interface IResourceBuilder : IBuilder where T : IResourceBuilder
- {
-
- ///
- /// Sets the name of the resource.
- ///
- /// The name of the resource
- T Name(string name);
-
- ///
- /// Sets the content type of the resource.
- ///
- /// The content type of the resource
- T Type(FlexibleContentType contentType);
-
- ///
- /// Sets the modification date and time of the resource.
- ///
- /// The modification date and time of the resource
- T Modified(DateTime modified);
-
- }
-
- public static class IResourceMetaDataBuilderExtensions
- {
-
- ///
- /// Sets the content type of the resource.
- ///
- /// The content type of the resource
- public static T Type(this IResourceBuilder builder, ContentType contentType) where T : IResourceBuilder => builder.Type(FlexibleContentType.Get(contentType));
-
- }
+ /// The name of the resource
+ T Name(string name);
+
+ ///
+ /// Sets the content type of the resource.
+ ///
+ /// The content type of the resource
+ T Type(FlexibleContentType contentType);
+
+ ///
+ /// Sets the modification date and time of the resource.
+ ///
+ /// The modification date and time of the resource
+ T Modified(DateTime modified);
+
+}
+
+public static class IResourceMetaDataBuilderExtensions
+{
+
+ ///
+ /// Sets the content type of the resource.
+ ///
+ /// The content type of the resource
+ public static T Type(this IResourceBuilder builder, ContentType contentType) where T : IResourceBuilder => builder.Type(FlexibleContentType.Get(contentType));
}
diff --git a/API/Content/IO/IResourceContainer.cs b/API/Content/IO/IResourceContainer.cs
index ddb9a409..6c47fa3e 100644
--- a/API/Content/IO/IResourceContainer.cs
+++ b/API/Content/IO/IResourceContainer.cs
@@ -2,48 +2,45 @@
using System.Collections.Generic;
using System.Threading.Tasks;
-namespace GenHTTP.Api.Content.IO
+namespace GenHTTP.Api.Content.IO;
+
+///
+/// Provides a single hierarchy level in a structure
+/// provided by a resource tree.
+///
+public interface IResourceContainer
{
///
- /// Provides a single hierarchy level in a structure
- /// provided by a resource tree.
+ /// The point in time when the container was modified (if known).
+ ///
+ DateTime? Modified { get; }
+
+ ///
+ /// Tries to fetch the child node with the given name.
+ ///
+ /// The name of the node to be fetched
+ /// The node fetched from the container, if the node could be found
+ ValueTask TryGetNodeAsync(string name);
+
+ ///
+ /// Returns the child nodes provided by this container.
+ ///
+ /// The child nodes provided by this container
+ ValueTask> GetNodes();
+
+ ///
+ /// Tries to fetch the resource with the given name.
+ ///
+ /// The name of the resource to be fetched
+ ///
+ /// The resource fetched from the container, if the resource could be found
+ ValueTask TryGetResourceAsync(string name);
+
+ ///
+ /// Returns the resources provided by this container.
///
- public interface IResourceContainer
- {
-
- ///
- /// The point in time when the container was modified (if known).
- ///
- DateTime? Modified { get; }
-
- ///
- /// Tries to fetch the child node with the given name.
- ///
- /// The name of the node to be fetched
- /// The node fetched from the container, if the node could be found
- ValueTask TryGetNodeAsync(string name);
-
- ///
- /// Returns the child nodes provided by this container.
- ///
- /// The child nodes provided by this container
- ValueTask> GetNodes();
-
- ///
- /// Tries to fetch the resource with the given name.
- ///
- /// The name of the resource to be fetched
- ///
- /// The resource fetched from the container, if the resource could be found
- ValueTask TryGetResourceAsync(string name);
-
- ///
- /// Returns the resources provided by this container.
- ///
- /// The resources provided by this container
- ValueTask> GetResources();
-
- }
+ /// The resources provided by this container
+ ValueTask> GetResources();
}
diff --git a/API/Content/IO/IResourceNode.cs b/API/Content/IO/IResourceNode.cs
index 7683f69d..8e0e4ef6 100644
--- a/API/Content/IO/IResourceNode.cs
+++ b/API/Content/IO/IResourceNode.cs
@@ -1,23 +1,20 @@
-namespace GenHTTP.Api.Content.IO
+namespace GenHTTP.Api.Content.IO;
+
+///
+/// Provides a single hierarchy level in a structure
+/// provided by a resource tree.
+///
+public interface IResourceNode : IResourceContainer
{
///
- /// Provides a single hierarchy level in a structure
- /// provided by a resource tree.
+ /// The name of this node.
///
- public interface IResourceNode : IResourceContainer
- {
-
- ///
- /// The name of this node.
- ///
- string Name { get; }
-
- ///
- /// The parent of this node.
- ///
- IResourceContainer Parent { get; }
+ string Name { get; }
- }
+ ///
+ /// The parent of this node.
+ ///
+ IResourceContainer Parent { get; }
}
diff --git a/API/Content/IO/IResourceTree.cs b/API/Content/IO/IResourceTree.cs
index e8151174..c4f3f691 100644
--- a/API/Content/IO/IResourceTree.cs
+++ b/API/Content/IO/IResourceTree.cs
@@ -1,13 +1,10 @@
-namespace GenHTTP.Api.Content.IO
-{
-
- ///
- /// Provides resources organized into a tree structure
- /// (e.g. a directory or embedded ressources).
- ///
- public interface IResourceTree : IResourceContainer
- {
+namespace GenHTTP.Api.Content.IO;
- }
+///
+/// Provides resources organized into a tree structure
+/// (e.g. a directory or embedded ressources).
+///
+public interface IResourceTree : IResourceContainer
+{
}
diff --git a/API/Content/ProviderException.cs b/API/Content/ProviderException.cs
index b6b9c84a..438990fb 100644
--- a/API/Content/ProviderException.cs
+++ b/API/Content/ProviderException.cs
@@ -2,41 +2,38 @@
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Api.Content
+namespace GenHTTP.Api.Content;
+
+///
+/// If thrown by a content provider or router, the server will return
+/// the specified HTTP response status to the client instead of
+/// indicating a server error.
+///
+[Serializable]
+public class ProviderException : Exception
{
+ #region Get-/Setters
+
///
- /// If thrown by a content provider or router, the server will return
- /// the specified HTTP response status to the client instead of
- /// indicating a server error.
+ /// The status to be returned to the client.
///
- [Serializable]
- public class ProviderException : Exception
- {
-
- #region Get-/Setters
-
- ///
- /// The status to be returned to the client.
- ///
- public ResponseStatus Status { get; }
+ public ResponseStatus Status { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- public ProviderException(ResponseStatus status, string message) : base(message)
- {
+ public ProviderException(ResponseStatus status, string message) : base(message)
+ {
Status = status;
}
- public ProviderException(ResponseStatus status, string message, Exception inner) : base(message, inner)
- {
+ public ProviderException(ResponseStatus status, string message, Exception inner) : base(message, inner)
+ {
Status = status;
}
- #endregion
-
- }
+ #endregion
}
diff --git a/API/Infrastructure/BindingException.cs b/API/Infrastructure/BindingException.cs
index 3678fda1..21a65ee6 100644
--- a/API/Infrastructure/BindingException.cs
+++ b/API/Infrastructure/BindingException.cs
@@ -1,20 +1,17 @@
using System;
-namespace GenHTTP.Api.Infrastructure
+namespace GenHTTP.Api.Infrastructure;
+
+///
+/// Will be thrown, if the server cannot bind to the requested port for some reason.
+///
+[Serializable]
+public class BindingException : Exception
{
- ///
- /// Will be thrown, if the server cannot bind to the requested port for some reason.
- ///
- [Serializable]
- public class BindingException : Exception
+ public BindingException(string message, Exception inner) : base(message, inner)
{
- public BindingException(string message, Exception inner) : base(message, inner)
- {
-
}
- }
-
}
diff --git a/API/Infrastructure/BuilderMissingPropertyException.cs b/API/Infrastructure/BuilderMissingPropertyException.cs
index a053c899..df710325 100644
--- a/API/Infrastructure/BuilderMissingPropertyException.cs
+++ b/API/Infrastructure/BuilderMissingPropertyException.cs
@@ -1,34 +1,31 @@
using System;
-namespace GenHTTP.Api.Infrastructure
+namespace GenHTTP.Api.Infrastructure;
+
+///
+/// Will be thrown, if a builder is missing a required property
+/// that is needed to create the target instance.
+///
+[Serializable]
+public class BuilderMissingPropertyException : Exception
{
+ #region Get-/Setters
+
///
- /// Will be thrown, if a builder is missing a required property
- /// that is needed to create the target instance.
+ /// The name of the property which has not been set.
///
- [Serializable]
- public class BuilderMissingPropertyException : Exception
- {
-
- #region Get-/Setters
+ public string Property { get; }
- ///
- /// The name of the property which has not been set.
- ///
- public string Property { get; }
+ #endregion
- #endregion
+ #region Initialization
- #region Initialization
-
- public BuilderMissingPropertyException(string property) : base($"Missing required property '{property}'")
- {
+ public BuilderMissingPropertyException(string property) : base($"Missing required property '{property}'")
+ {
Property = property;
}
- #endregion
-
- }
+ #endregion
}
diff --git a/API/Infrastructure/IBuilder.cs b/API/Infrastructure/IBuilder.cs
index a566eefb..6bcc3fa4 100644
--- a/API/Infrastructure/IBuilder.cs
+++ b/API/Infrastructure/IBuilder.cs
@@ -1,25 +1,22 @@
-namespace GenHTTP.Api.Infrastructure
+namespace GenHTTP.Api.Infrastructure;
+
+///
+/// General interface implemented by every builder resposible to
+/// configure and setup an instance.
+///
+/// The type which should be produced by the builder
+///
+/// Builders must not change their internal state when building an object, allowing
+/// builder instances to be re-used if required.
+///
+public interface IBuilder
{
///
- /// General interface implemented by every builder resposible to
- /// configure and setup an instance.
+ /// Creates a new instance of the specified type using
+ /// the current configuration.
///
- /// The type which should be produced by the builder
- ///
- /// Builders must not change their internal state when building an object, allowing
- /// builder instances to be re-used if required.
- ///
- public interface IBuilder
- {
-
- ///
- /// Creates a new instance of the specified type using
- /// the current configuration.
- ///
- /// The newly created instance
- T Build();
-
- }
+ /// The newly created instance
+ T Build();
}
diff --git a/API/Infrastructure/ICertificateProvider.cs b/API/Infrastructure/ICertificateProvider.cs
index 68409477..2dfcd8f6 100644
--- a/API/Infrastructure/ICertificateProvider.cs
+++ b/API/Infrastructure/ICertificateProvider.cs
@@ -1,22 +1,19 @@
using System.Security.Cryptography.X509Certificates;
-namespace GenHTTP.Api.Infrastructure
+namespace GenHTTP.Api.Infrastructure;
+
+///
+/// Allows secure endpoints to select the certificate they should
+/// authenticate the client with.
+///
+public interface ICertificateProvider
{
///
- /// Allows secure endpoints to select the certificate they should
- /// authenticate the client with.
+ /// Select a certificate for authentication based on the given host.
///
- public interface ICertificateProvider
- {
-
- ///
- /// Select a certificate for authentication based on the given host.
- ///
- /// The name of the host, if specified by the client
- /// The certificate to be used to authenticate the client
- X509Certificate2? Provide(string? host);
-
- }
+ /// The name of the host, if specified by the client
+ /// The certificate to be used to authenticate the client
+ X509Certificate2? Provide(string? host);
}
diff --git a/API/Infrastructure/IClientConnection.cs b/API/Infrastructure/IClientConnection.cs
index 294cedeb..95d4d9a4 100644
--- a/API/Infrastructure/IClientConnection.cs
+++ b/API/Infrastructure/IClientConnection.cs
@@ -2,32 +2,29 @@
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Api.Infrastructure
+namespace GenHTTP.Api.Infrastructure;
+
+///
+/// The remote client which requests a resource from the server.
+///
+public interface IClientConnection
{
///
- /// The remote client which requests a resource from the server.
+ /// The IP address of the remotely connected client.
///
- public interface IClientConnection
- {
-
- ///
- /// The IP address of the remotely connected client.
- ///
- IPAddress IPAddress { get; }
+ IPAddress IPAddress { get; }
- ///
- /// The protocol used by the client to connect
- /// to the server.
- ///
- ClientProtocol? Protocol { get; }
-
- ///
- /// The host name used by the client to connect
- /// to the server.
- ///
- string? Host { get; }
+ ///
+ /// The protocol used by the client to connect
+ /// to the server.
+ ///
+ ClientProtocol? Protocol { get; }
- }
+ ///
+ /// The host name used by the client to connect
+ /// to the server.
+ ///
+ string? Host { get; }
}
diff --git a/API/Infrastructure/IEndPoint.cs b/API/Infrastructure/IEndPoint.cs
index b1e4fec2..0d2074d5 100644
--- a/API/Infrastructure/IEndPoint.cs
+++ b/API/Infrastructure/IEndPoint.cs
@@ -1,34 +1,31 @@
using System;
using System.Net;
-namespace GenHTTP.Api.Infrastructure
+namespace GenHTTP.Api.Infrastructure;
+
+///
+/// An endpoint the server will listen on for incoming requests.
+///
+public interface IEndPoint : IDisposable
{
///
- /// An endpoint the server will listen on for incoming requests.
+ /// The IP address the endpoint is bound to.
///
- public interface IEndPoint : IDisposable
- {
-
- ///
- /// The IP address the endpoint is bound to.
- ///
- ///
- /// Can be a specific IPv4/IPv6 address or a more generic one
- /// such as .
- ///
- IPAddress IPAddress { get; }
+ ///
+ /// Can be a specific IPv4/IPv6 address or a more generic one
+ /// such as .
+ ///
+ IPAddress IPAddress { get; }
- ///
- /// The port the endpoint is listening on.
- ///
- ushort Port { get; }
-
- ///
- /// Specifies, whether this is is an endpoint secured via SSL/TLS.
- ///
- bool Secure { get; }
+ ///
+ /// The port the endpoint is listening on.
+ ///
+ ushort Port { get; }
- }
+ ///
+ /// Specifies, whether this is is an endpoint secured via SSL/TLS.
+ ///
+ bool Secure { get; }
}
diff --git a/API/Infrastructure/IEndPointCollection.cs b/API/Infrastructure/IEndPointCollection.cs
index 20fcd86e..c5d17da0 100644
--- a/API/Infrastructure/IEndPointCollection.cs
+++ b/API/Infrastructure/IEndPointCollection.cs
@@ -1,14 +1,11 @@
using System.Collections.Generic;
-namespace GenHTTP.Api.Infrastructure
-{
-
- ///
- /// Provides a list of endpoints a server is listening to.
- ///
- public interface IEndPointCollection : IReadOnlyList
- {
+namespace GenHTTP.Api.Infrastructure;
- }
+///
+/// Provides a list of endpoints a server is listening to.
+///
+public interface IEndPointCollection : IReadOnlyList
+{
}
diff --git a/API/Infrastructure/IServer.cs b/API/Infrastructure/IServer.cs
index fded7336..f02bc459 100644
--- a/API/Infrastructure/IServer.cs
+++ b/API/Infrastructure/IServer.cs
@@ -1,54 +1,51 @@
using System;
using GenHTTP.Api.Content;
-namespace GenHTTP.Api.Infrastructure
+namespace GenHTTP.Api.Infrastructure;
+
+///
+/// Listens for incoming HTTP requests and dispatches them
+/// to the registered routers and content providers.
+///
+public interface IServer : IDisposable
{
///
- /// Listens for incoming HTTP requests and dispatches them
- /// to the registered routers and content providers.
+ /// The version of the server software.
+ ///
+ ///
+ /// This property is for informational use only. Do not change
+ /// your code depending on the version you are working with.
+ ///
+ string Version { get; }
+
+ ///
+ /// Specifies, whether the server still serves requests or
+ /// whether it is currently shut down.
+ ///
+ bool Running { get; }
+
+ ///
+ /// If enabled, components may provide additional information
+ /// allowing developers to further debug web applications.
+ ///
+ bool Development { get; }
+
+ ///
+ /// The endpoints the server is listening on.
+ ///
+ IEndPointCollection EndPoints { get; }
+
+ ///
+ /// An instance that will be called on certain events such as
+ /// handled requests or errors that occur within the engine.
+ ///
+ IServerCompanion? Companion { get; }
+
+ ///
+ /// The main router that will be used by the server to dispatch
+ /// incoming HTTP requests.
///
- public interface IServer : IDisposable
- {
-
- ///
- /// The version of the server software.
- ///
- ///
- /// This property is for informational use only. Do not change
- /// your code depending on the version you are working with.
- ///
- string Version { get; }
-
- ///
- /// Specifies, whether the server still serves requests or
- /// whether it is currently shut down.
- ///
- bool Running { get; }
-
- ///
- /// If enabled, components may provide additional information
- /// allowing developers to further debug web applications.
- ///
- bool Development { get; }
-
- ///
- /// The endpoints the server is listening on.
- ///
- IEndPointCollection EndPoints { get; }
-
- ///
- /// An instance that will be called on certain events such as
- /// handled requests or errors that occur within the engine.
- ///
- IServerCompanion? Companion { get; }
-
- ///
- /// The main router that will be used by the server to dispatch
- /// incoming HTTP requests.
- ///
- IHandler Handler { get; }
-
- }
+ IHandler Handler { get; }
}
diff --git a/API/Infrastructure/IServerBuilder.cs b/API/Infrastructure/IServerBuilder.cs
index ad581471..77e01350 100644
--- a/API/Infrastructure/IServerBuilder.cs
+++ b/API/Infrastructure/IServerBuilder.cs
@@ -4,173 +4,170 @@
using System.Security.Cryptography.X509Certificates;
using GenHTTP.Api.Content;
-namespace GenHTTP.Api.Infrastructure
+namespace GenHTTP.Api.Infrastructure;
+
+///
+/// Allows to configure and create a new instance.
+///
+public interface IServerBuilder : IServerBuilder { }
+
+///
+/// Allows to configure and create a new instance.
+///
+public interface IServerBuilder : IBuilder
{
+ #region Content
+
+ ///
+ /// Specifies the root handler that will be invoked when
+ /// a client request needs to be handled.
+ ///
+ /// The handler to be invoked to handle requests
+ ///
+ /// Note that only a single handler is supported. To build are more
+ /// complex application, consider passing a Layout instead.
+ ///
+ T Handler(IHandlerBuilder handler);
+
+ #endregion
+
+ #region Infrastructure
+
+ ///
+ /// Registers a companion that will log all handled requests and
+ /// errors to the console.
+ ///
+ T Console();
+
+ ///
+ /// Registers the given companion to be used by the server, allowing
+ /// to log and handle requests and errors.
+ ///
+ /// The companion to be used by the server
+ T Companion(IServerCompanion companion);
+
///
- /// Allows to configure and create a new instance.
+ /// Enables or disables the development mode on the server instance. When in
+ /// development mode, the server will return additional information
+ /// useful for developers of web applications.
///
- public interface IServerBuilder : IServerBuilder { }
+ /// Whether the development should be active
+ ///
+ /// By default, the development mode is disabled.
+ ///
+ T Development(bool developmentMode = true);
+
+ #endregion
+
+ #region Binding
///
- /// Allows to configure and create a new instance.
+ /// Specifies the port, the server will listen on (defaults to 8080 on IPv4/IPv6).
///
- public interface IServerBuilder : IBuilder
- {
-
- #region Content
-
- ///
- /// Specifies the root handler that will be invoked when
- /// a client request needs to be handled.
- ///
- /// The handler to be invoked to handle requests
- ///
- /// Note that only a single handler is supported. To build are more
- /// complex application, consider passing a Layout instead.
- ///
- T Handler(IHandlerBuilder handler);
-
- #endregion
-
- #region Infrastructure
-
- ///
- /// Registers a companion that will log all handled requests and
- /// errors to the console.
- ///
- T Console();
-
- ///
- /// Registers the given companion to be used by the server, allowing
- /// to log and handle requests and errors.
- ///
- /// The companion to be used by the server
- T Companion(IServerCompanion companion);
-
- ///
- /// Enables or disables the development mode on the server instance. When in
- /// development mode, the server will return additional information
- /// useful for developers of web applications.
- ///
- /// Whether the development should be active
- ///
- /// By default, the development mode is disabled.
- ///
- T Development(bool developmentMode = true);
-
- #endregion
-
- #region Binding
-
- ///
- /// Specifies the port, the server will listen on (defaults to 8080 on IPv4/IPv6).
- ///
- /// The port the server should listen on
- ///
- /// If you register custom endpoints using the Bind methods, this value
- /// will be ignored.
- ///
- T Port(ushort port);
-
- ///
- /// Registers an endpoint for the given address and port the server will
- /// bind to on startup to listen for incomming HTTP requests.
- ///
- /// The address to bind to
- /// The port to listen on
- T Bind(IPAddress address, ushort port);
-
- ///
- /// Registers a secure endpoint the server will bind to on
- /// startup to listen for incoming HTTPS requests.
- ///
- /// The address to bind to
- /// The port to listen on
- /// The certificate used to negoiate a connection with
- ///
- /// By default, the endpoint will accept TLS 1.2 connections only.
- ///
- T Bind(IPAddress address, ushort port, X509Certificate2 certificate);
-
- ///
- /// Registers a secure endpoint the server will bind to on
- /// startup to listen for incoming HTTPS requests.
- ///
- /// The address to bind to
- /// The port to listen on
- /// The certificate used to negoiate a connection with
- /// The SSL/TLS protocl versions which should be supported by the endpoint
- T Bind(IPAddress address, ushort port, X509Certificate2 certificate, SslProtocols protocols);
-
- ///
- /// Registers a secure endpoint the server will bind to on
- /// startup to listen for incoming HTTPS requests.
- ///
- /// The address to bind to
- /// The port to listen on
- /// The provider to select the certificate used to negoiate a connection with
- ///
- /// By default, the endpoint will accept TLS 1.2 connections only.
- ///
- T Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider);
-
- ///
- /// Registers a secure endpoint the server will bind to on
- /// startup to listen for incoming HTTPS requests.
- ///
- /// The address to bind to
- /// The port to listen on
- /// The provider to select the certificate used to negoiate a connection with
- /// The SSL/TLS protocl versions which should be supported by the endpoint
- T Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider, SslProtocols protocols);
-
- #endregion
-
- #region Extensibility
-
- ///
- /// Adds a concern to the server instance which will be executed before
- /// and after the root handler is invoked.
- ///
- /// The concern to be added to the instance
- T Add(IConcernBuilder concern);
-
- #endregion
-
- #region Network settings
-
- ///
- /// Configures the number of connections the operating system will accept
- /// while they not have yet been accepted by the server.
- ///
- /// The number of connections to be accepted
- ///
- /// Adjust this value only, if you expect large bursts of simultaneous requests
- /// or your server requires very long to generate requests.
- ///
- T Backlog(ushort backlog);
-
- ///
- /// Specifies the period of time after which the server will
- /// assume the client connection timed out.
- ///
- T RequestReadTimeout(TimeSpan timeout);
-
- ///
- /// Requests smaller than this limit (in bytes) will be held in memory, while
- /// larger requests will be cached in a temporary file.
- ///
- T RequestMemoryLimit(uint limit);
-
- ///
- /// Size of the buffer that will be used to read or write large
- /// data streams (such as uploads or downloads).
- ///
- T TransferBufferSize(uint bufferSize);
-
- #endregion
-
- }
+ /// The port the server should listen on
+ ///
+ /// If you register custom endpoints using the Bind methods, this value
+ /// will be ignored.
+ ///
+ T Port(ushort port);
+
+ ///
+ /// Registers an endpoint for the given address and port the server will
+ /// bind to on startup to listen for incomming HTTP requests.
+ ///
+ /// The address to bind to
+ /// The port to listen on
+ T Bind(IPAddress address, ushort port);
+
+ ///
+ /// Registers a secure endpoint the server will bind to on
+ /// startup to listen for incoming HTTPS requests.
+ ///
+ /// The address to bind to
+ /// The port to listen on
+ /// The certificate used to negoiate a connection with
+ ///
+ /// By default, the endpoint will accept TLS 1.2 connections only.
+ ///
+ T Bind(IPAddress address, ushort port, X509Certificate2 certificate);
+
+ ///
+ /// Registers a secure endpoint the server will bind to on
+ /// startup to listen for incoming HTTPS requests.
+ ///
+ /// The address to bind to
+ /// The port to listen on
+ /// The certificate used to negoiate a connection with
+ /// The SSL/TLS protocl versions which should be supported by the endpoint
+ T Bind(IPAddress address, ushort port, X509Certificate2 certificate, SslProtocols protocols);
+
+ ///
+ /// Registers a secure endpoint the server will bind to on
+ /// startup to listen for incoming HTTPS requests.
+ ///
+ /// The address to bind to
+ /// The port to listen on
+ /// The provider to select the certificate used to negoiate a connection with
+ ///
+ /// By default, the endpoint will accept TLS 1.2 connections only.
+ ///
+ T Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider);
+
+ ///
+ /// Registers a secure endpoint the server will bind to on
+ /// startup to listen for incoming HTTPS requests.
+ ///
+ /// The address to bind to
+ /// The port to listen on
+ /// The provider to select the certificate used to negoiate a connection with
+ /// The SSL/TLS protocl versions which should be supported by the endpoint
+ T Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider, SslProtocols protocols);
+
+ #endregion
+
+ #region Extensibility
+
+ ///
+ /// Adds a concern to the server instance which will be executed before
+ /// and after the root handler is invoked.
+ ///
+ /// The concern to be added to the instance
+ T Add(IConcernBuilder concern);
+
+ #endregion
+
+ #region Network settings
+
+ ///
+ /// Configures the number of connections the operating system will accept
+ /// while they not have yet been accepted by the server.
+ ///
+ /// The number of connections to be accepted
+ ///
+ /// Adjust this value only, if you expect large bursts of simultaneous requests
+ /// or your server requires very long to generate requests.
+ ///
+ T Backlog(ushort backlog);
+
+ ///
+ /// Specifies the period of time after which the server will
+ /// assume the client connection timed out.
+ ///
+ T RequestReadTimeout(TimeSpan timeout);
+
+ ///
+ /// Requests smaller than this limit (in bytes) will be held in memory, while
+ /// larger requests will be cached in a temporary file.
+ ///
+ T RequestMemoryLimit(uint limit);
+
+ ///
+ /// Size of the buffer that will be used to read or write large
+ /// data streams (such as uploads or downloads).
+ ///
+ T TransferBufferSize(uint bufferSize);
+
+ #endregion
}
diff --git a/API/Infrastructure/IServerCompanion.cs b/API/Infrastructure/IServerCompanion.cs
index 2464d24e..1078f9cd 100644
--- a/API/Infrastructure/IServerCompanion.cs
+++ b/API/Infrastructure/IServerCompanion.cs
@@ -2,85 +2,82 @@
using System.Net;
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Api.Infrastructure
-{
+namespace GenHTTP.Api.Infrastructure;
+
+#region Error scopes
- #region Error scopes
+///
+/// The kind of errors which may occur within the
+/// server engine.
+///
+public enum ServerErrorScope
+{
///
- /// The kind of errors which may occur within the
- /// server engine.
+ /// Errors which occur within the regular lifecycle,
+ /// such as startup errors.
///
- public enum ServerErrorScope
- {
+ General,
- ///
- /// Errors which occur within the regular lifecycle,
- /// such as startup errors.
- ///
- General,
-
- ///
- /// Errors which occur when listening for requests or
- /// when handling them.
- ///
- ServerConnection,
+ ///
+ /// Errors which occur when listening for requests or
+ /// when handling them.
+ ///
+ ServerConnection,
- ///
- /// Errors which occur when communicating with the client,
- /// such as aborted connections.
- ///
- ClientConnection,
+ ///
+ /// Errors which occur when communicating with the client,
+ /// such as aborted connections.
+ ///
+ ClientConnection,
- ///
- /// Errors which occur when trying to establish a secure
- /// connection with the client.
- ///
- Security,
+ ///
+ /// Errors which occur when trying to establish a secure
+ /// connection with the client.
+ ///
+ Security,
- ///
- /// Errors which occur when the server tries to generate a default
- /// error page, e.g. because the template somehow fails to render.
- ///
- PageGeneration,
+ ///
+ /// Errors which occur when the server tries to generate a default
+ /// error page, e.g. because the template somehow fails to render.
+ ///
+ PageGeneration,
- ///
- /// An error which occurred within an extension.
- ///
- Extension,
+ ///
+ /// An error which occurred within an extension.
+ ///
+ Extension,
- }
+}
- #endregion
+#endregion
+
+///
+/// A companion which can be registered at the server to handle
+/// requests and error messages.
+///
+///
+/// Bad runtime characteristics of an implementing class can severly
+/// lower the throughput of your server instance. If you would like to
+/// perform long-running tasks such as logging to a database, it's recommended
+/// to add some kind of asynchronous worker mechanism.
+///
+public interface IServerCompanion
+{
///
- /// A companion which can be registered at the server to handle
- /// requests and error messages.
+ /// Will be invoked after request has been handled by the server.
///
- ///
- /// Bad runtime characteristics of an implementing class can severly
- /// lower the throughput of your server instance. If you would like to
- /// perform long-running tasks such as logging to a database, it's recommended
- /// to add some kind of asynchronous worker mechanism.
- ///
- public interface IServerCompanion
- {
+ /// The request which has been handled
+ /// The response which has been generated by the server
+ void OnRequestHandled(IRequest request, IResponse response);
- ///
- /// Will be invoked after request has been handled by the server.
- ///
- /// The request which has been handled
- /// The response which has been generated by the server
- void OnRequestHandled(IRequest request, IResponse response);
-
- ///
- /// Will be invoked if an error occurred within the server engine.
- ///
- /// The scope of the error
- /// The endpoint of the client which caused this error (if any)
- /// The actual exception which occurred
- void OnServerError(ServerErrorScope scope, IPAddress? client, Exception error);
-
- }
+ ///
+ /// Will be invoked if an error occurred within the server engine.
+ ///
+ /// The scope of the error
+ /// The endpoint of the client which caused this error (if any)
+ /// The actual exception which occurred
+ void OnServerError(ServerErrorScope scope, IPAddress? client, Exception error);
-}
+}
\ No newline at end of file
diff --git a/API/Infrastructure/IServerHost.cs b/API/Infrastructure/IServerHost.cs
index a0faffc7..c1559d09 100644
--- a/API/Infrastructure/IServerHost.cs
+++ b/API/Infrastructure/IServerHost.cs
@@ -1,45 +1,42 @@
-namespace GenHTTP.Api.Infrastructure
+namespace GenHTTP.Api.Infrastructure;
+
+///
+/// Allows applications to manage the lifecycle of a server instance.
+///
+public interface IServerHost : IServerBuilder
{
///
- /// Allows applications to manage the lifecycle of a server instance.
+ /// The server instance maintained by the host, if started.
///
- public interface IServerHost : IServerBuilder
- {
-
- ///
- /// The server instance maintained by the host, if started.
- ///
- IServer? Instance { get; }
-
- ///
- /// Builds a server instance from the current configuration
- /// and starts it.
- ///
- IServerHost Start();
+ IServer? Instance { get; }
- ///
- /// Stops the currently running server instance, if any.
- ///
- IServerHost Stop();
+ ///
+ /// Builds a server instance from the current configuration
+ /// and starts it.
+ ///
+ IServerHost Start();
- ///
- /// Stops the currently running server instance and starts
- /// a new one.
- ///
- IServerHost Restart();
+ ///
+ /// Stops the currently running server instance, if any.
+ ///
+ IServerHost Stop();
- ///
- /// Builds a server instance from the current configuration
- /// and keeps it running until the application process exits.
- ///
- ///
- /// Convenience method that can be used as a one-liner by
- /// console or docker based applications.
- ///
- /// The return code to be passed to the operating system
- int Run();
+ ///
+ /// Stops the currently running server instance and starts
+ /// a new one.
+ ///
+ IServerHost Restart();
- }
+ ///
+ /// Builds a server instance from the current configuration
+ /// and keeps it running until the application process exits.
+ ///
+ ///
+ /// Convenience method that can be used as a one-liner by
+ /// console or docker based applications.
+ ///
+ /// The return code to be passed to the operating system
+ int Run();
}
diff --git a/API/Infrastructure/Priority.cs b/API/Infrastructure/Priority.cs
index b9aa0f7e..aeed3e9b 100644
--- a/API/Infrastructure/Priority.cs
+++ b/API/Infrastructure/Priority.cs
@@ -1,11 +1,8 @@
-namespace GenHTTP.Api.Infrastructure
-{
-
- public enum Priority
- {
- Low = 0,
- Medium = 50,
- High = 100
- }
+namespace GenHTTP.Api.Infrastructure;
+public enum Priority
+{
+ Low = 0,
+ Medium = 50,
+ High = 100
}
diff --git a/API/Infrastructure/PriorityEvaluation.cs b/API/Infrastructure/PriorityEvaluation.cs
index 9f5f3ce7..8a382ffd 100644
--- a/API/Infrastructure/PriorityEvaluation.cs
+++ b/API/Infrastructure/PriorityEvaluation.cs
@@ -1,8 +1,5 @@
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Api.Infrastructure
-{
+namespace GenHTTP.Api.Infrastructure;
- public delegate Priority PriorityEvaluation(IRequest request);
-
-}
+public delegate Priority PriorityEvaluation(IRequest request);
diff --git a/API/Infrastructure/SecureUpgrade.cs b/API/Infrastructure/SecureUpgrade.cs
index f2a2a298..1e03c211 100644
--- a/API/Infrastructure/SecureUpgrade.cs
+++ b/API/Infrastructure/SecureUpgrade.cs
@@ -1,31 +1,28 @@
-namespace GenHTTP.Api.Infrastructure
+namespace GenHTTP.Api.Infrastructure;
+
+///
+/// Specifies the strategy of the server to redirect
+/// unsecure requests to HTTPS secured endpoints.
+///
+public enum SecureUpgrade
{
///
- /// Specifies the strategy of the server to redirect
- /// unsecure requests to HTTPS secured endpoints.
+ /// The server will not attempt to upgrade requests.
///
- public enum SecureUpgrade
- {
-
- ///
- /// The server will not attempt to upgrade requests.
- ///
- None,
+ None,
- ///
- /// Clients may request an upgrade via the Upgrade-Insecure-Requests
- /// header. Aside from that, the server will not attempt to upgrade
- /// insecure requests.
- ///
- Allow,
-
- ///
- /// The server will always redirect requests to an insecure endpoint
- /// to the HTTPS secured one.
- ///
- Force
+ ///
+ /// Clients may request an upgrade via the Upgrade-Insecure-Requests
+ /// header. Aside from that, the server will not attempt to upgrade
+ /// insecure requests.
+ ///
+ Allow,
- }
+ ///
+ /// The server will always redirect requests to an insecure endpoint
+ /// to the HTTPS secured one.
+ ///
+ Force
}
diff --git a/API/Protocol/ClientProtocol.cs b/API/Protocol/ClientProtocol.cs
index 007bf14f..1a12f94c 100644
--- a/API/Protocol/ClientProtocol.cs
+++ b/API/Protocol/ClientProtocol.cs
@@ -1,10 +1,7 @@
-namespace GenHTTP.Api.Protocol
-{
-
- public enum ClientProtocol
- {
- HTTP,
- HTTPS
- }
+namespace GenHTTP.Api.Protocol;
-}
+public enum ClientProtocol
+{
+ HTTP,
+ HTTPS
+}
\ No newline at end of file
diff --git a/API/Protocol/ContentType.cs b/API/Protocol/ContentType.cs
index 08988cb8..05ac89c5 100644
--- a/API/Protocol/ContentType.cs
+++ b/API/Protocol/ContentType.cs
@@ -3,422 +3,421 @@
using System.Collections.Generic;
using System.Linq;
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+#region Known Types
+
+///
+/// The content type of the response.
+///
+public enum ContentType
{
- #region Known Types
+ ///
+ /// A html page.
+ ///
+ TextHtml,
///
- /// The content type of the response.
+ /// A stylesheet.
///
- public enum ContentType
- {
+ TextCss,
+
+ ///
+ /// A JavaScript source file.
+ ///
+ ApplicationJavaScript,
+
+ ///
+ /// A JSON file.
+ ///
+ ApplicationJson,
+
+ ///
+ /// A PNG image.
+ ///
+ ImagePng,
+
+ ///
+ /// A BMP image.
+ ///
+ ImageBmp,
+
+ ///
+ /// A JPG image.
+ ///
+ ImageJpg,
+
+ ///
+ /// A GIF image.
+ ///
+ ImageGif,
+
+ ///
+ /// A download.
+ ///
+ ApplicationForceDownload,
+
+ ///
+ /// Anything else - data.
+ ///
+ ApplicationOctetStream,
+
+ ///
+ /// A MP4 audio file.
+ ///
+ AudioMp4,
+
+ ///
+ /// A OGG audio file.
+ ///
+ AudioOgg,
- ///
- /// A html page.
- ///
- TextHtml,
-
- ///
- /// A stylesheet.
- ///
- TextCss,
-
- ///
- /// A JavaScript source file.
- ///
- ApplicationJavaScript,
-
- ///
- /// A JSON file.
- ///
- ApplicationJson,
-
- ///
- /// A PNG image.
- ///
- ImagePng,
-
- ///
- /// A BMP image.
- ///
- ImageBmp,
-
- ///
- /// A JPG image.
- ///
- ImageJpg,
-
- ///
- /// A GIF image.
- ///
- ImageGif,
-
- ///
- /// A download.
- ///
- ApplicationForceDownload,
-
- ///
- /// Anything else - data.
- ///
- ApplicationOctetStream,
-
- ///
- /// A MP4 audio file.
- ///
- AudioMp4,
-
- ///
- /// A OGG audio file.
- ///
- AudioOgg,
-
- ///
- /// A MPEG audio file.
- ///
- AudioMpeg,
-
- ///
- /// A TIFF image.
- ///
- ImageTiff,
-
- ///
- /// A CSV file.
- ///
- TextCsv,
-
- ///
- /// A RTF file.
- ///
- TextRichText,
-
- ///
- /// Plain text.
- ///
- TextPlain,
-
- ///
- /// A XML file.
- ///
- TextXml,
-
- ///
- /// A JavaScript file.
- ///
- TextJavaScript,
-
- ///
- /// A uncompressed audio file.
- ///
- AudioWav,
-
- ///
- /// Word processing document (e.g. docx).
- ///
- ApplicationOfficeDocumentWordProcessing,
-
- ///
- /// A presentation (e.g. pptx).
- ///
- ApplicationOfficeDocumentPresentation,
-
- ///
- /// A slideshow (e.g. .ppsx).
- ///
- ApplicationOfficeDocumentSlideshow,
-
- ///
- /// A sheet (e.g. .xlsx).
- ///
- ApplicationOfficeDocumentSheet,
-
- ///
- /// An icon.
- ///
- ImageIcon,
-
- ///
- /// Microsoft, embedded otf.
- ///
- FontEmbeddedOpenTypeFont,
-
- ///
- /// True type font (.ttf)
- ///
- FontTrueTypeFont,
-
- ///
- /// Woff font (.woff)
- ///
- FontWoff,
-
- ///
- /// Woff 2 font (.woff2)
- ///
- FontWoff2,
-
- ///
- /// Open type fonf (.otf)
- ///
- FontOpenTypeFont,
-
- ///
- /// Scalable Vector Graphics (.svg)
- ///
- ImageScalableVectorGraphics,
-
- ///
- /// Scalable Vector Graphics (.svg)
- ///
- ImageScalableVectorGraphicsXml,
-
- ///
- /// Scalable Vector Graphics (compressed, .svgz)
- ///
- ImageScalableVectorGraphicsCompressed,
-
- ///
- /// Url encoded form data.
- ///
- ApplicationWwwFormUrlEncoded,
-
- ///
- /// A Protobuf message.
- ///
- ApplicationProtobuf,
-
- ///
- /// 3GPP video file container (.3gp).
- ///
- Video3Gpp,
-
- ///
- /// 3GPP2 video files (.3g2).
- ///
- Video3Gpp2,
-
- ///
- /// AV1 video file (.av1).
- ///
- VideoAV1,
-
- ///
- /// A MPEG4 Part 10 (H.264) video file (.avc).
- ///
- VideoAvc,
-
- ///
- /// Digital video file (.dv).
- ///
- VideoDV,
-
- ///
- /// A H.261 video file.
- ///
- VideoH261,
-
- ///
- /// A H.263 video file.
- ///
- VideoH263,
-
- ///
- /// A H.264 encoded video file.
- ///
- VideoH264,
-
- ///
- /// A H.265 video file.
- ///
- VideoH265,
-
- ///
- /// A H.266 video file.
- ///
- VideoH266,
-
- ///
- /// A Matroska video file (.mkv).
- ///
- VideoMatroska,
-
- ///
- /// A 3D Matroska video file (.mk3d).
- ///
- VideoMatroska3D,
-
- ///
- /// A Motion JPEG 2000 video file (.mj2).
- ///
- VideoMJ2,
-
- ///
- /// A MP4 video file (.mp4).
- ///
- VideoMP4,
-
- ///
- /// A MPEG video file.
- ///
- VideoMpeg,
-
- ///
- /// A MPEG-4 video file.
- ///
- VideoMpeg4Generic,
-
- ///
- /// A MPEG-2 elementary stream video (.mpv).
- ///
- VideoMpv,
-
- ///
- /// An Apple quick time video file (.mov or .hdmov).
- ///
- VideoQuicktime,
-
- ///
- /// A raw video file.
- ///
- VideoRaw,
-
- ///
- /// A SMPTE 421M video file (.vc1).
- ///
- VideoVC1,
-
- ///
- /// A SMPTE VC-2 video file.
- ///
- VideoVC2,
-
- ///
- /// A VP8 encoded video file (.webm).
- ///
- VideoVP8,
-
- ///
- /// A VP9 encoded video file (.webm).
- ///
- VideoVP9,
-
- ///
- /// A WebM video file (.webm).
- ///
- VideoWebM
-
- }
+ ///
+ /// A MPEG audio file.
+ ///
+ AudioMpeg,
+
+ ///
+ /// A TIFF image.
+ ///
+ ImageTiff,
+
+ ///
+ /// A CSV file.
+ ///
+ TextCsv,
+
+ ///
+ /// A RTF file.
+ ///
+ TextRichText,
+
+ ///
+ /// Plain text.
+ ///
+ TextPlain,
+
+ ///
+ /// A XML file.
+ ///
+ TextXml,
+
+ ///
+ /// A JavaScript file.
+ ///
+ TextJavaScript,
+
+ ///
+ /// A uncompressed audio file.
+ ///
+ AudioWav,
+
+ ///
+ /// Word processing document (e.g. docx).
+ ///
+ ApplicationOfficeDocumentWordProcessing,
+
+ ///
+ /// A presentation (e.g. pptx).
+ ///
+ ApplicationOfficeDocumentPresentation,
+
+ ///
+ /// A slideshow (e.g. .ppsx).
+ ///
+ ApplicationOfficeDocumentSlideshow,
+
+ ///
+ /// A sheet (e.g. .xlsx).
+ ///
+ ApplicationOfficeDocumentSheet,
+
+ ///
+ /// An icon.
+ ///
+ ImageIcon,
+
+ ///
+ /// Microsoft, embedded otf.
+ ///
+ FontEmbeddedOpenTypeFont,
+
+ ///
+ /// True type font (.ttf)
+ ///
+ FontTrueTypeFont,
+
+ ///
+ /// Woff font (.woff)
+ ///
+ FontWoff,
+
+ ///
+ /// Woff 2 font (.woff2)
+ ///
+ FontWoff2,
+
+ ///
+ /// Open type fonf (.otf)
+ ///
+ FontOpenTypeFont,
+
+ ///
+ /// Scalable Vector Graphics (.svg)
+ ///
+ ImageScalableVectorGraphics,
+
+ ///
+ /// Scalable Vector Graphics (.svg)
+ ///
+ ImageScalableVectorGraphicsXml,
+
+ ///
+ /// Scalable Vector Graphics (compressed, .svgz)
+ ///
+ ImageScalableVectorGraphicsCompressed,
+
+ ///
+ /// Url encoded form data.
+ ///
+ ApplicationWwwFormUrlEncoded,
+
+ ///
+ /// A Protobuf message.
+ ///
+ ApplicationProtobuf,
+
+ ///
+ /// 3GPP video file container (.3gp).
+ ///
+ Video3Gpp,
+
+ ///
+ /// 3GPP2 video files (.3g2).
+ ///
+ Video3Gpp2,
+
+ ///
+ /// AV1 video file (.av1).
+ ///
+ VideoAV1,
+
+ ///
+ /// A MPEG4 Part 10 (H.264) video file (.avc).
+ ///
+ VideoAvc,
+
+ ///
+ /// Digital video file (.dv).
+ ///
+ VideoDV,
+
+ ///
+ /// A H.261 video file.
+ ///
+ VideoH261,
+
+ ///
+ /// A H.263 video file.
+ ///
+ VideoH263,
+
+ ///
+ /// A H.264 encoded video file.
+ ///
+ VideoH264,
+
+ ///
+ /// A H.265 video file.
+ ///
+ VideoH265,
+
+ ///
+ /// A H.266 video file.
+ ///
+ VideoH266,
+
+ ///
+ /// A Matroska video file (.mkv).
+ ///
+ VideoMatroska,
+
+ ///
+ /// A 3D Matroska video file (.mk3d).
+ ///
+ VideoMatroska3D,
+
+ ///
+ /// A Motion JPEG 2000 video file (.mj2).
+ ///
+ VideoMJ2,
+
+ ///
+ /// A MP4 video file (.mp4).
+ ///
+ VideoMP4,
+
+ ///
+ /// A MPEG video file.
+ ///
+ VideoMpeg,
+
+ ///
+ /// A MPEG-4 video file.
+ ///
+ VideoMpeg4Generic,
+
+ ///
+ /// A MPEG-2 elementary stream video (.mpv).
+ ///
+ VideoMpv,
+
+ ///
+ /// An Apple quick time video file (.mov or .hdmov).
+ ///
+ VideoQuicktime,
+
+ ///
+ /// A raw video file.
+ ///
+ VideoRaw,
+
+ ///
+ /// A SMPTE 421M video file (.vc1).
+ ///
+ VideoVC1,
+
+ ///
+ /// A SMPTE VC-2 video file.
+ ///
+ VideoVC2,
+
+ ///
+ /// A VP8 encoded video file (.webm).
+ ///
+ VideoVP8,
+
+ ///
+ /// A VP9 encoded video file (.webm).
+ ///
+ VideoVP9,
+
+ ///
+ /// A WebM video file (.webm).
+ ///
+ VideoWebM
+
+}
+
+#endregion
+
+///
+/// The type of content which is sent to or received from a client.
+///
+public class FlexibleContentType
+{
+ private static readonly ConcurrentDictionary _RawCache = new(StringComparer.InvariantCultureIgnoreCase);
+
+ private static readonly Dictionary _KnownCache = new();
+
+ #region Get-/Setters
+
+ ///
+ /// The known, enumerated type, if any.
+ ///
+ public ContentType? KnownType { get; }
+
+ ///
+ /// The raw type.
+ ///
+ public string RawType { get; }
+
+ ///
+ /// The charset of the content, if any.
+ ///
+ public string? Charset { get; }
#endregion
+ #region Mapping
+
+ private static readonly Dictionary MAPPING = new()
+ {
+ { ContentType.AudioMp4, "audio/mp4" },
+ { ContentType.AudioOgg, "audio/ogg" },
+ { ContentType.AudioMpeg, "audio/mpeg" },
+ { ContentType.AudioWav, "audio/wav" },
+ { ContentType.ApplicationJavaScript, "application/javascript" },
+ { ContentType.ApplicationOfficeDocumentWordProcessing, "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
+ { ContentType.ApplicationOfficeDocumentPresentation, "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
+ { ContentType.ApplicationOfficeDocumentSlideshow, "application/vnd.openxmlformats-officedocument.presentationml.slideshow" },
+ { ContentType.ApplicationOfficeDocumentSheet, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
+ { ContentType.ApplicationForceDownload, "application/force-download" },
+ { ContentType.ApplicationOctetStream, "application/octet-stream" },
+ { ContentType.ApplicationJson, "application/json" },
+ { ContentType.ApplicationWwwFormUrlEncoded, "application/x-www-form-urlencoded" },
+ { ContentType.ApplicationProtobuf, "application/protobuf" },
+ { ContentType.FontEmbeddedOpenTypeFont, "font/eot" },
+ { ContentType.FontOpenTypeFont, "font/otf" },
+ { ContentType.FontTrueTypeFont, "font/ttf" },
+ { ContentType.FontWoff, "font/woff" },
+ { ContentType.FontWoff2, "font/woff2" },
+ { ContentType.ImageIcon, "image/x-icon" },
+ { ContentType.ImageGif, "image/gif" },
+ { ContentType.ImageJpg, "image/jpg" },
+ { ContentType.ImagePng, "image/png" },
+ { ContentType.ImageTiff, "image/tiff" },
+ { ContentType.ImageBmp, "image/bmp" },
+ { ContentType.ImageScalableVectorGraphics, "image/svg" },
+ { ContentType.ImageScalableVectorGraphicsXml, "image/svg+xml" },
+ { ContentType.ImageScalableVectorGraphicsCompressed, "image/svgz" },
+ { ContentType.TextHtml, "text/html" },
+ { ContentType.TextCss, "text/css" },
+ { ContentType.TextCsv, "text/csv" },
+ { ContentType.TextRichText, "text/richtext" },
+ { ContentType.TextPlain, "text/plain" },
+ { ContentType.TextJavaScript, "text/javascript" },
+ { ContentType.TextXml, "text/xml" },
+ { ContentType.Video3Gpp, "video/3gpp" },
+ { ContentType.Video3Gpp2, "video/3gpp2" },
+ { ContentType.VideoAV1, "video/av1" },
+ { ContentType.VideoAvc, "video/av" },
+ { ContentType.VideoDV, "video/dv" },
+ { ContentType.VideoH261, "video/H261" },
+ { ContentType.VideoH263, "video/H263" },
+ { ContentType.VideoH264, "video/H264" },
+ { ContentType.VideoH265, "video/H265" },
+ { ContentType.VideoH266, "video/H266" },
+ { ContentType.VideoMatroska, "video/matroska" },
+ { ContentType.VideoMatroska3D, "video/matroska-3d" },
+ { ContentType.VideoMJ2, "video/mj2" },
+ { ContentType.VideoMP4, "video/mp4" },
+ { ContentType.VideoMpeg, "video/mpeg" },
+ { ContentType.VideoMpeg4Generic, "video/mpeg4-generic" },
+ { ContentType.VideoMpv, "video/MPV" },
+ { ContentType.VideoQuicktime, "video/quicktime" },
+ { ContentType.VideoRaw, "video/raw" },
+ { ContentType.VideoVC1, "video/vc1" },
+ { ContentType.VideoVC2, "video/vc2" },
+ { ContentType.VideoVP8, "video/VP8" },
+ { ContentType.VideoVP9, "video/VP9" },
+ { ContentType.VideoWebM, "video/webm" }
+ };
+
+ private static readonly Dictionary MAPPING_REVERSE = MAPPING.ToDictionary(x => x.Value, x => x.Key);
+
+ #endregion
+
+ #region Initialization
+
///
- /// The type of content which is sent to or received from a client.
+ /// Create a new content type from the given string.
///
- public class FlexibleContentType
+ /// The string representation of the content type
+ /// The charset of the content, if known
+ public FlexibleContentType(string rawType, string? charset = null)
{
- private static readonly ConcurrentDictionary _RawCache = new(StringComparer.InvariantCultureIgnoreCase);
-
- private static readonly Dictionary _KnownCache = new();
-
- #region Get-/Setters
-
- ///
- /// The known, enumerated type, if any.
- ///
- public ContentType? KnownType { get; }
-
- ///
- /// The raw type.
- ///
- public string RawType { get; }
-
- ///
- /// The charset of the content, if any.
- ///
- public string? Charset { get; }
-
- #endregion
-
- #region Mapping
-
- private static readonly Dictionary MAPPING = new()
- {
- { ContentType.AudioMp4, "audio/mp4" },
- { ContentType.AudioOgg, "audio/ogg" },
- { ContentType.AudioMpeg, "audio/mpeg" },
- { ContentType.AudioWav, "audio/wav" },
- { ContentType.ApplicationJavaScript, "application/javascript" },
- { ContentType.ApplicationOfficeDocumentWordProcessing, "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
- { ContentType.ApplicationOfficeDocumentPresentation, "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
- { ContentType.ApplicationOfficeDocumentSlideshow, "application/vnd.openxmlformats-officedocument.presentationml.slideshow" },
- { ContentType.ApplicationOfficeDocumentSheet, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
- { ContentType.ApplicationForceDownload, "application/force-download" },
- { ContentType.ApplicationOctetStream, "application/octet-stream" },
- { ContentType.ApplicationJson, "application/json" },
- { ContentType.ApplicationWwwFormUrlEncoded, "application/x-www-form-urlencoded" },
- { ContentType.ApplicationProtobuf, "application/protobuf" },
- { ContentType.FontEmbeddedOpenTypeFont, "font/eot" },
- { ContentType.FontOpenTypeFont, "font/otf" },
- { ContentType.FontTrueTypeFont, "font/ttf" },
- { ContentType.FontWoff, "font/woff" },
- { ContentType.FontWoff2, "font/woff2" },
- { ContentType.ImageIcon, "image/x-icon" },
- { ContentType.ImageGif, "image/gif" },
- { ContentType.ImageJpg, "image/jpg" },
- { ContentType.ImagePng, "image/png" },
- { ContentType.ImageTiff, "image/tiff" },
- { ContentType.ImageBmp, "image/bmp" },
- { ContentType.ImageScalableVectorGraphics, "image/svg" },
- { ContentType.ImageScalableVectorGraphicsXml, "image/svg+xml" },
- { ContentType.ImageScalableVectorGraphicsCompressed, "image/svgz" },
- { ContentType.TextHtml, "text/html" },
- { ContentType.TextCss, "text/css" },
- { ContentType.TextCsv, "text/csv" },
- { ContentType.TextRichText, "text/richtext" },
- { ContentType.TextPlain, "text/plain" },
- { ContentType.TextJavaScript, "text/javascript" },
- { ContentType.TextXml, "text/xml" },
- { ContentType.Video3Gpp, "video/3gpp" },
- { ContentType.Video3Gpp2, "video/3gpp2" },
- { ContentType.VideoAV1, "video/av1" },
- { ContentType.VideoAvc, "video/av" },
- { ContentType.VideoDV, "video/dv" },
- { ContentType.VideoH261, "video/H261" },
- { ContentType.VideoH263, "video/H263" },
- { ContentType.VideoH264, "video/H264" },
- { ContentType.VideoH265, "video/H265" },
- { ContentType.VideoH266, "video/H266" },
- { ContentType.VideoMatroska, "video/matroska" },
- { ContentType.VideoMatroska3D, "video/matroska-3d" },
- { ContentType.VideoMJ2, "video/mj2" },
- { ContentType.VideoMP4, "video/mp4" },
- { ContentType.VideoMpeg, "video/mpeg" },
- { ContentType.VideoMpeg4Generic, "video/mpeg4-generic" },
- { ContentType.VideoMpv, "video/MPV" },
- { ContentType.VideoQuicktime, "video/quicktime" },
- { ContentType.VideoRaw, "video/raw" },
- { ContentType.VideoVC1, "video/vc1" },
- { ContentType.VideoVC2, "video/vc2" },
- { ContentType.VideoVP8, "video/VP8" },
- { ContentType.VideoVP9, "video/VP9" },
- { ContentType.VideoWebM, "video/webm" }
- };
-
- private static readonly Dictionary MAPPING_REVERSE = MAPPING.ToDictionary(x => x.Value, x => x.Key);
-
- #endregion
-
- #region Initialization
-
- ///
- /// Create a new content type from the given string.
- ///
- /// The string representation of the content type
- /// The charset of the content, if known
- public FlexibleContentType(string rawType, string? charset = null)
- {
RawType = rawType;
Charset = charset;
@@ -432,30 +431,30 @@ public FlexibleContentType(string rawType, string? charset = null)
}
}
- ///
- /// Create a new content type from the given known type.
- ///
- /// The known type
- /// The charset of the content, if known
- public FlexibleContentType(ContentType type, string? charset = null)
- {
+ ///
+ /// Create a new content type from the given known type.
+ ///
+ /// The known type
+ /// The charset of the content, if known
+ public FlexibleContentType(ContentType type, string? charset = null)
+ {
KnownType = type;
RawType = MAPPING[type];
Charset = charset;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- ///
- /// Fetches a cached instance for the given content type.
- ///
- /// The raw string to be resolved
- /// The content type instance to be used
- public static FlexibleContentType Get(string rawType, string? charset = null)
- {
+ ///
+ /// Fetches a cached instance for the given content type.
+ ///
+ /// The raw string to be resolved
+ /// The content type instance to be used
+ public static FlexibleContentType Get(string rawType, string? charset = null)
+ {
if (charset is not null)
{
return new(rawType, charset);
@@ -473,13 +472,13 @@ public static FlexibleContentType Get(string rawType, string? charset = null)
return type;
}
- ///
- /// Fetches a cached instance for the given content type.
- ///
- /// The known type to be resolved
- /// The content type instance to be used
- public static FlexibleContentType Get(ContentType knownType, string? charset = null)
- {
+ ///
+ /// Fetches a cached instance for the given content type.
+ ///
+ /// The known type to be resolved
+ /// The content type instance to be used
+ public static FlexibleContentType Get(ContentType knownType, string? charset = null)
+ {
if (charset is not null)
{
return new(knownType, charset);
@@ -497,13 +496,13 @@ public static FlexibleContentType Get(ContentType knownType, string? charset = n
return type;
}
- ///
- /// Parses the given header value into a content type structure.
- ///
- /// The header to be parsed
- /// The parsed content type
- public static FlexibleContentType Parse(string header)
- {
+ ///
+ /// Parses the given header value into a content type structure.
+ ///
+ /// The header to be parsed
+ /// The parsed content type
+ public static FlexibleContentType Parse(string header)
+ {
var span = header.AsSpan();
var index = span.IndexOf(';');
@@ -529,24 +528,22 @@ public static FlexibleContentType Parse(string header)
}
}
- #endregion
-
- #region Convenience
+ #endregion
- public static bool operator ==(FlexibleContentType type, ContentType knownType) => type.KnownType == knownType;
+ #region Convenience
- public static bool operator !=(FlexibleContentType type, ContentType knownType) => type.KnownType != knownType;
+ public static bool operator ==(FlexibleContentType type, ContentType knownType) => type.KnownType == knownType;
- public static bool operator ==(FlexibleContentType type, string rawType) => type.RawType == rawType;
+ public static bool operator !=(FlexibleContentType type, ContentType knownType) => type.KnownType != knownType;
- public static bool operator !=(FlexibleContentType type, string rawType) => type.RawType != rawType;
+ public static bool operator ==(FlexibleContentType type, string rawType) => type.RawType == rawType;
- public override bool Equals(object? obj) => obj is FlexibleContentType type && RawType == type.RawType;
+ public static bool operator !=(FlexibleContentType type, string rawType) => type.RawType != rawType;
- public override int GetHashCode() => RawType.GetHashCode();
+ public override bool Equals(object? obj) => obj is FlexibleContentType type && RawType == type.RawType;
- #endregion
+ public override int GetHashCode() => RawType.GetHashCode();
- }
+ #endregion
}
diff --git a/API/Protocol/Cookie.cs b/API/Protocol/Cookie.cs
index b1e5bfb4..c1e1379d 100644
--- a/API/Protocol/Cookie.cs
+++ b/API/Protocol/Cookie.cs
@@ -1,59 +1,56 @@
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+///
+/// Represents a cookie that can be send to or received from a client.
+///
+public struct Cookie
{
+ #region Get-/Setters
+
///
- /// Represents a cookie that can be send to or received from a client.
+ /// The name of the cookie.
///
- public struct Cookie
- {
-
- #region Get-/Setters
+ public string Name { get; }
- ///
- /// The name of the cookie.
- ///
- public string Name { get; }
-
- ///
- /// The value of the cookie.
- ///
- public string Value { get; set; }
+ ///
+ /// The value of the cookie.
+ ///
+ public string Value { get; set; }
- ///
- /// The number of seconds after the cookie will be discarded by the client.
- ///
- public ulong? MaxAge { get; set; }
+ ///
+ /// The number of seconds after the cookie will be discarded by the client.
+ ///
+ public ulong? MaxAge { get; set; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- ///
- /// Creates a new cookie with the given name and value.
- ///
- /// The name of the cookie
- /// The value of the cookie
- public Cookie(string name, string value)
- {
+ ///
+ /// Creates a new cookie with the given name and value.
+ ///
+ /// The name of the cookie
+ /// The value of the cookie
+ public Cookie(string name, string value)
+ {
Name = name;
Value = value;
MaxAge = null;
}
- ///
- /// Creates a new cookie with the given name and value.
- ///
- /// The name of the cookie
- /// The value of the cookie
- /// The number of seconds until the cookie will be discarded
- public Cookie(string name, string value, ulong maxAge) : this(name, value)
- {
+ ///
+ /// Creates a new cookie with the given name and value.
+ ///
+ /// The name of the cookie
+ /// The value of the cookie
+ /// The number of seconds until the cookie will be discarded
+ public Cookie(string name, string value, ulong maxAge) : this(name, value)
+ {
MaxAge = maxAge;
}
- #endregion
-
- }
+ #endregion
}
diff --git a/API/Protocol/Forwarding.cs b/API/Protocol/Forwarding.cs
index f6ba38a2..469167cc 100644
--- a/API/Protocol/Forwarding.cs
+++ b/API/Protocol/Forwarding.cs
@@ -1,12 +1,9 @@
using System.Net;
-namespace GenHTTP.Api.Protocol
-{
+namespace GenHTTP.Api.Protocol;
- ///
- /// Stores information how a request has been proxied
- /// to the server.
- ///
- public record Forwarding(IPAddress? For, string? Host, ClientProtocol? Protocol);
-
-}
+///
+/// Stores information how a request has been proxied
+/// to the server.
+///
+public record Forwarding(IPAddress? For, string? Host, ClientProtocol? Protocol);
diff --git a/API/Protocol/HttpProtocol.cs b/API/Protocol/HttpProtocol.cs
index fc0eb2da..ec9c6018 100644
--- a/API/Protocol/HttpProtocol.cs
+++ b/API/Protocol/HttpProtocol.cs
@@ -1,19 +1,16 @@
-namespace GenHTTP.Api.Protocol
-{
+namespace GenHTTP.Api.Protocol;
+///
+/// The type of protocol to use for the response.
+///
+public enum HttpProtocol
+{
///
- /// The type of protocol to use for the response.
+ /// HTTP/1.0
///
- public enum HttpProtocol
- {
- ///
- /// HTTP/1.0
- ///
- Http_1_0,
- ///
- /// HTTP/1.1
- ///
- Http_1_1
- }
-
+ Http_1_0,
+ ///
+ /// HTTP/1.1
+ ///
+ Http_1_1
}
diff --git a/API/Protocol/ICookieCollection.cs b/API/Protocol/ICookieCollection.cs
index a21885ce..a343dc0a 100644
--- a/API/Protocol/ICookieCollection.cs
+++ b/API/Protocol/ICookieCollection.cs
@@ -1,16 +1,13 @@
using System;
using System.Collections.Generic;
-namespace GenHTTP.Api.Protocol
-{
-
- ///
- /// A collection representing the cookies of an
- /// or .
- ///
- public interface ICookieCollection : IReadOnlyDictionary, IDisposable
- {
+namespace GenHTTP.Api.Protocol;
- }
+///
+/// A collection representing the cookies of an
+/// or .
+///
+public interface ICookieCollection : IReadOnlyDictionary, IDisposable
+{
}
diff --git a/API/Protocol/IEditableHeaderCollection.cs b/API/Protocol/IEditableHeaderCollection.cs
index ff6c9e5f..3fba3c0e 100644
--- a/API/Protocol/IEditableHeaderCollection.cs
+++ b/API/Protocol/IEditableHeaderCollection.cs
@@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
-namespace GenHTTP.Api.Protocol
-{
-
- public interface IEditableHeaderCollection : IDictionary, IDisposable
- {
+namespace GenHTTP.Api.Protocol;
- }
+public interface IEditableHeaderCollection : IDictionary, IDisposable
+{
-}
+}
\ No newline at end of file
diff --git a/API/Protocol/IForwardingCollection.cs b/API/Protocol/IForwardingCollection.cs
index 4e2a39bf..51c32351 100644
--- a/API/Protocol/IForwardingCollection.cs
+++ b/API/Protocol/IForwardingCollection.cs
@@ -1,11 +1,8 @@
using System.Collections.Generic;
-namespace GenHTTP.Api.Protocol
-{
-
- public interface IForwardingCollection : IList
- {
+namespace GenHTTP.Api.Protocol;
- }
+public interface IForwardingCollection : IList
+{
}
diff --git a/API/Protocol/IHeaderCollection.cs b/API/Protocol/IHeaderCollection.cs
index 29865665..d4b05466 100644
--- a/API/Protocol/IHeaderCollection.cs
+++ b/API/Protocol/IHeaderCollection.cs
@@ -1,15 +1,12 @@
using System;
using System.Collections.Generic;
-namespace GenHTTP.Api.Protocol
-{
-
- ///
- /// The headers of an or .
- ///
- public interface IHeaderCollection : IReadOnlyDictionary, IDisposable
- {
+namespace GenHTTP.Api.Protocol;
- }
+///
+/// The headers of an or .
+///
+public interface IHeaderCollection : IReadOnlyDictionary, IDisposable
+{
}
diff --git a/API/Protocol/IRequest.cs b/API/Protocol/IRequest.cs
index 3be74196..c487dbdc 100644
--- a/API/Protocol/IRequest.cs
+++ b/API/Protocol/IRequest.cs
@@ -4,148 +4,145 @@
using GenHTTP.Api.Infrastructure;
using GenHTTP.Api.Routing;
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+///
+/// A request send by the currently connected client.
+///
+public interface IRequest : IDisposable
{
+ #region General Infrastructure
+
+ ///
+ /// The server handling the request.
+ ///
+ IServer Server { get; }
+
+ ///
+ /// The endpoint the request originates from.
+ ///
+ IEndPoint EndPoint { get; }
+
+ ///
+ /// The client which sent the request.
+ ///
+ IClientConnection Client { get; }
+
+ ///
+ /// If the request has been forwarded by a proxy, the client property
+ /// will return the originating client where this property will return
+ /// the information of the proxy.
+ ///
+ IClientConnection LocalClient { get; }
+
+ #endregion
+
+ #region HTTP Protocol
+
+ ///
+ /// The requested protocol type.
+ ///
+ HttpProtocol ProtocolType { get; }
+
+ ///
+ /// The HTTP method used by the client to issue this request.
+ ///
+ FlexibleRequestMethod Method { get; }
+
+ ///
+ /// The path requested by the client (with no query parameters attached).
+ ///
+ RoutingTarget Target { get; }
+
+ #endregion
+
+ #region Headers
+
///
- /// A request send by the currently connected client.
- ///
- public interface IRequest : IDisposable
- {
+ /// The user agent which issued this request, if any.
+ ///
+ string? UserAgent { get; }
- #region General Infrastructure
-
- ///
- /// The server handling the request.
- ///
- IServer Server { get; }
-
- ///
- /// The endpoint the request originates from.
- ///
- IEndPoint EndPoint { get; }
+ ///
+ /// The referrer which caused the invociation of this request, if any.
+ ///
+ string? Referer { get; }
- ///
- /// The client which sent the request.
- ///
- IClientConnection Client { get; }
-
- ///
- /// If the request has been forwarded by a proxy, the client property
- /// will return the originating client where this property will return
- /// the information of the proxy.
- ///
- IClientConnection LocalClient { get; }
+ ///
+ /// The host requested by the client, if any.
+ ///
+ string? Host { get; }
- #endregion
+ ///
+ /// Read an additional header value from the request.
+ ///
+ /// The name of the header field to be read
+ /// The value of the header field, if specified by the client
+ string? this[string additionalHeader] { get; }
- #region HTTP Protocol
+ ///
+ /// The query parameters passed by the client.
+ ///
+ IRequestQuery Query { get; }
- ///
- /// The requested protocol type.
- ///
- HttpProtocol ProtocolType { get; }
+ ///
+ /// The cookies passed by the client.
+ ///
+ ICookieCollection Cookies { get; }
- ///
- /// The HTTP method used by the client to issue this request.
- ///
- FlexibleRequestMethod Method { get; }
+ ///
+ /// If the request has been forwarded by one or more proxies, this collection may contain
+ /// additional information about the initial request by the originating client.
+ ///
+ ///
+ /// Use to quickly access the requesting client without the need
+ /// of scrolling through the forwardings.
+ ///
+ IForwardingCollection Forwardings { get; }
- ///
- /// The path requested by the client (with no query parameters attached).
- ///
- RoutingTarget Target { get; }
+ ///
+ /// The headers of this HTTP request.
+ ///
+ IHeaderCollection Headers { get; }
- #endregion
+ #endregion
- #region Headers
+ #region Body
- ///
- /// The user agent which issued this request, if any.
- ///
- string? UserAgent { get; }
+ ///
+ /// The content transmitted by the client, if any.
+ ///
+ Stream? Content { get; }
- ///
- /// The referrer which caused the invociation of this request, if any.
- ///
- string? Referer { get; }
+ ///
+ /// The type of content transmitted by the client, if any.
+ ///
+ FlexibleContentType? ContentType { get; }
- ///
- /// The host requested by the client, if any.
- ///
- string? Host { get; }
+ #endregion
- ///
- /// Read an additional header value from the request.
- ///
- /// The name of the header field to be read
- /// The value of the header field, if specified by the client
- string? this[string additionalHeader] { get; }
+ #region Functionality
- ///
- /// The query parameters passed by the client.
- ///
- IRequestQuery Query { get; }
+ ///
+ /// Generates a new response for this request to be send to the client.
+ ///
+ /// The newly created response
+ IResponseBuilder Respond();
- ///
- /// The cookies passed by the client.
- ///
- ICookieCollection Cookies { get; }
+ #endregion
- ///
- /// If the request has been forwarded by one or more proxies, this collection may contain
- /// additional information about the initial request by the originating client.
- ///
- ///
- /// Use to quickly access the requesting client without the need
- /// of scrolling through the forwardings.
- ///
- IForwardingCollection Forwardings { get; }
+ #region Extensibility
- ///
- /// The headers of this HTTP request.
- ///
- IHeaderCollection Headers { get; }
+ ///
+ /// Additional properties that have been attached to the request.
+ ///
+ ///
+ /// Can be used to store additional state on request level if needed.
+ /// Should be avoided in favor of more strict coupling.
+ ///
+ IRequestProperties Properties { get; }
- #endregion
-
- #region Body
-
- ///
- /// The content transmitted by the client, if any.
- ///
- Stream? Content { get; }
-
- ///
- /// The type of content transmitted by the client, if any.
- ///
- FlexibleContentType? ContentType { get; }
-
- #endregion
-
- #region Functionality
-
- ///
- /// Generates a new response for this request to be send to the client.
- ///
- /// The newly created response
- IResponseBuilder Respond();
-
- #endregion
-
- #region Extensibility
-
- ///
- /// Additional properties that have been attached to the request.
- ///
- ///
- /// Can be used to store additional state on request level if needed.
- /// Should be avoided in favor of more strict coupling.
- ///
- IRequestProperties Properties { get; }
-
- #endregion
-
- }
+ #endregion
}
diff --git a/API/Protocol/IRequestProperties.cs b/API/Protocol/IRequestProperties.cs
index aeb7e636..233d9cde 100644
--- a/API/Protocol/IRequestProperties.cs
+++ b/API/Protocol/IRequestProperties.cs
@@ -1,39 +1,36 @@
using System;
using System.Diagnostics.CodeAnalysis;
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+///
+/// Property bag to store additional data within the
+/// currently running request context.
+///
+public interface IRequestProperties : IDisposable
{
///
- /// Property bag to store additional data within the
- /// currently running request context.
+ /// Accesses a value that is stored within
+ /// the property bag.
///
- public interface IRequestProperties : IDisposable
- {
-
- ///
- /// Accesses a value that is stored within
- /// the property bag.
- ///
- /// The key of the item to be fetched
- /// Thrown if the given key is not present
- object this[string key] { get; set; }
+ /// The key of the item to be fetched
+ /// Thrown if the given key is not present
+ object this[string key] { get; set; }
- ///
- /// Attempts to fetch the typed value for the given key from the property bag.
- ///
- /// The key of the value to be fetched
- /// The entry read from the property bag, if any
- /// The expected type of value to be returned
- /// True if the value could be read, false otherwise
- bool TryGet(string key, [MaybeNullWhen(returnValue: false)] out T entry);
-
- ///
- /// Removes the entry with the given name.
- ///
- /// The entry to be removed
- void Clear(string key);
+ ///
+ /// Attempts to fetch the typed value for the given key from the property bag.
+ ///
+ /// The key of the value to be fetched
+ /// The entry read from the property bag, if any
+ /// The expected type of value to be returned
+ /// True if the value could be read, false otherwise
+ bool TryGet(string key, [MaybeNullWhen(returnValue: false)] out T entry);
- }
+ ///
+ /// Removes the entry with the given name.
+ ///
+ /// The entry to be removed
+ void Clear(string key);
-}
+}
\ No newline at end of file
diff --git a/API/Protocol/IRequestQuery.cs b/API/Protocol/IRequestQuery.cs
index 4a6e2699..31770b36 100644
--- a/API/Protocol/IRequestQuery.cs
+++ b/API/Protocol/IRequestQuery.cs
@@ -1,15 +1,12 @@
using System;
using System.Collections.Generic;
-namespace GenHTTP.Api.Protocol
-{
-
- ///
- /// Stores the query sent by the client.
- ///
- public interface IRequestQuery : IReadOnlyDictionary, IDisposable
- {
+namespace GenHTTP.Api.Protocol;
- }
+///
+/// Stores the query sent by the client.
+///
+public interface IRequestQuery : IReadOnlyDictionary, IDisposable
+{
}
diff --git a/API/Protocol/IResponse.cs b/API/Protocol/IResponse.cs
index 08f47eef..ebf946bc 100644
--- a/API/Protocol/IResponse.cs
+++ b/API/Protocol/IResponse.cs
@@ -1,89 +1,86 @@
using System;
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+///
+/// The response to be send to the connected client for a given request.
+///
+public interface IResponse : IDisposable
{
+ #region Protocol
+
///
- /// The response to be send to the connected client for a given request.
+ /// The HTTP response code.
///
- public interface IResponse : IDisposable
- {
-
- #region Protocol
-
- ///
- /// The HTTP response code.
- ///
- FlexibleResponseStatus Status { get; set; }
+ FlexibleResponseStatus Status { get; set; }
- #endregion
+ #endregion
- #region Headers
+ #region Headers
- ///
- /// Define, when this resource will expire.
- ///
- DateTime? Expires { get; set; }
-
- ///
- /// Define, when this ressource has been changed the last time.
- ///
- DateTime? Modified { get; set; }
+ ///
+ /// Define, when this resource will expire.
+ ///
+ DateTime? Expires { get; set; }
- ///
- /// Retrieve or set the value of a header field.
- ///
- /// The name of the header field
- /// The value of the header field
- string? this[string field] { get; set; }
+ ///
+ /// Define, when this ressource has been changed the last time.
+ ///
+ DateTime? Modified { get; set; }
- ///
- /// The headers of the HTTP response.
- ///
- IEditableHeaderCollection Headers { get; }
+ ///
+ /// Retrieve or set the value of a header field.
+ ///
+ /// The name of the header field
+ /// The value of the header field
+ string? this[string field] { get; set; }
- ///
- /// The cookies to be sent to the client.
- ///
- ICookieCollection Cookies { get; }
+ ///
+ /// The headers of the HTTP response.
+ ///
+ IEditableHeaderCollection Headers { get; }
- ///
- /// True, if there are cookies to be sent with this respone.
- ///
- bool HasCookies { get; }
+ ///
+ /// The cookies to be sent to the client.
+ ///
+ ICookieCollection Cookies { get; }
- ///
- /// Adds the given cookie to the cookie collection of this response.
- ///
- /// The cookie to be added
- void SetCookie(Cookie cookie);
+ ///
+ /// True, if there are cookies to be sent with this respone.
+ ///
+ bool HasCookies { get; }
- #endregion
+ ///
+ /// Adds the given cookie to the cookie collection of this response.
+ ///
+ /// The cookie to be added
+ void SetCookie(Cookie cookie);
- #region Content
+ #endregion
- ///
- /// The type of the content.
- ///
- FlexibleContentType? ContentType { get; set; }
+ #region Content
- ///
- /// The encoding of the content (e.g. "br").
- ///
- string? ContentEncoding { get; set; }
+ ///
+ /// The type of the content.
+ ///
+ FlexibleContentType? ContentType { get; set; }
- ///
- /// The number of bytes the content consists of.
- ///
- ulong? ContentLength { get; set; }
+ ///
+ /// The encoding of the content (e.g. "br").
+ ///
+ string? ContentEncoding { get; set; }
- ///
- /// The response that will be sent to the requesting client.
- ///
- IResponseContent? Content { get; set; }
+ ///
+ /// The number of bytes the content consists of.
+ ///
+ ulong? ContentLength { get; set; }
- #endregion
+ ///
+ /// The response that will be sent to the requesting client.
+ ///
+ IResponseContent? Content { get; set; }
- }
+ #endregion
}
diff --git a/API/Protocol/IResponseBuilder.cs b/API/Protocol/IResponseBuilder.cs
index 566d73fa..26222344 100644
--- a/API/Protocol/IResponseBuilder.cs
+++ b/API/Protocol/IResponseBuilder.cs
@@ -1,26 +1,23 @@
using GenHTTP.Api.Infrastructure;
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+///
+/// Allows to configure a HTTP response to be send.
+///
+public interface IResponseBuilder : IBuilder, IResponseModification
{
///
- /// Allows to configure a HTTP response to be send.
+ /// Specifies the content to be sent to the client.
///
- public interface IResponseBuilder : IBuilder, IResponseModification
- {
-
- ///
- /// Specifies the content to be sent to the client.
- ///
- /// The content to be send to the client
- IResponseBuilder Content(IResponseContent content);
-
- ///
- /// Specifies the length of the content stream, if known.
- ///
- /// The length of the content stream
- IResponseBuilder Length(ulong length);
+ /// The content to be send to the client
+ IResponseBuilder Content(IResponseContent content);
- }
+ ///
+ /// Specifies the length of the content stream, if known.
+ ///
+ /// The length of the content stream
+ IResponseBuilder Length(ulong length);
}
diff --git a/API/Protocol/IResponseContent.cs b/API/Protocol/IResponseContent.cs
index c8d1152c..d092e99a 100644
--- a/API/Protocol/IResponseContent.cs
+++ b/API/Protocol/IResponseContent.cs
@@ -1,51 +1,48 @@
using System.IO;
using System.Threading.Tasks;
-namespace GenHTTP.Api.Protocol
-{
+namespace GenHTTP.Api.Protocol;
+///
+/// Represents the content of a HTTP response to be sent to the client.
+///
+///
+/// Allows to efficiently stream data into the network stream used by the server.
+///
+public interface IResponseContent
+{
+
///
- /// Represents the content of a HTTP response to be sent to the client.
+ /// The number of bytes to be sent to the client (if known).
///
///
- /// Allows to efficiently stream data into the network stream used by the server.
+ /// If null
is returned by this method, the server needs
+ /// to use chunked encoding to send the data to the client. Therefore,
+ /// try to determine the correct length of the content to be sent
+ /// whenever possible.
+ ///
+ /// Writing more or less bytes than indicated by this property to the
+ /// target stream will cause HTTP client errors or timeouts to occur.
///
- public interface IResponseContent
- {
-
- ///
- /// The number of bytes to be sent to the client (if known).
- ///
- ///
- /// If null
is returned by this method, the server needs
- /// to use chunked encoding to send the data to the client. Therefore,
- /// try to determine the correct length of the content to be sent
- /// whenever possible.
- ///
- /// Writing more or less bytes than indicated by this property to the
- /// target stream will cause HTTP client errors or timeouts to occur.
- ///
- ulong? Length { get; }
-
- ///
- /// A checksum of the content represented by this instance.
- ///
- ///
- /// The checksum calculation should be as fast as possible but
- /// still allow to reliably detect changes. For efficient processing,
- /// this also means that the content should actually be expanded
- /// when the Write call is invoked, not when the content instance
- /// is constructed.
- ///
- ValueTask CalculateChecksumAsync();
+ ulong? Length { get; }
- ///
- /// Writes the content to the specified target stream.
- ///
- /// The stream to write the data to
- /// The buffer size to be used to write the data
- ValueTask WriteAsync(Stream target, uint bufferSize);
+ ///
+ /// A checksum of the content represented by this instance.
+ ///
+ ///
+ /// The checksum calculation should be as fast as possible but
+ /// still allow to reliably detect changes. For efficient processing,
+ /// this also means that the content should actually be expanded
+ /// when the Write call is invoked, not when the content instance
+ /// is constructed.
+ ///
+ ValueTask CalculateChecksumAsync();
- }
+ ///
+ /// Writes the content to the specified target stream.
+ ///
+ /// The stream to write the data to
+ /// The buffer size to be used to write the data
+ ValueTask WriteAsync(Stream target, uint bufferSize);
}
diff --git a/API/Protocol/IResponseModification.cs b/API/Protocol/IResponseModification.cs
index eb86eeb0..771f134c 100644
--- a/API/Protocol/IResponseModification.cs
+++ b/API/Protocol/IResponseModification.cs
@@ -1,76 +1,73 @@
using System;
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+///
+/// Allows the response generated by a builder or handler to be
+/// adjusted.
+///
+///
+/// This can be useful if you would like to add behavior that the
+/// original handler (such as a page renderer) does not provide.
+///
+/// For example, as the page handlers implement this interface,
+/// you can add an additional header to the response being generated
+/// for a page.
+///
+/// The type of builder used as a return value
+public interface IResponseModification
{
///
- /// Allows the response generated by a builder or handler to be
- /// adjusted.
+ /// Specifies the HTTP status code of the response.
///
- ///
- /// This can be useful if you would like to add behavior that the
- /// original handler (such as a page renderer) does not provide.
- ///
- /// For example, as the page handlers implement this interface,
- /// you can add an additional header to the response being generated
- /// for a page.
- ///
- /// The type of builder used as a return value
- public interface IResponseModification
- {
-
- ///
- /// Specifies the HTTP status code of the response.
- ///
- /// The HTTP status code of the response
- TBuilder Status(ResponseStatus status);
-
- ///
- /// Specifies the HTTP status code of the response.
- ///
- /// The status code of the response
- /// The reason phrase of the response (such as "Not Found" for 404)
- TBuilder Status(int status, string reason);
+ /// The HTTP status code of the response
+ TBuilder Status(ResponseStatus status);
- ///
- /// Sets the given header field on the response. Changing HTTP
- /// protocol headers may cause incorrect behavior.
- ///
- /// The name of the header to be set
- /// The value of the header field
- TBuilder Header(string key, string value);
+ ///
+ /// Specifies the HTTP status code of the response.
+ ///
+ /// The status code of the response
+ /// The reason phrase of the response (such as "Not Found" for 404)
+ TBuilder Status(int status, string reason);
- ///
- /// Sets the expiration date of the response.
- ///
- /// The expiration date of the response
- TBuilder Expires(DateTime expiryDate);
+ ///
+ /// Sets the given header field on the response. Changing HTTP
+ /// protocol headers may cause incorrect behavior.
+ ///
+ /// The name of the header to be set
+ /// The value of the header field
+ TBuilder Header(string key, string value);
- ///
- /// Sets the point in time when the requested resource has been
- /// modified last.
- ///
- /// The point in time when the requested resource has been modified last
- TBuilder Modified(DateTime modificationDate);
+ ///
+ /// Sets the expiration date of the response.
+ ///
+ /// The expiration date of the response
+ TBuilder Expires(DateTime expiryDate);
- ///
- /// Adds the given cookie to the response.
- ///
- /// The cookie to be added
- TBuilder Cookie(Cookie cookie);
+ ///
+ /// Sets the point in time when the requested resource has been
+ /// modified last.
+ ///
+ /// The point in time when the requested resource has been modified last
+ TBuilder Modified(DateTime modificationDate);
- ///
- /// Specifies the content type of this response.
- ///
- /// The content type of this response
- TBuilder Type(FlexibleContentType contentType);
+ ///
+ /// Adds the given cookie to the response.
+ ///
+ /// The cookie to be added
+ TBuilder Cookie(Cookie cookie);
- ///
- /// Sets the encoding of the content.
- ///
- /// The encoding of the content
- TBuilder Encoding(string encoding);
+ ///
+ /// Specifies the content type of this response.
+ ///
+ /// The content type of this response
+ TBuilder Type(FlexibleContentType contentType);
- }
+ ///
+ /// Sets the encoding of the content.
+ ///
+ /// The encoding of the content
+ TBuilder Encoding(string encoding);
}
diff --git a/API/Protocol/ProtocolException.cs b/API/Protocol/ProtocolException.cs
index 9e9b4be8..6de1639a 100644
--- a/API/Protocol/ProtocolException.cs
+++ b/API/Protocol/ProtocolException.cs
@@ -1,26 +1,23 @@
using System;
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+///
+/// Thrown by the server, if the HTTP protocol has
+/// somehow been violated (either by the server or the client).
+///
+[Serializable]
+public class ProtocolException : Exception
{
- ///
- /// Thrown by the server, if the HTTP protocol has
- /// somehow been violated (either by the server or the client).
- ///
- [Serializable]
- public class ProtocolException : Exception
+ public ProtocolException(string reason) : base(reason)
{
- public ProtocolException(string reason) : base(reason)
- {
-
}
- public ProtocolException(string reason, Exception inner) : base(reason, inner)
- {
+ public ProtocolException(string reason, Exception inner) : base(reason, inner)
+ {
}
- }
-
}
diff --git a/API/Protocol/RequestMethod.cs b/API/Protocol/RequestMethod.cs
index 9d1fa2cf..3f06fa32 100644
--- a/API/Protocol/RequestMethod.cs
+++ b/API/Protocol/RequestMethod.cs
@@ -1,106 +1,105 @@
using System;
using System.Collections.Generic;
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+public enum RequestMethod
{
+ GET,
+ HEAD,
+ POST,
+ PUT,
+ PATCH,
+ DELETE,
+ OPTIONS,
+ PROPFIND,
+ PROPPATCH,
+ MKCOL,
+ COPY,
+ MOVE,
+ LOCK,
+ UNLOCK
+}
- public enum RequestMethod
+///
+/// The kind of request sent by the client.
+///
+public class FlexibleRequestMethod
+{
+ private static readonly Dictionary _RawCache = new(StringComparer.InvariantCultureIgnoreCase)
+ {
+ { "HEAD", new(RequestMethod.HEAD) },
+ { "GET", new(RequestMethod.GET) },
+ { "POST", new(RequestMethod.POST) },
+ { "PUT", new(RequestMethod.PUT) },
+ { "DELETE", new(RequestMethod.DELETE) },
+ { "OPTIONS", new(RequestMethod.OPTIONS) }
+ };
+
+ private static readonly Dictionary _KnownCache = new()
{
- GET,
- HEAD,
- POST,
- PUT,
- PATCH,
- DELETE,
- OPTIONS,
- PROPFIND,
- PROPPATCH,
- MKCOL,
- COPY,
- MOVE,
- LOCK,
- UNLOCK
- }
+ { RequestMethod.HEAD, new(RequestMethod.HEAD) },
+ { RequestMethod.GET, new(RequestMethod.GET) },
+ { RequestMethod.POST, new(RequestMethod.POST) },
+ { RequestMethod.PUT, new(RequestMethod.PUT) },
+ { RequestMethod.DELETE, new(RequestMethod.DELETE) },
+ { RequestMethod.OPTIONS, new(RequestMethod.OPTIONS) }
+ };
+
+ #region Get-/Setters
///
- /// The kind of request sent by the client.
+ /// The known method of the request, if any.
///
- public class FlexibleRequestMethod
+ public RequestMethod? KnownMethod { get; }
+
+ ///
+ /// The raw method of the request.
+ ///
+ public string RawMethod { get; }
+
+ #endregion
+
+ #region Mapping
+
+ private static readonly Dictionary MAPPING = new(StringComparer.OrdinalIgnoreCase)
+ {
+ { "GET", RequestMethod.GET },
+ { "HEAD", RequestMethod.HEAD },
+ { "POST", RequestMethod.POST },
+ { "PUT", RequestMethod.PUT },
+ { "PATCH", RequestMethod.PATCH },
+ { "DELETE", RequestMethod.DELETE },
+ { "OPTIONS", RequestMethod.OPTIONS },
+ { "PROPFIND", RequestMethod.PROPFIND },
+ { "PROPPATCH", RequestMethod.PROPPATCH },
+ { "MKCOL", RequestMethod.MKCOL },
+ { "COPY", RequestMethod.COPY },
+ { "MOVE", RequestMethod.MOVE },
+ { "LOCK", RequestMethod.LOCK },
+ { "UNLOCK", RequestMethod.UNLOCK }
+ };
+
+ #endregion
+
+ #region Initialization
+
+ ///
+ /// Creates a new request method instance from a known type.
+ ///
+ /// The known type to be used
+ public FlexibleRequestMethod(RequestMethod method)
{
- private static readonly Dictionary _RawCache = new(StringComparer.InvariantCultureIgnoreCase)
- {
- { "HEAD", new(RequestMethod.HEAD) },
- { "GET", new(RequestMethod.GET) },
- { "POST", new(RequestMethod.POST) },
- { "PUT", new(RequestMethod.PUT) },
- { "DELETE", new(RequestMethod.DELETE) },
- { "OPTIONS", new(RequestMethod.OPTIONS) }
- };
-
- private static readonly Dictionary _KnownCache = new()
- {
- { RequestMethod.HEAD, new(RequestMethod.HEAD) },
- { RequestMethod.GET, new(RequestMethod.GET) },
- { RequestMethod.POST, new(RequestMethod.POST) },
- { RequestMethod.PUT, new(RequestMethod.PUT) },
- { RequestMethod.DELETE, new(RequestMethod.DELETE) },
- { RequestMethod.OPTIONS, new(RequestMethod.OPTIONS) }
- };
-
- #region Get-/Setters
-
- ///
- /// The known method of the request, if any.
- ///
- public RequestMethod? KnownMethod { get; }
-
- ///
- /// The raw method of the request.
- ///
- public string RawMethod { get; }
-
- #endregion
-
- #region Mapping
-
- private static readonly Dictionary MAPPING = new(StringComparer.OrdinalIgnoreCase)
- {
- { "GET", RequestMethod.GET },
- { "HEAD", RequestMethod.HEAD },
- { "POST", RequestMethod.POST },
- { "PUT", RequestMethod.PUT },
- { "PATCH", RequestMethod.PATCH },
- { "DELETE", RequestMethod.DELETE },
- { "OPTIONS", RequestMethod.OPTIONS },
- { "PROPFIND", RequestMethod.PROPFIND },
- { "PROPPATCH", RequestMethod.PROPPATCH },
- { "MKCOL", RequestMethod.MKCOL },
- { "COPY", RequestMethod.COPY },
- { "MOVE", RequestMethod.MOVE },
- { "LOCK", RequestMethod.LOCK },
- { "UNLOCK", RequestMethod.UNLOCK }
- };
-
- #endregion
-
- #region Initialization
-
- ///
- /// Creates a new request method instance from a known type.
- ///
- /// The known type to be used
- public FlexibleRequestMethod(RequestMethod method)
- {
KnownMethod = method;
RawMethod = Enum.GetName(method) ?? throw new ArgumentException("The given method cannot be mapped", nameof(method));
}
- ///
- /// Create a new request method instance.
- ///
- /// The raw type transmitted by the client
- public FlexibleRequestMethod(string rawType)
- {
+ ///
+ /// Create a new request method instance.
+ ///
+ /// The raw type transmitted by the client
+ public FlexibleRequestMethod(string rawType)
+ {
RawMethod = rawType;
if (MAPPING.TryGetValue(rawType, out var type))
@@ -113,17 +112,17 @@ public FlexibleRequestMethod(string rawType)
}
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- ///
- /// Fetches a cached instance for the given content type.
- ///
- /// The raw string to be resolved
- /// The content type instance to be used
- public static FlexibleRequestMethod Get(string rawMethod)
- {
+ ///
+ /// Fetches a cached instance for the given content type.
+ ///
+ /// The raw string to be resolved
+ /// The content type instance to be used
+ public static FlexibleRequestMethod Get(string rawMethod)
+ {
if (_RawCache.TryGetValue(rawMethod, out var found))
{
return found;
@@ -136,13 +135,13 @@ public static FlexibleRequestMethod Get(string rawMethod)
return method;
}
- ///
- /// Fetches a cached instance for the given content type.
- ///
- /// The known value to be resolved
- /// The content type instance to be used
- public static FlexibleRequestMethod Get(RequestMethod knownMethod)
- {
+ ///
+ /// Fetches a cached instance for the given content type.
+ ///
+ /// The known value to be resolved
+ /// The content type instance to be used
+ public static FlexibleRequestMethod Get(RequestMethod knownMethod)
+ {
if (_KnownCache.TryGetValue(knownMethod, out var found))
{
return found;
@@ -155,24 +154,22 @@ public static FlexibleRequestMethod Get(RequestMethod knownMethod)
return method;
}
- #endregion
-
- #region Convenience
+ #endregion
- public static bool operator ==(FlexibleRequestMethod method, RequestMethod knownMethod) => method.KnownMethod == knownMethod;
+ #region Convenience
- public static bool operator !=(FlexibleRequestMethod method, RequestMethod knownMethod) => method.KnownMethod != knownMethod;
+ public static bool operator ==(FlexibleRequestMethod method, RequestMethod knownMethod) => method.KnownMethod == knownMethod;
- public static bool operator ==(FlexibleRequestMethod method, string rawMethod) => method.RawMethod == rawMethod;
+ public static bool operator !=(FlexibleRequestMethod method, RequestMethod knownMethod) => method.KnownMethod != knownMethod;
- public static bool operator !=(FlexibleRequestMethod method, string rawMethod) => method.RawMethod != rawMethod;
+ public static bool operator ==(FlexibleRequestMethod method, string rawMethod) => method.RawMethod == rawMethod;
- public override bool Equals(object? obj) => obj is FlexibleRequestMethod method && RawMethod == method.RawMethod;
+ public static bool operator !=(FlexibleRequestMethod method, string rawMethod) => method.RawMethod != rawMethod;
- public override int GetHashCode() => RawMethod.GetHashCode();
+ public override bool Equals(object? obj) => obj is FlexibleRequestMethod method && RawMethod == method.RawMethod;
- #endregion
+ public override int GetHashCode() => RawMethod.GetHashCode();
- }
+ #endregion
}
diff --git a/API/Protocol/ResponseModificationBuilder.cs b/API/Protocol/ResponseModificationBuilder.cs
index af7c73b2..586d0732 100644
--- a/API/Protocol/ResponseModificationBuilder.cs
+++ b/API/Protocol/ResponseModificationBuilder.cs
@@ -3,32 +3,31 @@
using GenHTTP.Api.Infrastructure;
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+///
+/// Allows to build a response modification object so that
+/// individual handlers do not need to implement the logic
+/// theirselves.
+///
+public class ResponseModificationBuilder : IResponseModification, IBuilder
{
+ private FlexibleResponseStatus? _Status;
- ///
- /// Allows to build a response modification object so that
- /// individual handlers do not need to implement the logic
- /// theirselves.
- ///
- public class ResponseModificationBuilder : IResponseModification, IBuilder
- {
- private FlexibleResponseStatus? _Status;
-
- private FlexibleContentType? _ContentType;
+ private FlexibleContentType? _ContentType;
- private List? _Cookies;
+ private List? _Cookies;
- private string? _Encoding;
+ private string? _Encoding;
- private DateTime? _ExpiryDate, _ModificationDate;
+ private DateTime? _ExpiryDate, _ModificationDate;
- private Dictionary? _Headers;
+ private Dictionary? _Headers;
- #region Functionality
+ #region Functionality
- public ResponseModificationBuilder Cookie(Cookie cookie)
- {
+ public ResponseModificationBuilder Cookie(Cookie cookie)
+ {
if (_Cookies == null)
{
_Cookies = new();
@@ -39,20 +38,20 @@ public ResponseModificationBuilder Cookie(Cookie cookie)
return this;
}
- public ResponseModificationBuilder Encoding(string encoding)
- {
+ public ResponseModificationBuilder Encoding(string encoding)
+ {
_Encoding = encoding;
return this;
}
- public ResponseModificationBuilder Expires(DateTime expiryDate)
- {
+ public ResponseModificationBuilder Expires(DateTime expiryDate)
+ {
_ExpiryDate = expiryDate;
return this;
}
- public ResponseModificationBuilder Header(string key, string value)
- {
+ public ResponseModificationBuilder Header(string key, string value)
+ {
if (_Headers == null)
{
_Headers = new();
@@ -63,32 +62,32 @@ public ResponseModificationBuilder Header(string key, string value)
return this;
}
- public ResponseModificationBuilder Modified(DateTime modificationDate)
- {
+ public ResponseModificationBuilder Modified(DateTime modificationDate)
+ {
_ModificationDate = modificationDate;
return this;
}
- public ResponseModificationBuilder Status(ResponseStatus status)
- {
+ public ResponseModificationBuilder Status(ResponseStatus status)
+ {
_Status = new(status);
return this;
}
- public ResponseModificationBuilder Status(int status, string reason)
- {
+ public ResponseModificationBuilder Status(int status, string reason)
+ {
_Status = new(status, reason);
return this;
}
- public ResponseModificationBuilder Type(FlexibleContentType contentType)
- {
+ public ResponseModificationBuilder Type(FlexibleContentType contentType)
+ {
_ContentType = contentType;
return this;
}
- public ResponseModifications? Build()
- {
+ public ResponseModifications? Build()
+ {
if ((_Status != null) || (_Encoding != null) || (null != _ContentType)
|| (_ExpiryDate != null) || (_ModificationDate != null)
|| (_Cookies?.Count > 0) || (_Headers?.Count > 0))
@@ -99,8 +98,6 @@ public ResponseModificationBuilder Type(FlexibleContentType contentType)
return null;
}
- #endregion
-
- }
+ #endregion
-}
+}
\ No newline at end of file
diff --git a/API/Protocol/ResponseModifications.cs b/API/Protocol/ResponseModifications.cs
index 110cc58d..a4c49225 100644
--- a/API/Protocol/ResponseModifications.cs
+++ b/API/Protocol/ResponseModifications.cs
@@ -1,60 +1,59 @@
using System;
using System.Collections.Generic;
-namespace GenHTTP.Api.Protocol
-{
+namespace GenHTTP.Api.Protocol;
- ///
- /// A set of custom modifications to be applied to a response.
- ///
- public sealed class ResponseModifications
- {
+///
+/// A set of custom modifications to be applied to a response.
+///
+public sealed class ResponseModifications
+{
- #region Get-/Setters
+ #region Get-/Setters
- ///
- /// The status to be set on the response, if set.
- ///
- public FlexibleResponseStatus? Status { get; }
+ ///
+ /// The status to be set on the response, if set.
+ ///
+ public FlexibleResponseStatus? Status { get; }
- ///
- /// The content type to be set on the response, if set.
- ///
- public FlexibleContentType? ContentType { get; }
+ ///
+ /// The content type to be set on the response, if set.
+ ///
+ public FlexibleContentType? ContentType { get; }
- ///
- /// The cookies to be set on the response, if set.
- ///
- public List? Cookies { get; }
+ ///
+ /// The cookies to be set on the response, if set.
+ ///
+ public List? Cookies { get; }
- ///
- /// The encoding to be set on the response, if set.
- ///
- public string? Encoding { get; }
+ ///
+ /// The encoding to be set on the response, if set.
+ ///
+ public string? Encoding { get; }
- ///
- /// The expiration date to be set on the response, if set.
- ///
- public DateTime? ExpiryDate { get; }
+ ///
+ /// The expiration date to be set on the response, if set.
+ ///
+ public DateTime? ExpiryDate { get; }
- ///
- /// The modification date to be set on the response, if set.
- ///
- public DateTime? ModificationDate { get; }
+ ///
+ /// The modification date to be set on the response, if set.
+ ///
+ public DateTime? ModificationDate { get; }
- ///
- /// The headers to be set on the response, if set.
- ///
- public Dictionary? Headers { get; }
+ ///
+ /// The headers to be set on the response, if set.
+ ///
+ public Dictionary? Headers { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- public ResponseModifications(FlexibleResponseStatus? status, FlexibleContentType? contentType,
- List? cookies, string? encoding, DateTime? expiryDate, DateTime? modificationDate,
- Dictionary? headers)
- {
+ public ResponseModifications(FlexibleResponseStatus? status, FlexibleContentType? contentType,
+ List? cookies, string? encoding, DateTime? expiryDate, DateTime? modificationDate,
+ Dictionary? headers)
+ {
Status = status;
ContentType = contentType;
@@ -67,17 +66,17 @@ public ResponseModifications(FlexibleResponseStatus? status, FlexibleContentType
Headers = headers;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- ///
- /// Applies the modifications configured in this instance to the
- /// given response.
- ///
- /// The response to be adjusted
- public void Apply(IResponseBuilder builder)
- {
+ ///
+ /// Applies the modifications configured in this instance to the
+ /// given response.
+ ///
+ /// The response to be adjusted
+ public void Apply(IResponseBuilder builder)
+ {
if (Status != null)
{
builder.Status(Status.Value.RawStatus, Status.Value.Phrase);
@@ -120,8 +119,6 @@ public void Apply(IResponseBuilder builder)
}
}
- #endregion
-
- }
+ #endregion
}
diff --git a/API/Protocol/ResponseStatus.cs b/API/Protocol/ResponseStatus.cs
index 9c9a0f0d..c3dc7ce0 100644
--- a/API/Protocol/ResponseStatus.cs
+++ b/API/Protocol/ResponseStatus.cs
@@ -2,210 +2,209 @@
using System.Linq;
using System.Collections.Generic;
-namespace GenHTTP.Api.Protocol
+namespace GenHTTP.Api.Protocol;
+
+#region Known Types
+
+public enum ResponseStatus
{
- #region Known Types
+ Continue = 100,
- public enum ResponseStatus
- {
+ SwitchingProtocols = 101,
- Continue = 100,
+ Processing = 102,
- SwitchingProtocols = 101,
+ OK = 200,
- Processing = 102,
+ Created = 201,
- OK = 200,
+ Accepted = 202,
- Created = 201,
+ NoContent = 204,
- Accepted = 202,
+ PartialContent = 206,
- NoContent = 204,
+ MultiStatus = 207,
- PartialContent = 206,
+ AlreadyReported = 208,
- MultiStatus = 207,
+ MovedPermanently = 301,
- AlreadyReported = 208,
+ Found = 302,
- MovedPermanently = 301,
+ SeeOther = 303,
- Found = 302,
+ NotModified = 304,
- SeeOther = 303,
+ TemporaryRedirect = 307,
- NotModified = 304,
+ PermanentRedirect = 308,
- TemporaryRedirect = 307,
+ BadRequest = 400,
- PermanentRedirect = 308,
+ Unauthorized = 401,
- BadRequest = 400,
+ Forbidden = 403,
- Unauthorized = 401,
+ NotFound = 404,
- Forbidden = 403,
+ MethodNotAllowed = 405,
- NotFound = 404,
+ NotAcceptable = 406,
- MethodNotAllowed = 405,
+ ProxyAuthenticationRequired = 407,
- NotAcceptable = 406,
+ Conflict = 409,
- ProxyAuthenticationRequired = 407,
+ Gone = 410,
- Conflict = 409,
+ LengthRequired = 411,
- Gone = 410,
+ PreconditionFailed = 412,
- LengthRequired = 411,
+ RequestEntityTooLarge = 413,
- PreconditionFailed = 412,
+ RequestUriTooLong = 414,
- RequestEntityTooLarge = 413,
+ UnsupportedMediaType = 415,
- RequestUriTooLong = 414,
+ RequestedRangeNotSatisfiable = 416,
- UnsupportedMediaType = 415,
+ ExpectationFailed = 417,
- RequestedRangeNotSatisfiable = 416,
+ UnprocessableEntity = 422,
- ExpectationFailed = 417,
+ Locked = 423,
- UnprocessableEntity = 422,
+ FailedDependency = 424,
- Locked = 423,
+ ReservedForWebDAV = 425,
- FailedDependency = 424,
+ UpgradeRequired = 426,
- ReservedForWebDAV = 425,
+ PreconditionRequired = 428,
- UpgradeRequired = 426,
+ TooManyRequests = 429,
- PreconditionRequired = 428,
+ RequestHeaderFieldsTooLarge = 431,
- TooManyRequests = 429,
+ UnavailableForLegalReasons = 451,
- RequestHeaderFieldsTooLarge = 431,
+ InternalServerError = 500,
- UnavailableForLegalReasons = 451,
+ NotImplemented = 501,
- InternalServerError = 500,
+ BadGateway = 502,
- NotImplemented = 501,
+ ServiceUnavailable = 503,
- BadGateway = 502,
+ GatewayTimeout = 504,
- ServiceUnavailable = 503,
+ HttpVersionNotSupported = 505,
- GatewayTimeout = 504,
+ InsufficientStorage = 507,
- HttpVersionNotSupported = 505,
+ LoopDetected = 508,
- InsufficientStorage = 507,
+ NotExtended = 510,
- LoopDetected = 508,
+ NetworkAuthenticationRequired = 511
- NotExtended = 510,
+}
- NetworkAuthenticationRequired = 511
+#endregion
- }
+///
+/// The status of the response send to the client.
+///
+public struct FlexibleResponseStatus
+{
- #endregion
+ #region Get-/Setters
+
+ ///
+ /// The known status, if any.
+ ///
+ public ResponseStatus? KnownStatus { get; }
+
+ ///
+ /// The raw HTTP status.
+ ///
+ public int RawStatus { get; }
///
- /// The status of the response send to the client.
+ /// The reason phrase to be send.
///
- public struct FlexibleResponseStatus
+ public string Phrase { get; }
+
+ #endregion
+
+ #region Mapping
+
+ private static readonly Dictionary MAPPING = new()
{
+ { ResponseStatus.Accepted, "Accepted" },
+ { ResponseStatus.BadGateway, "Bad Gateway" },
+ { ResponseStatus.BadRequest, "Bad Request" },
+ { ResponseStatus.Created, "Created" },
+ { ResponseStatus.Forbidden, "Forbidden" },
+ { ResponseStatus.InternalServerError, "Internal Server Error" },
+ { ResponseStatus.MethodNotAllowed, "Method Not Allowed" },
+ { ResponseStatus.MovedPermanently, "Moved Permamently" },
+ { ResponseStatus.Found, "Found" },
+ { ResponseStatus.NoContent, "No Content" },
+ { ResponseStatus.NotFound, "Not Found" },
+ { ResponseStatus.NotImplemented, "Not Implemented" },
+ { ResponseStatus.NotModified, "Not Modified" },
+ { ResponseStatus.OK, "OK" },
+ { ResponseStatus.ServiceUnavailable, "Service Unavailable"},
+ { ResponseStatus.Unauthorized, "Unauthorized"},
+ { ResponseStatus.PartialContent, "Partial Content"},
+ { ResponseStatus.MultiStatus, "Multi-Status"},
+ { ResponseStatus.AlreadyReported, "Already Reported"},
+ { ResponseStatus.SeeOther, "See Other" },
+ { ResponseStatus.TemporaryRedirect, "Temporary Redirect"},
+ { ResponseStatus.PermanentRedirect, "Permanent Redirect"},
+ { ResponseStatus.Continue, "Continue" },
+ { ResponseStatus.SwitchingProtocols, "Switching Protocols" },
+ { ResponseStatus.NotAcceptable, "Not Acceptable" },
+ { ResponseStatus.ProxyAuthenticationRequired, "Proxy Authentication Required" },
+ { ResponseStatus.Conflict, "Conflict" },
+ { ResponseStatus.Gone, "Gone" },
+ { ResponseStatus.LengthRequired, "Length Required" },
+ { ResponseStatus.PreconditionFailed, "Precondition Failed" },
+ { ResponseStatus.RequestEntityTooLarge, "Request Entity Too Large" },
+ { ResponseStatus.RequestUriTooLong, "Request Uri Too Long" },
+ { ResponseStatus.UnsupportedMediaType, "Unsupported Media Type" },
+ { ResponseStatus.RequestedRangeNotSatisfiable, "Requested Range Not Satisfiable" },
+ { ResponseStatus.ExpectationFailed, "Expectation Failed" },
+ { ResponseStatus.UnprocessableEntity, "Unprocessable Entity" },
+ { ResponseStatus.Locked, "Locked" },
+ { ResponseStatus.FailedDependency, "Failed Dependency" },
+ { ResponseStatus.ReservedForWebDAV, "Reserved For WebDAV" },
+ { ResponseStatus.UpgradeRequired, "Upgrade Required" },
+ { ResponseStatus.PreconditionRequired, "Precondition Required" },
+ { ResponseStatus.TooManyRequests, "Too Many Requests" },
+ { ResponseStatus.RequestHeaderFieldsTooLarge, "Request Header Fields Too Large" },
+ { ResponseStatus.UnavailableForLegalReasons, "Unavailable For Legal Reasons" },
+ { ResponseStatus.GatewayTimeout, "Gateway Timeout" },
+ { ResponseStatus.HttpVersionNotSupported, "HTTP Version Not Supported" },
+ { ResponseStatus.InsufficientStorage, "Insufficient Storage" },
+ { ResponseStatus.LoopDetected, "Loop Detected" },
+ { ResponseStatus.NotExtended, "Not Extended" },
+ { ResponseStatus.NetworkAuthenticationRequired, "Network Authentication Required" },
+ { ResponseStatus.Processing, "Processing" }
+ };
+
+ private static readonly Dictionary CODE_MAPPING = MAPPING.Keys.ToDictionary((k) => (int)k, (k) => k);
+
+ #endregion
- #region Get-/Setters
-
- ///
- /// The known status, if any.
- ///
- public ResponseStatus? KnownStatus { get; }
-
- ///
- /// The raw HTTP status.
- ///
- public int RawStatus { get; }
-
- ///
- /// The reason phrase to be send.
- ///
- public string Phrase { get; }
-
- #endregion
-
- #region Mapping
-
- private static readonly Dictionary MAPPING = new()
- {
- { ResponseStatus.Accepted, "Accepted" },
- { ResponseStatus.BadGateway, "Bad Gateway" },
- { ResponseStatus.BadRequest, "Bad Request" },
- { ResponseStatus.Created, "Created" },
- { ResponseStatus.Forbidden, "Forbidden" },
- { ResponseStatus.InternalServerError, "Internal Server Error" },
- { ResponseStatus.MethodNotAllowed, "Method Not Allowed" },
- { ResponseStatus.MovedPermanently, "Moved Permamently" },
- { ResponseStatus.Found, "Found" },
- { ResponseStatus.NoContent, "No Content" },
- { ResponseStatus.NotFound, "Not Found" },
- { ResponseStatus.NotImplemented, "Not Implemented" },
- { ResponseStatus.NotModified, "Not Modified" },
- { ResponseStatus.OK, "OK" },
- { ResponseStatus.ServiceUnavailable, "Service Unavailable"},
- { ResponseStatus.Unauthorized, "Unauthorized"},
- { ResponseStatus.PartialContent, "Partial Content"},
- { ResponseStatus.MultiStatus, "Multi-Status"},
- { ResponseStatus.AlreadyReported, "Already Reported"},
- { ResponseStatus.SeeOther, "See Other" },
- { ResponseStatus.TemporaryRedirect, "Temporary Redirect"},
- { ResponseStatus.PermanentRedirect, "Permanent Redirect"},
- { ResponseStatus.Continue, "Continue" },
- { ResponseStatus.SwitchingProtocols, "Switching Protocols" },
- { ResponseStatus.NotAcceptable, "Not Acceptable" },
- { ResponseStatus.ProxyAuthenticationRequired, "Proxy Authentication Required" },
- { ResponseStatus.Conflict, "Conflict" },
- { ResponseStatus.Gone, "Gone" },
- { ResponseStatus.LengthRequired, "Length Required" },
- { ResponseStatus.PreconditionFailed, "Precondition Failed" },
- { ResponseStatus.RequestEntityTooLarge, "Request Entity Too Large" },
- { ResponseStatus.RequestUriTooLong, "Request Uri Too Long" },
- { ResponseStatus.UnsupportedMediaType, "Unsupported Media Type" },
- { ResponseStatus.RequestedRangeNotSatisfiable, "Requested Range Not Satisfiable" },
- { ResponseStatus.ExpectationFailed, "Expectation Failed" },
- { ResponseStatus.UnprocessableEntity, "Unprocessable Entity" },
- { ResponseStatus.Locked, "Locked" },
- { ResponseStatus.FailedDependency, "Failed Dependency" },
- { ResponseStatus.ReservedForWebDAV, "Reserved For WebDAV" },
- { ResponseStatus.UpgradeRequired, "Upgrade Required" },
- { ResponseStatus.PreconditionRequired, "Precondition Required" },
- { ResponseStatus.TooManyRequests, "Too Many Requests" },
- { ResponseStatus.RequestHeaderFieldsTooLarge, "Request Header Fields Too Large" },
- { ResponseStatus.UnavailableForLegalReasons, "Unavailable For Legal Reasons" },
- { ResponseStatus.GatewayTimeout, "Gateway Timeout" },
- { ResponseStatus.HttpVersionNotSupported, "HTTP Version Not Supported" },
- { ResponseStatus.InsufficientStorage, "Insufficient Storage" },
- { ResponseStatus.LoopDetected, "Loop Detected" },
- { ResponseStatus.NotExtended, "Not Extended" },
- { ResponseStatus.NetworkAuthenticationRequired, "Network Authentication Required" },
- { ResponseStatus.Processing, "Processing" }
- };
-
- private static readonly Dictionary CODE_MAPPING = MAPPING.Keys.ToDictionary((k) => (int)k, (k) => k);
-
- #endregion
-
- #region Initialization
-
- public FlexibleResponseStatus(int status, string phrase)
- {
+ #region Initialization
+
+ public FlexibleResponseStatus(int status, string phrase)
+ {
RawStatus = status;
Phrase = phrase;
@@ -219,32 +218,30 @@ public FlexibleResponseStatus(int status, string phrase)
}
}
- public FlexibleResponseStatus(ResponseStatus status)
- {
+ public FlexibleResponseStatus(ResponseStatus status)
+ {
KnownStatus = status;
RawStatus = (int)status;
Phrase = MAPPING[status];
}
- #endregion
-
- #region Convenience
+ #endregion
- public static bool operator ==(FlexibleResponseStatus status, ResponseStatus knownStatus) => status.KnownStatus == knownStatus;
+ #region Convenience
- public static bool operator !=(FlexibleResponseStatus status, ResponseStatus knownStatus) => status.KnownStatus != knownStatus;
+ public static bool operator ==(FlexibleResponseStatus status, ResponseStatus knownStatus) => status.KnownStatus == knownStatus;
- public static bool operator ==(FlexibleResponseStatus status, int rawStatus) => status.RawStatus == rawStatus;
+ public static bool operator !=(FlexibleResponseStatus status, ResponseStatus knownStatus) => status.KnownStatus != knownStatus;
- public static bool operator !=(FlexibleResponseStatus status, int rawStatus) => status.RawStatus != rawStatus;
+ public static bool operator ==(FlexibleResponseStatus status, int rawStatus) => status.RawStatus == rawStatus;
- public override bool Equals(object? obj) => obj is FlexibleResponseStatus status && RawStatus == status.RawStatus;
+ public static bool operator !=(FlexibleResponseStatus status, int rawStatus) => status.RawStatus != rawStatus;
- public override int GetHashCode() => RawStatus.GetHashCode();
+ public override bool Equals(object? obj) => obj is FlexibleResponseStatus status && RawStatus == status.RawStatus;
- #endregion
+ public override int GetHashCode() => RawStatus.GetHashCode();
- }
+ #endregion
}
diff --git a/API/Routing/PathBuilder.cs b/API/Routing/PathBuilder.cs
index 0a6984d2..3834bd10 100644
--- a/API/Routing/PathBuilder.cs
+++ b/API/Routing/PathBuilder.cs
@@ -3,58 +3,57 @@
using GenHTTP.Api.Infrastructure;
-namespace GenHTTP.Api.Routing
-{
+namespace GenHTTP.Api.Routing;
- ///
- /// Allows to build a instance.
- ///
- public sealed class PathBuilder : IBuilder
- {
- private readonly List _Segments;
+///
+/// Allows to build a instance.
+///
+public sealed class PathBuilder : IBuilder
+{
+ private readonly List _Segments;
- private bool _TrailingSlash;
+ private bool _TrailingSlash;
- #region Get-/Setters
+ #region Get-/Setters
- ///
- /// True, if no segments have (yet) been added to
- /// this path.
- ///
- public bool IsEmpty => _Segments.Count == 0;
+ ///
+ /// True, if no segments have (yet) been added to
+ /// this path.
+ ///
+ public bool IsEmpty => _Segments.Count == 0;
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- ///
- /// Creates a new, empty path builder.
- ///
- /// Whether the resulting path should end with a slash
- public PathBuilder(bool trailingSlash)
- {
+ ///
+ /// Creates a new, empty path builder.
+ ///
+ /// Whether the resulting path should end with a slash
+ public PathBuilder(bool trailingSlash)
+ {
_Segments = new();
_TrailingSlash = trailingSlash;
}
- ///
- /// Creates a new path builder with the given segments.
- ///
- /// The segments of the path
- /// Whether the resulting path should end with a slash
- public PathBuilder(IEnumerable parts, bool trailingSlash)
- {
+ ///
+ /// Creates a new path builder with the given segments.
+ ///
+ /// The segments of the path
+ /// Whether the resulting path should end with a slash
+ public PathBuilder(IEnumerable parts, bool trailingSlash)
+ {
_Segments = new(parts);
_TrailingSlash = trailingSlash;
}
- ///
- /// Creates a new path builder from the given absolute
- /// or relative path.
- ///
- /// The path to be parsed
- public PathBuilder(string path)
- {
+ ///
+ /// Creates a new path builder from the given absolute
+ /// or relative path.
+ ///
+ /// The path to be parsed
+ public PathBuilder(string path)
+ {
var splitted = path.Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var parts = new List(splitted.Length);
@@ -68,84 +67,82 @@ public PathBuilder(string path)
_TrailingSlash = path.EndsWith('/');
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- ///
- /// Adds the given segment to the beginning of the resulting path.
- ///
- /// The segment to be prepended
- public PathBuilder Preprend(string segment)
- {
+ ///
+ /// Adds the given segment to the beginning of the resulting path.
+ ///
+ /// The segment to be prepended
+ public PathBuilder Preprend(string segment)
+ {
_Segments.Insert(0, new WebPathPart(segment));
return this;
}
- ///
- /// Adds the given part to the beginning of the resulting path.
- ///
- /// The part to be prepended
- public PathBuilder Preprend(WebPathPart part)
- {
+ ///
+ /// Adds the given part to the beginning of the resulting path.
+ ///
+ /// The part to be prepended
+ public PathBuilder Preprend(WebPathPart part)
+ {
_Segments.Insert(0, part);
return this;
}
- ///
- /// Adds the given path to the beginning of the resulting path.
- ///
- /// The path to be prepended
- public PathBuilder Preprend(WebPath path)
- {
+ ///
+ /// Adds the given path to the beginning of the resulting path.
+ ///
+ /// The path to be prepended
+ public PathBuilder Preprend(WebPath path)
+ {
_Segments.InsertRange(0, path.Parts);
return this;
}
- ///
- /// Adds the given segment to the end of the resulting path.
- ///
- /// The segment to be appended
- public PathBuilder Append(string segment)
- {
+ ///
+ /// Adds the given segment to the end of the resulting path.
+ ///
+ /// The segment to be appended
+ public PathBuilder Append(string segment)
+ {
_Segments.Add(new WebPathPart(segment));
return this;
}
- ///
- /// Adds the given segment to the end of the resulting path.
- ///
- /// The segment to be appended
- public PathBuilder Append(WebPathPart segment)
- {
+ ///
+ /// Adds the given segment to the end of the resulting path.
+ ///
+ /// The segment to be appended
+ public PathBuilder Append(WebPathPart segment)
+ {
_Segments.Add(segment);
return this;
}
- ///
- /// Adds the given path to the end of the resulting path.
- ///
- /// The path to be appended
- public PathBuilder Append(WebPath path)
- {
+ ///
+ /// Adds the given path to the end of the resulting path.
+ ///
+ /// The path to be appended
+ public PathBuilder Append(WebPath path)
+ {
_Segments.AddRange(path.Parts);
return this;
}
- ///
- /// Specifies, whether the resulting path ends with a slash or not.
- ///
- /// True, if the path should end with a trailing slash
- public PathBuilder TrailingSlash(bool existent)
- {
+ ///
+ /// Specifies, whether the resulting path ends with a slash or not.
+ ///
+ /// True, if the path should end with a trailing slash
+ public PathBuilder TrailingSlash(bool existent)
+ {
_TrailingSlash = existent;
return this;
}
- public WebPath Build() => new(_Segments, _TrailingSlash);
-
- #endregion
+ public WebPath Build() => new(_Segments, _TrailingSlash);
- }
+ #endregion
}
diff --git a/API/Routing/RoutingTarget.cs b/API/Routing/RoutingTarget.cs
index 82c5489f..08a60a0d 100644
--- a/API/Routing/RoutingTarget.cs
+++ b/API/Routing/RoutingTarget.cs
@@ -1,67 +1,66 @@
using System;
using System.Collections.Generic;
-namespace GenHTTP.Api.Routing
+namespace GenHTTP.Api.Routing;
+
+///
+/// Provides a view on the target path of a request.
+///
+///
+/// Stores the state of the routing mechanism and allows handlers to
+/// get the remaining parts to be handled.
+///
+public sealed class RoutingTarget
{
-
- ///
- /// Provides a view on the target path of a request.
- ///
- ///
- /// Stores the state of the routing mechanism and allows handlers to
- /// get the remaining parts to be handled.
- ///
- public sealed class RoutingTarget
- {
- private static readonly List EMPTY_LIST = new();
+ private static readonly List EMPTY_LIST = new();
- private int _Index = 0;
+ private int _Index = 0;
- #region Get-/Setters
+ #region Get-/Setters
- ///
- /// The path of the request to be handled by the server.
- ///
- public WebPath Path { get; }
+ ///
+ /// The path of the request to be handled by the server.
+ ///
+ public WebPath Path { get; }
- ///
- /// The segment to be currently handled by the responsible handler.
- ///
- public WebPathPart? Current => (_Index < Path.Parts.Count) ? Path.Parts[_Index] : null;
+ ///
+ /// The segment to be currently handled by the responsible handler.
+ ///
+ public WebPathPart? Current => (_Index < Path.Parts.Count) ? Path.Parts[_Index] : null;
- ///
- /// Specifies, whether the end of the path has been reached.
- ///
- public bool Ended => (_Index >= Path.Parts.Count);
+ ///
+ /// Specifies, whether the end of the path has been reached.
+ ///
+ public bool Ended => (_Index >= Path.Parts.Count);
- ///
- /// Specifies, whether the last part of the path has been reached.
- ///
- public bool Last => (_Index == Path.Parts.Count - 1);
+ ///
+ /// Specifies, whether the last part of the path has been reached.
+ ///
+ public bool Last => (_Index == Path.Parts.Count - 1);
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- ///
- /// Creates a new routing target and sets the pointer to the beginning of the path.
- ///
- /// The targeted path
- public RoutingTarget(WebPath path)
- {
+ ///
+ /// Creates a new routing target and sets the pointer to the beginning of the path.
+ ///
+ /// The targeted path
+ public RoutingTarget(WebPath path)
+ {
Path = path;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- ///
- /// Acknowledges the currently handled segment and advances the
- /// pointer to the next one.
- ///
- public void Advance()
- {
+ ///
+ /// Acknowledges the currently handled segment and advances the
+ /// pointer to the next one.
+ ///
+ public void Advance()
+ {
if (Ended)
{
throw new InvalidOperationException("Already at the end of the path");
@@ -70,12 +69,12 @@ public void Advance()
_Index++;
}
- ///
- /// Retrieves the part of the path that still needs to be routed.
- ///
- /// The remaining part of the path
- public WebPath GetRemaining()
- {
+ ///
+ /// Retrieves the part of the path that still needs to be routed.
+ ///
+ /// The remaining part of the path
+ public WebPath GetRemaining()
+ {
var remaining = Path.Parts.Count - _Index;
var resultList = (remaining > 0) ? new List(remaining) : EMPTY_LIST;
@@ -88,8 +87,6 @@ public WebPath GetRemaining()
return new(resultList, Path.TrailingSlash);
}
- #endregion
-
- }
+ #endregion
-}
+}
\ No newline at end of file
diff --git a/API/Routing/WebPath.cs b/API/Routing/WebPath.cs
index 697835bf..c597acf3 100644
--- a/API/Routing/WebPath.cs
+++ b/API/Routing/WebPath.cs
@@ -1,40 +1,39 @@
using System.Collections.Generic;
using System.Linq;
-namespace GenHTTP.Api.Routing
+namespace GenHTTP.Api.Routing;
+
+///
+/// Specifies a resource available on the server.
+///
+public sealed class WebPath
{
+ #region Get-/Setters
+
///
- /// Specifies a resource available on the server.
+ /// The segments the path consists of.
///
- public sealed class WebPath
- {
-
- #region Get-/Setters
+ public IReadOnlyList Parts { get; }
- ///
- /// The segments the path consists of.
- ///
- public IReadOnlyList Parts { get; }
-
- ///
- /// Specifies, whether the path ends with a trailing slash.
- ///
- public bool TrailingSlash { get; }
+ ///
+ /// Specifies, whether the path ends with a trailing slash.
+ ///
+ public bool TrailingSlash { get; }
- ///
- /// Specifies, whether the path equals the root of the server instance.
- ///
- public bool IsRoot => (Parts.Count == 0);
+ ///
+ /// Specifies, whether the path equals the root of the server instance.
+ ///
+ public bool IsRoot => (Parts.Count == 0);
- ///
- /// The name of the file that is referenced by this path (if this is
- /// the path to a file).
- ///
- public string? File
+ ///
+ /// The name of the file that is referenced by this path (if this is
+ /// the path to a file).
+ ///
+ public string? File
+ {
+ get
{
- get
- {
if (!TrailingSlash)
{
var part = (Parts.Count > 0) ? Parts[Parts.Count - 1] : null;
@@ -44,38 +43,38 @@ public string? File
return null;
}
- }
+ }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- public WebPath(IReadOnlyList parts, bool trailingSlash)
- {
+ public WebPath(IReadOnlyList parts, bool trailingSlash)
+ {
Parts = parts;
TrailingSlash = trailingSlash;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- ///
- /// Creates a builder that allows to edit this path.
- ///
- /// Specifies, whether the new path will have a trailing slash
- /// The newly created builder instance
- public PathBuilder Edit(bool trailingSlash) => new(Parts, trailingSlash);
+ ///
+ /// Creates a builder that allows to edit this path.
+ ///
+ /// Specifies, whether the new path will have a trailing slash
+ /// The newly created builder instance
+ public PathBuilder Edit(bool trailingSlash) => new(Parts, trailingSlash);
- public override string ToString() => ToString(false);
+ public override string ToString() => ToString(false);
- ///
- /// Generates the string representation of this path.
- ///
- /// Specifies, whether special characters in the path should be percent encoded
- /// The string representation of the path
- public string ToString(bool encoded)
- {
+ ///
+ /// Generates the string representation of this path.
+ ///
+ /// Specifies, whether special characters in the path should be percent encoded
+ /// The string representation of the path
+ public string ToString(bool encoded)
+ {
if (!IsRoot)
{
var parts = Parts.Select(p => (encoded) ? p.Original : p.Value);
@@ -86,8 +85,6 @@ public string ToString(bool encoded)
return "/";
}
- #endregion
-
- }
+ #endregion
}
diff --git a/API/Routing/WebPathPart.cs b/API/Routing/WebPathPart.cs
index fd65e8ef..b211754b 100644
--- a/API/Routing/WebPathPart.cs
+++ b/API/Routing/WebPathPart.cs
@@ -1,29 +1,28 @@
using System;
-namespace GenHTTP.Api.Routing
+namespace GenHTTP.Api.Routing;
+
+///
+/// Represents a part of an URL (between two slashes).
+///
+public class WebPathPart
{
+ private string? _Value = null;
+
+ #region Get-/Setters
///
- /// Represents a part of an URL (between two slashes).
+ /// The string as received by the server (e.g. "some%20path").
///
- public class WebPathPart
- {
- private string? _Value = null;
-
- #region Get-/Setters
-
- ///
- /// The string as received by the server (e.g. "some%20path").
- ///
- public string Original { get; }
+ public string Original { get; }
- ///
- /// The decoded representation of the path (e.g. "some path").
- ///
- public string Value
+ ///
+ /// The decoded representation of the path (e.g. "some path").
+ ///
+ public string Value
+ {
+ get
{
- get
- {
if (_Value is null)
{
_Value = Original.Contains('%') ? Uri.UnescapeDataString(Original) : Original;
@@ -31,35 +30,35 @@ public string Value
return _Value;
}
- }
+ }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- ///
- /// Creates a new part from the original string.
- ///
- /// The original string
- public WebPathPart(string original)
- {
+ ///
+ /// Creates a new part from the original string.
+ ///
+ /// The original string
+ public WebPathPart(string original)
+ {
Original = original;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- public override string ToString() => Value;
+ public override string ToString() => Value;
- public override int GetHashCode() => HashCode.Combine(Original, Value);
+ public override int GetHashCode() => HashCode.Combine(Original, Value);
- public static bool operator ==(WebPathPart part, string value) => part.Original == value || part.Value == value;
+ public static bool operator ==(WebPathPart part, string value) => part.Original == value || part.Value == value;
- public static bool operator !=(WebPathPart part, string value) => part.Original != value && part.Value != value;
+ public static bool operator !=(WebPathPart part, string value) => part.Original != value && part.Value != value;
- public override bool Equals(object? obj)
- {
+ public override bool Equals(object? obj)
+ {
if (ReferenceEquals(this, obj))
{
return true;
@@ -73,8 +72,6 @@ public override bool Equals(object? obj)
return (obj as WebPathPart)?.GetHashCode() == GetHashCode();
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Host.cs b/Engine/Host.cs
index cce3474e..0286d562 100644
--- a/Engine/Host.cs
+++ b/Engine/Host.cs
@@ -1,19 +1,16 @@
using GenHTTP.Api.Infrastructure;
using GenHTTP.Engine.Hosting;
-namespace GenHTTP.Engine
-{
-
- public static class Host
- {
+namespace GenHTTP.Engine;
- ///
- /// Provides a new server host that can be used to run a
- /// server instance of the GenHTTP webserver.
- ///
- /// The host which can be used to run a server instance
- public static IServerHost Create() => new ServerHost();
+public static class Host
+{
- }
+ ///
+ /// Provides a new server host that can be used to run a
+ /// server instance of the GenHTTP webserver.
+ ///
+ /// The host which can be used to run a server instance
+ public static IServerHost Create() => new ServerHost();
}
diff --git a/Engine/Hosting/ServerHost.cs b/Engine/Hosting/ServerHost.cs
index fd25d2c5..a1abde2c 100644
--- a/Engine/Hosting/ServerHost.cs
+++ b/Engine/Hosting/ServerHost.cs
@@ -8,59 +8,58 @@
using GenHTTP.Api.Content;
using GenHTTP.Api.Infrastructure;
-namespace GenHTTP.Engine.Hosting
-{
+namespace GenHTTP.Engine.Hosting;
- public sealed class ServerHost : IServerHost
- {
- private readonly IServerBuilder _Builder = Server.Create();
+public sealed class ServerHost : IServerHost
+{
+ private readonly IServerBuilder _Builder = Server.Create();
- #region Builder facade
+ #region Builder facade
- public IServerHost Backlog(ushort backlog) { _Builder.Backlog(backlog); return this; }
+ public IServerHost Backlog(ushort backlog) { _Builder.Backlog(backlog); return this; }
- public IServerHost Bind(IPAddress address, ushort port) { _Builder.Bind(address, port); return this; }
+ public IServerHost Bind(IPAddress address, ushort port) { _Builder.Bind(address, port); return this; }
- public IServerHost Bind(IPAddress address, ushort port, X509Certificate2 certificate) { _Builder.Bind(address, port, certificate); return this; }
+ public IServerHost Bind(IPAddress address, ushort port, X509Certificate2 certificate) { _Builder.Bind(address, port, certificate); return this; }
- public IServerHost Bind(IPAddress address, ushort port, X509Certificate2 certificate, SslProtocols protocols) { _Builder.Bind(address, port, certificate, protocols); return this; }
+ public IServerHost Bind(IPAddress address, ushort port, X509Certificate2 certificate, SslProtocols protocols) { _Builder.Bind(address, port, certificate, protocols); return this; }
- public IServerHost Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider) { _Builder.Bind(address, port, certificateProvider); return this; }
+ public IServerHost Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider) { _Builder.Bind(address, port, certificateProvider); return this; }
- public IServerHost Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider, SslProtocols protocols) { _Builder.Bind(address, port, certificateProvider, protocols); return this; }
+ public IServerHost Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider, SslProtocols protocols) { _Builder.Bind(address, port, certificateProvider, protocols); return this; }
- public IServerHost Companion(IServerCompanion companion) { _Builder.Companion(companion); return this; }
+ public IServerHost Companion(IServerCompanion companion) { _Builder.Companion(companion); return this; }
- public IServerHost Console() { _Builder.Console(); return this; }
+ public IServerHost Console() { _Builder.Console(); return this; }
- public IServerHost Development(bool developmentMode = true) { _Builder.Development(developmentMode); return this; }
+ public IServerHost Development(bool developmentMode = true) { _Builder.Development(developmentMode); return this; }
- public IServerHost Port(ushort port) { _Builder.Port(port); return this; }
+ public IServerHost Port(ushort port) { _Builder.Port(port); return this; }
- public IServerHost RequestMemoryLimit(uint limit) { _Builder.RequestMemoryLimit(limit); return this; }
+ public IServerHost RequestMemoryLimit(uint limit) { _Builder.RequestMemoryLimit(limit); return this; }
- public IServerHost RequestReadTimeout(TimeSpan timeout) { _Builder.RequestReadTimeout(timeout); return this; }
+ public IServerHost RequestReadTimeout(TimeSpan timeout) { _Builder.RequestReadTimeout(timeout); return this; }
- public IServerHost Handler(IHandlerBuilder handler) { _Builder.Handler(handler); return this; }
+ public IServerHost Handler(IHandlerBuilder handler) { _Builder.Handler(handler); return this; }
- public IServerHost TransferBufferSize(uint bufferSize) { _Builder.TransferBufferSize(bufferSize); return this; }
+ public IServerHost TransferBufferSize(uint bufferSize) { _Builder.TransferBufferSize(bufferSize); return this; }
- public IServerHost Add(IConcernBuilder concern) { _Builder.Add(concern); return this; }
+ public IServerHost Add(IConcernBuilder concern) { _Builder.Add(concern); return this; }
- public IServer Build() => _Builder.Build();
+ public IServer Build() => _Builder.Build();
- #endregion
+ #endregion
- #region Get-/Setters
+ #region Get-/Setters
- public IServer? Instance { get; private set; }
+ public IServer? Instance { get; private set; }
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- public int Run()
- {
+ public int Run()
+ {
try
{
var waitEvent = new ManualResetEvent(false);
@@ -105,32 +104,30 @@ public int Run()
}
}
- public IServerHost Start()
- {
+ public IServerHost Start()
+ {
Stop();
Instance = Build();
return this;
}
- public IServerHost Stop()
- {
+ public IServerHost Stop()
+ {
Instance?.Dispose();
Instance = null;
return this;
}
- public IServerHost Restart()
- {
+ public IServerHost Restart()
+ {
Stop();
Start();
return this;
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Infrastructure/Configuration.cs b/Engine/Infrastructure/Configuration.cs
index a441b2b2..fbe3dfc0 100644
--- a/Engine/Infrastructure/Configuration.cs
+++ b/Engine/Infrastructure/Configuration.cs
@@ -2,20 +2,16 @@
using System.Collections.Generic;
using System.Net;
using System.Security.Authentication;
-
using GenHTTP.Api.Infrastructure;
-namespace GenHTTP.Engine.Infrastructure.Configuration
-{
-
- internal record ServerConfiguration(bool DevelopmentMode, IEnumerable EndPoints,
- NetworkConfiguration Network);
+namespace GenHTTP.Engine.Infrastructure;
- internal record NetworkConfiguration(TimeSpan RequestReadTimeout, uint RequestMemoryLimit,
- uint TransferBufferSize, ushort Backlog);
+internal record ServerConfiguration(bool DevelopmentMode, IEnumerable EndPoints,
+ NetworkConfiguration Network);
- internal record EndPointConfiguration(IPAddress Address, ushort Port, SecurityConfiguration? Security);
+internal record NetworkConfiguration(TimeSpan RequestReadTimeout, uint RequestMemoryLimit,
+ uint TransferBufferSize, ushort Backlog);
- internal record SecurityConfiguration(ICertificateProvider Certificate, SslProtocols Protocols);
+internal record EndPointConfiguration(IPAddress Address, ushort Port, SecurityConfiguration? Security);
-}
+internal record SecurityConfiguration(ICertificateProvider Certificate, SslProtocols Protocols);
diff --git a/Engine/Infrastructure/ConsoleCompanion.cs b/Engine/Infrastructure/ConsoleCompanion.cs
index c6a84012..21bdb971 100644
--- a/Engine/Infrastructure/ConsoleCompanion.cs
+++ b/Engine/Infrastructure/ConsoleCompanion.cs
@@ -4,22 +4,19 @@
using GenHTTP.Api.Infrastructure;
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Engine.Infrastructure
+namespace GenHTTP.Engine.Infrastructure;
+
+internal sealed class ConsoleCompanion : IServerCompanion
{
- internal sealed class ConsoleCompanion : IServerCompanion
+ public void OnRequestHandled(IRequest request, IResponse response)
{
-
- public void OnRequestHandled(IRequest request, IResponse response)
- {
Console.WriteLine($"REQ - {request.Client.IPAddress} - {request.Method.RawMethod} {request.Target.Path} - {response.Status.RawStatus} - {response.ContentLength ?? 0}");
}
- public void OnServerError(ServerErrorScope scope, IPAddress? client, Exception error)
- {
+ public void OnServerError(ServerErrorScope scope, IPAddress? client, Exception error)
+ {
Console.WriteLine($"ERR - {client : 'n/a'} - {scope} - {error}");
}
- }
-
}
diff --git a/Engine/Infrastructure/CoreRouter.cs b/Engine/Infrastructure/CoreRouter.cs
index d17c5837..662425d9 100644
--- a/Engine/Infrastructure/CoreRouter.cs
+++ b/Engine/Infrastructure/CoreRouter.cs
@@ -5,46 +5,43 @@
using GenHTTP.Api.Content;
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Engine.Infrastructure
+namespace GenHTTP.Engine.Infrastructure;
+
+///
+/// Request handler which is installed by the engine as the root handler - all
+/// requests will start processing from here on. Provides core functionality
+/// such as rendering exceptions when they bubble up uncatched.
+///
+internal sealed class CoreRouter : IHandler
{
- ///
- /// Request handler which is installed by the engine as the root handler - all
- /// requests will start processing from here on. Provides core functionality
- /// such as rendering exceptions when they bubble up uncatched.
- ///
- internal sealed class CoreRouter : IHandler
- {
-
- #region Get-/Setters
+ #region Get-/Setters
- public IHandler Parent
- {
- get { throw new NotSupportedException("Core router has no parent"); }
- set { throw new NotSupportedException("Setting core router's parent is not allowed"); }
- }
+ public IHandler Parent
+ {
+ get { throw new NotSupportedException("Core router has no parent"); }
+ set { throw new NotSupportedException("Setting core router's parent is not allowed"); }
+ }
- public IHandler Content { get; }
+ public IHandler Content { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal CoreRouter(IHandlerBuilder content, IEnumerable concerns)
- {
+ internal CoreRouter(IHandlerBuilder content, IEnumerable concerns)
+ {
Content = Concerns.Chain(this, concerns, (p) => content.Build(p));
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- public ValueTask HandleAsync(IRequest request) => Content.HandleAsync(request);
+ public ValueTask HandleAsync(IRequest request) => Content.HandleAsync(request);
- public ValueTask PrepareAsync() => Content.PrepareAsync();
+ public ValueTask PrepareAsync() => Content.PrepareAsync();
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Infrastructure/Endpoints/EndPoint.cs b/Engine/Infrastructure/Endpoints/EndPoint.cs
index 8ae4e351..632450c8 100644
--- a/Engine/Infrastructure/Endpoints/EndPoint.cs
+++ b/Engine/Infrastructure/Endpoints/EndPoint.cs
@@ -6,45 +6,42 @@
using System.Threading.Tasks;
using GenHTTP.Api.Infrastructure;
-
-using GenHTTP.Engine.Infrastructure.Configuration;
-
+using GenHTTP.Engine.Protocol;
using PooledAwait;
-namespace GenHTTP.Engine.Infrastructure.Endpoints
-{
+namespace GenHTTP.Engine.Infrastructure.Endpoints;
- internal abstract class EndPoint : IEndPoint
- {
+internal abstract class EndPoint : IEndPoint
+{
- #region Get-/Setters
+ #region Get-/Setters
- protected IServer Server { get; }
+ protected IServer Server { get; }
- protected NetworkConfiguration Configuration { get; }
+ protected NetworkConfiguration Configuration { get; }
- private Task Task { get; set; }
+ private Task Task { get; set; }
- private IPEndPoint Endpoint { get; }
+ private IPEndPoint Endpoint { get; }
- private Socket Socket { get; }
+ private Socket Socket { get; }
- #endregion
+ #endregion
- #region Basic Information
+ #region Basic Information
- public IPAddress IPAddress { get; }
+ public IPAddress IPAddress { get; }
- public ushort Port { get; }
+ public ushort Port { get; }
- public abstract bool Secure { get; }
+ public abstract bool Secure { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- protected EndPoint(IServer server, IPEndPoint endPoint, NetworkConfiguration configuration)
- {
+ protected EndPoint(IServer server, IPEndPoint endPoint, NetworkConfiguration configuration)
+ {
Server = server;
Endpoint = endPoint;
@@ -68,12 +65,12 @@ protected EndPoint(IServer server, IPEndPoint endPoint, NetworkConfiguration con
Task = Task.Run(() => Listen());
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- private async Task Listen()
- {
+ private async Task Listen()
+ {
try
{
do
@@ -91,30 +88,30 @@ private async Task Listen()
}
}
- private void Handle(Socket client)
- {
+ private void Handle(Socket client)
+ {
using var _ = ExecutionContext.SuppressFlow();
Task.Run(() => Accept(client));
}
- protected abstract PooledValueTask Accept(Socket client);
+ protected abstract PooledValueTask Accept(Socket client);
- protected PooledValueTask Handle(Socket client, Stream inputStream)
- {
+ protected PooledValueTask Handle(Socket client, Stream inputStream)
+ {
client.NoDelay = true;
return new ClientHandler(client, inputStream, Server, this, Configuration).Run();
}
- #endregion
+ #endregion
- #region IDisposable Support
+ #region IDisposable Support
- private bool disposed = false, shuttingDown = false;
+ private bool disposed = false, shuttingDown = false;
- protected virtual void Dispose(bool disposing)
- {
+ protected virtual void Dispose(bool disposing)
+ {
shuttingDown = true;
if (!disposed)
@@ -138,14 +135,12 @@ protected virtual void Dispose(bool disposing)
}
}
- public void Dispose()
- {
+ public void Dispose()
+ {
Dispose(true);
GC.SuppressFinalize(this);
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Infrastructure/Endpoints/EndpointCollection.cs b/Engine/Infrastructure/Endpoints/EndpointCollection.cs
index 837c8307..f56d8d88 100644
--- a/Engine/Infrastructure/Endpoints/EndpointCollection.cs
+++ b/Engine/Infrastructure/Endpoints/EndpointCollection.cs
@@ -3,26 +3,24 @@
using System.Net;
using GenHTTP.Api.Infrastructure;
-using GenHTTP.Engine.Infrastructure.Configuration;
-namespace GenHTTP.Engine.Infrastructure.Endpoints
-{
+namespace GenHTTP.Engine.Infrastructure.Endpoints;
- internal sealed class EndPointCollection : List, IDisposable, IEndPointCollection
- {
+internal sealed class EndPointCollection : List, IDisposable, IEndPointCollection
+{
- #region Get-/Setters
+ #region Get-/Setters
- private IServer Server { get; }
+ private IServer Server { get; }
- private NetworkConfiguration NetworkConfiguration { get; }
+ private NetworkConfiguration NetworkConfiguration { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- public EndPointCollection(IServer server, IEnumerable configuration, NetworkConfiguration networkConfiguration)
- {
+ public EndPointCollection(IServer server, IEnumerable configuration, NetworkConfiguration networkConfiguration)
+ {
Server = server;
NetworkConfiguration = networkConfiguration;
@@ -32,12 +30,12 @@ public EndPointCollection(IServer server, IEnumerable con
}
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- private EndPoint Start(EndPointConfiguration configuration)
- {
+ private EndPoint Start(EndPointConfiguration configuration)
+ {
var endpoint = new IPEndPoint(configuration.Address, configuration.Port);
if (configuration.Security is null)
@@ -50,14 +48,14 @@ private EndPoint Start(EndPointConfiguration configuration)
}
}
- #endregion
+ #endregion
- #region IDisposable Support
+ #region IDisposable Support
- private bool disposed = false;
+ private bool disposed = false;
- public void Dispose()
- {
+ public void Dispose()
+ {
if (!disposed)
{
foreach (IEndPoint endpoint in this)
@@ -80,8 +78,6 @@ public void Dispose()
GC.SuppressFinalize(this);
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Infrastructure/Endpoints/InsecureEndPoint.cs b/Engine/Infrastructure/Endpoints/InsecureEndPoint.cs
index 1ede3487..34b70e25 100644
--- a/Engine/Infrastructure/Endpoints/InsecureEndPoint.cs
+++ b/Engine/Infrastructure/Endpoints/InsecureEndPoint.cs
@@ -2,40 +2,35 @@
using System.Net.Sockets;
using GenHTTP.Api.Infrastructure;
-
-using GenHTTP.Engine.Infrastructure.Configuration;
using GenHTTP.Engine.Utilities;
using PooledAwait;
-namespace GenHTTP.Engine.Infrastructure.Endpoints
-{
+namespace GenHTTP.Engine.Infrastructure.Endpoints;
- internal sealed class InsecureEndPoint : EndPoint
- {
+internal sealed class InsecureEndPoint : EndPoint
+{
- #region Get-/Setters
+ #region Get-/Setters
- public override bool Secure => false;
+ public override bool Secure => false;
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal InsecureEndPoint(IServer server, IPEndPoint endPoint, NetworkConfiguration configuration)
- : base(server, endPoint, configuration)
- {
+ internal InsecureEndPoint(IServer server, IPEndPoint endPoint, NetworkConfiguration configuration)
+ : base(server, endPoint, configuration)
+ {
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- protected override PooledValueTask Accept(Socket client) => Handle(client, new PoolBufferedStream(new NetworkStream(client), Configuration.TransferBufferSize));
+ protected override PooledValueTask Accept(Socket client) => Handle(client, new PoolBufferedStream(new NetworkStream(client), Configuration.TransferBufferSize));
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Infrastructure/Endpoints/SecureEndPoint.cs b/Engine/Infrastructure/Endpoints/SecureEndPoint.cs
index 9c326097..780b813d 100644
--- a/Engine/Infrastructure/Endpoints/SecureEndPoint.cs
+++ b/Engine/Infrastructure/Endpoints/SecureEndPoint.cs
@@ -7,34 +7,31 @@
using System.Threading.Tasks;
using GenHTTP.Api.Infrastructure;
-
-using GenHTTP.Engine.Infrastructure.Configuration;
using GenHTTP.Engine.Protocol;
using GenHTTP.Engine.Utilities;
using PooledAwait;
-namespace GenHTTP.Engine.Infrastructure.Endpoints
-{
+namespace GenHTTP.Engine.Infrastructure.Endpoints;
- internal sealed class SecureEndPoint : EndPoint
- {
+internal sealed class SecureEndPoint : EndPoint
+{
- #region Get-/Setters
+ #region Get-/Setters
- internal SecurityConfiguration Options { get; }
+ internal SecurityConfiguration Options { get; }
- public override bool Secure => true;
+ public override bool Secure => true;
- private SslServerAuthenticationOptions AuthenticationOptions { get; }
+ private SslServerAuthenticationOptions AuthenticationOptions { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal SecureEndPoint(IServer server, IPEndPoint endPoint, SecurityConfiguration options, NetworkConfiguration configuration)
- : base(server, endPoint, configuration)
- {
+ internal SecureEndPoint(IServer server, IPEndPoint endPoint, SecurityConfiguration options, NetworkConfiguration configuration)
+ : base(server, endPoint, configuration)
+ {
Options = options;
AuthenticationOptions = new()
@@ -49,12 +46,12 @@ internal SecureEndPoint(IServer server, IPEndPoint endPoint, SecurityConfigurati
};
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- protected override async PooledValueTask Accept(Socket client)
- {
+ protected override async PooledValueTask Accept(Socket client)
+ {
var stream = await TryAuthenticate(client);
if (stream is not null)
@@ -75,8 +72,8 @@ protected override async PooledValueTask Accept(Socket client)
}
}
- private async ValueTask TryAuthenticate(Socket client)
- {
+ private async ValueTask TryAuthenticate(Socket client)
+ {
try
{
var stream = new SslStream(new NetworkStream(client), false);
@@ -93,8 +90,8 @@ protected override async PooledValueTask Accept(Socket client)
}
}
- private X509Certificate2 SelectCertificate(object sender, string? hostName)
- {
+ private X509Certificate2 SelectCertificate(object sender, string? hostName)
+ {
var certificate = Options.Certificate.Provide(hostName);
if (certificate is null)
@@ -105,8 +102,6 @@ private X509Certificate2 SelectCertificate(object sender, string? hostName)
return certificate;
}
- #endregion
-
- }
+ #endregion
-}
+}
\ No newline at end of file
diff --git a/Engine/Infrastructure/Endpoints/SimpleCertificateProvider.cs b/Engine/Infrastructure/Endpoints/SimpleCertificateProvider.cs
index c2cc8237..a2e9e587 100644
--- a/Engine/Infrastructure/Endpoints/SimpleCertificateProvider.cs
+++ b/Engine/Infrastructure/Endpoints/SimpleCertificateProvider.cs
@@ -2,33 +2,30 @@
using GenHTTP.Api.Infrastructure;
-namespace GenHTTP.Engine.Infrastructure.Endpoints
-{
+namespace GenHTTP.Engine.Infrastructure.Endpoints;
- internal sealed class SimpleCertificateProvider : ICertificateProvider
- {
+internal sealed class SimpleCertificateProvider : ICertificateProvider
+{
- #region Get-/Setters
+ #region Get-/Setters
- internal X509Certificate2 Certificate { get; }
+ internal X509Certificate2 Certificate { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal SimpleCertificateProvider(X509Certificate2 certificate)
- {
+ internal SimpleCertificateProvider(X509Certificate2 certificate)
+ {
Certificate = certificate;
}
- #endregion
-
- #region Functionaliy
+ #endregion
- public X509Certificate2? Provide(string? host) => Certificate;
+ #region Functionaliy
- #endregion
+ public X509Certificate2? Provide(string? host) => Certificate;
- }
+ #endregion
-}
+}
\ No newline at end of file
diff --git a/Engine/Infrastructure/ThreadedServer.cs b/Engine/Infrastructure/ThreadedServer.cs
index 2658fe1b..e0fb6201 100644
--- a/Engine/Infrastructure/ThreadedServer.cs
+++ b/Engine/Infrastructure/ThreadedServer.cs
@@ -4,39 +4,36 @@
using GenHTTP.Api.Content;
using GenHTTP.Api.Infrastructure;
-
-using GenHTTP.Engine.Infrastructure.Configuration;
using GenHTTP.Engine.Infrastructure.Endpoints;
-namespace GenHTTP.Engine.Infrastructure
-{
+namespace GenHTTP.Engine.Infrastructure;
- internal sealed class ThreadedServer : IServer
- {
- private readonly EndPointCollection _EndPoints;
+internal sealed class ThreadedServer : IServer
+{
+ private readonly EndPointCollection _EndPoints;
- #region Get-/Setters
+ #region Get-/Setters
- public string Version { get; }
+ public string Version { get; }
- public bool Running => !disposed;
+ public bool Running => !disposed;
- public bool Development => Configuration.DevelopmentMode;
+ public bool Development => Configuration.DevelopmentMode;
- public IHandler Handler { get; private set; }
+ public IHandler Handler { get; private set; }
- public IServerCompanion? Companion { get; private set; }
+ public IServerCompanion? Companion { get; private set; }
- public IEndPointCollection EndPoints => _EndPoints;
+ public IEndPointCollection EndPoints => _EndPoints;
- internal ServerConfiguration Configuration { get; }
+ internal ServerConfiguration Configuration { get; }
- #endregion
+ #endregion
- #region Constructors
+ #region Constructors
- internal ThreadedServer(IServerCompanion? companion, ServerConfiguration configuration, IHandler handler)
- {
+ internal ThreadedServer(IServerCompanion? companion, ServerConfiguration configuration, IHandler handler)
+ {
Version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "(n/a)";
Companion = companion;
@@ -49,8 +46,8 @@ internal ThreadedServer(IServerCompanion? companion, ServerConfiguration configu
_EndPoints = new(this, configuration.EndPoints, configuration.Network);
}
- private static async ValueTask PrepareHandlerAsync(IHandler handler, IServerCompanion? companion)
- {
+ private static async ValueTask PrepareHandlerAsync(IHandler handler, IServerCompanion? companion)
+ {
try
{
await handler.PrepareAsync();
@@ -61,14 +58,14 @@ private static async ValueTask PrepareHandlerAsync(IHandler handler, IServerComp
}
}
- #endregion
+ #endregion
- #region IDisposable Support
+ #region IDisposable Support
- private bool disposed = false;
+ private bool disposed = false;
- public void Dispose()
- {
+ public void Dispose()
+ {
if (!disposed)
{
_EndPoints.Dispose();
@@ -79,8 +76,6 @@ public void Dispose()
GC.SuppressFinalize(this);
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Infrastructure/ThreadedServerBuilder.cs b/Engine/Infrastructure/ThreadedServerBuilder.cs
index 74fa1e18..9806a96c 100644
--- a/Engine/Infrastructure/ThreadedServerBuilder.cs
+++ b/Engine/Infrastructure/ThreadedServerBuilder.cs
@@ -7,70 +7,67 @@
using GenHTTP.Api.Content;
using GenHTTP.Api.Infrastructure;
-
-using GenHTTP.Engine.Infrastructure.Configuration;
using GenHTTP.Engine.Infrastructure.Endpoints;
using GenHTTP.Modules.ErrorHandling;
-namespace GenHTTP.Engine.Infrastructure
-{
+namespace GenHTTP.Engine.Infrastructure;
- internal sealed class ThreadedServerBuilder : IServerBuilder
- {
- private ushort _Backlog = 1024;
- private ushort _Port = 8080;
+internal sealed class ThreadedServerBuilder : IServerBuilder
+{
+ private ushort _Backlog = 1024;
+ private ushort _Port = 8080;
- private uint _RequestMemoryLimit = 1 * 1024 * 1024; // 1 MB
- private uint _TransferBufferSize = 65 * 1024; // 65 KB
+ private uint _RequestMemoryLimit = 1 * 1024 * 1024; // 1 MB
+ private uint _TransferBufferSize = 65 * 1024; // 65 KB
- private bool _Development = false;
+ private bool _Development = false;
- private TimeSpan _RequestReadTimeout = TimeSpan.FromSeconds(10);
+ private TimeSpan _RequestReadTimeout = TimeSpan.FromSeconds(10);
- private IHandlerBuilder? _Handler;
- private IServerCompanion? _Companion;
+ private IHandlerBuilder? _Handler;
+ private IServerCompanion? _Companion;
- private readonly List _EndPoints = new();
+ private readonly List _EndPoints = new();
- private readonly List _Concerns = new();
+ private readonly List _Concerns = new();
- #region Content
+ #region Content
- public IServerBuilder Handler(IHandlerBuilder handler)
- {
+ public IServerBuilder Handler(IHandlerBuilder handler)
+ {
_Handler = handler;
return this;
}
- #endregion
+ #endregion
- #region Infrastructure
+ #region Infrastructure
- public IServerBuilder Console()
- {
+ public IServerBuilder Console()
+ {
_Companion = new ConsoleCompanion();
return this;
}
- public IServerBuilder Companion(IServerCompanion companion)
- {
+ public IServerBuilder Companion(IServerCompanion companion)
+ {
_Companion = companion;
return this;
}
- public IServerBuilder Development(bool developmentMode = true)
- {
+ public IServerBuilder Development(bool developmentMode = true)
+ {
_Development = developmentMode;
return this;
}
- #endregion
+ #endregion
- #region Binding
+ #region Binding
- public IServerBuilder Port(ushort port)
- {
+ public IServerBuilder Port(ushort port)
+ {
if (port == 0)
{
throw new ArgumentOutOfRangeException(nameof(port));
@@ -80,78 +77,78 @@ public IServerBuilder Port(ushort port)
return this;
}
- public IServerBuilder Bind(IPAddress address, ushort port)
- {
+ public IServerBuilder Bind(IPAddress address, ushort port)
+ {
_EndPoints.Add(new EndPointConfiguration(address, port, null));
return this;
}
- public IServerBuilder Bind(IPAddress address, ushort port, X509Certificate2 certificate)
- {
+ public IServerBuilder Bind(IPAddress address, ushort port, X509Certificate2 certificate)
+ {
return Bind(address, port, new SimpleCertificateProvider(certificate));
}
- public IServerBuilder Bind(IPAddress address, ushort port, X509Certificate2 certificate, SslProtocols protocols)
- {
+ public IServerBuilder Bind(IPAddress address, ushort port, X509Certificate2 certificate, SslProtocols protocols)
+ {
return Bind(address, port, new SimpleCertificateProvider(certificate), protocols);
}
- public IServerBuilder Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider)
- {
+ public IServerBuilder Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider)
+ {
_EndPoints.Add(new EndPointConfiguration(address, port, new SecurityConfiguration(certificateProvider, SslProtocols.Tls12 | SslProtocols.Tls13)));
return this;
}
- public IServerBuilder Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider, SslProtocols protocols)
- {
+ public IServerBuilder Bind(IPAddress address, ushort port, ICertificateProvider certificateProvider, SslProtocols protocols)
+ {
_EndPoints.Add(new EndPointConfiguration(address, port, new SecurityConfiguration(certificateProvider, protocols)));
return this;
}
- #endregion
+ #endregion
- #region Network settings
+ #region Network settings
- public IServerBuilder Backlog(ushort backlog)
- {
+ public IServerBuilder Backlog(ushort backlog)
+ {
_Backlog = backlog;
return this;
}
- public IServerBuilder RequestReadTimeout(TimeSpan timeout)
- {
+ public IServerBuilder RequestReadTimeout(TimeSpan timeout)
+ {
_RequestReadTimeout = timeout;
return this;
}
- public IServerBuilder RequestMemoryLimit(uint limit)
- {
+ public IServerBuilder RequestMemoryLimit(uint limit)
+ {
_RequestMemoryLimit = limit;
return this;
}
- public IServerBuilder TransferBufferSize(uint bufferSize)
- {
+ public IServerBuilder TransferBufferSize(uint bufferSize)
+ {
_TransferBufferSize = bufferSize;
return this;
}
- #endregion
+ #endregion
- #region Extensibility
+ #region Extensibility
- public IServerBuilder Add(IConcernBuilder concern)
- {
+ public IServerBuilder Add(IConcernBuilder concern)
+ {
_Concerns.Add(concern);
return this;
}
- #endregion
+ #endregion
- #region Builder
+ #region Builder
- public IServer Build()
- {
+ public IServer Build()
+ {
if (_Handler is null)
{
throw new BuilderMissingPropertyException("Handler");
@@ -176,8 +173,6 @@ public IServer Build()
return new ThreadedServer(_Companion, config, handler);
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/ChunkedStream.cs b/Engine/Protocol/ChunkedStream.cs
index 3906ab64..804eef46 100644
--- a/Engine/Protocol/ChunkedStream.cs
+++ b/Engine/Protocol/ChunkedStream.cs
@@ -5,66 +5,65 @@
using GenHTTP.Modules.IO.Streaming;
-namespace GenHTTP.Engine.Protocol
+namespace GenHTTP.Engine.Protocol;
+
+///
+/// Implements chunked transfer encoding by letting the client
+/// know how many bytes have been written to the response stream.
+///
+///
+/// Response streams are always wrapped into a chunked stream as
+/// soon as there is no known content length. To avoid this overhead,
+/// specify the length of your content whenever possible.
+///
+public sealed class ChunkedStream : Stream
{
+ private static readonly string NL = "\r\n";
- ///
- /// Implements chunked transfer encoding by letting the client
- /// know how many bytes have been written to the response stream.
- ///
- ///
- /// Response streams are always wrapped into a chunked stream as
- /// soon as there is no known content length. To avoid this overhead,
- /// specify the length of your content whenever possible.
- ///
- public sealed class ChunkedStream : Stream
- {
- private static readonly string NL = "\r\n";
-
- #region Get-/Setters
+ #region Get-/Setters
- public override bool CanRead => false;
+ public override bool CanRead => false;
- public override bool CanSeek => false;
+ public override bool CanSeek => false;
- public override bool CanWrite => true;
+ public override bool CanWrite => true;
- public override long Length => throw new NotSupportedException();
+ public override long Length => throw new NotSupportedException();
- public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
+ public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
- private Stream Target { get; }
+ private Stream Target { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- public ChunkedStream(Stream target)
- {
+ public ChunkedStream(Stream target)
+ {
Target = target;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- public override int Read(byte[] buffer, int offset, int count)
- {
+ public override int Read(byte[] buffer, int offset, int count)
+ {
throw new NotSupportedException();
}
- public override long Seek(long offset, SeekOrigin origin)
- {
+ public override long Seek(long offset, SeekOrigin origin)
+ {
throw new NotSupportedException();
}
- public override void SetLength(long value)
- {
+ public override void SetLength(long value)
+ {
throw new NotSupportedException();
}
- public override void Write(byte[] buffer, int offset, int count)
- {
+ public override void Write(byte[] buffer, int offset, int count)
+ {
if (count > 0)
{
Write(count);
@@ -75,8 +74,8 @@ public override void Write(byte[] buffer, int offset, int count)
}
}
- public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- {
+ public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
if (count > 0)
{
await WriteAsync(count);
@@ -87,8 +86,8 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc
}
}
- public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default)
- {
+ public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default)
+ {
if (!buffer.IsEmpty)
{
await WriteAsync(buffer.Length);
@@ -99,26 +98,24 @@ public override async ValueTask WriteAsync(ReadOnlyMemory buffer, Cancella
}
}
- public async ValueTask FinishAsync()
- {
+ public async ValueTask FinishAsync()
+ {
await WriteAsync("0\r\n\r\n");
}
- public override void Flush()
- {
+ public override void Flush()
+ {
Target.Flush();
}
- public override Task FlushAsync(CancellationToken cancellationToken) => Target.FlushAsync(cancellationToken);
-
- private void Write(int value) => $"{value:X}\r\n".Write(Target);
+ public override Task FlushAsync(CancellationToken cancellationToken) => Target.FlushAsync(cancellationToken);
- private ValueTask WriteAsync(string text) => text.WriteAsync(Target);
+ private void Write(int value) => $"{value:X}\r\n".Write(Target);
- private ValueTask WriteAsync(int value) => $"{value:X}\r\n".WriteAsync(Target);
+ private ValueTask WriteAsync(string text) => text.WriteAsync(Target);
- #endregion
+ private ValueTask WriteAsync(int value) => $"{value:X}\r\n".WriteAsync(Target);
- }
+ #endregion
}
diff --git a/Engine/Protocol/ClientConnection.cs b/Engine/Protocol/ClientConnection.cs
index c680859b..4c0ec66e 100644
--- a/Engine/Protocol/ClientConnection.cs
+++ b/Engine/Protocol/ClientConnection.cs
@@ -3,9 +3,6 @@
using GenHTTP.Api.Infrastructure;
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Engine.Protocol
-{
+namespace GenHTTP.Engine.Protocol;
- internal record ClientConnection(IPAddress IPAddress, ClientProtocol? Protocol, string? Host) : IClientConnection;
-
-}
+internal record ClientConnection(IPAddress IPAddress, ClientProtocol? Protocol, string? Host) : IClientConnection;
diff --git a/Engine/Protocol/ClientHandler.cs b/Engine/Protocol/ClientHandler.cs
index d6bc4ba8..200a3ac8 100644
--- a/Engine/Protocol/ClientHandler.cs
+++ b/Engine/Protocol/ClientHandler.cs
@@ -3,55 +3,49 @@
using System.IO;
using System.IO.Pipelines;
using System.Net.Sockets;
-
using GenHTTP.Api.Infrastructure;
using GenHTTP.Api.Protocol;
-
-using GenHTTP.Engine.Infrastructure.Configuration;
-using GenHTTP.Engine.Protocol;
+using GenHTTP.Engine.Infrastructure;
using GenHTTP.Engine.Protocol.Parser;
-
using GenHTTP.Modules.IO.Strings;
-
using PooledAwait;
-namespace GenHTTP.Engine
+namespace GenHTTP.Engine.Protocol;
+
+///
+/// Maintains a single connection to a client, continuously reading
+/// requests and generating responses.
+///
+///
+/// Implements keep alive and maintains the connection state (e.g. by
+/// closing it after the last request has been handled).
+///
+internal sealed class ClientHandler
{
+ private static readonly StreamPipeReaderOptions READER_OPTIONS = new(pool: MemoryPool.Shared, leaveOpen: true, bufferSize: 65536);
- ///
- /// Maintains a single connection to a client, continuously reading
- /// requests and generating responses.
- ///
- ///
- /// Implements keep alive and maintains the connection state (e.g. by
- /// closing it after the last request has been handled).
- ///
- internal sealed class ClientHandler
- {
- private static readonly StreamPipeReaderOptions READER_OPTIONS = new(pool: MemoryPool.Shared, leaveOpen: true, bufferSize: 65536);
-
- #region Get-/Setter
+ #region Get-/Setter
- public IServer Server { get; }
+ public IServer Server { get; }
- public IEndPoint EndPoint { get; }
+ public IEndPoint EndPoint { get; }
- internal NetworkConfiguration Configuration { get; }
+ internal NetworkConfiguration Configuration { get; }
- internal Socket Connection { get; }
+ internal Socket Connection { get; }
- internal Stream Stream { get; }
+ internal Stream Stream { get; }
- private bool? KeepAlive { get; set; }
+ private bool? KeepAlive { get; set; }
- private ResponseHandler ResponseHandler { get; set; }
+ private ResponseHandler ResponseHandler { get; set; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal ClientHandler(Socket socket, Stream stream, IServer server, IEndPoint endPoint, NetworkConfiguration config)
- {
+ internal ClientHandler(Socket socket, Stream stream, IServer server, IEndPoint endPoint, NetworkConfiguration config)
+ {
Server = server;
EndPoint = endPoint;
@@ -63,12 +57,12 @@ internal ClientHandler(Socket socket, Stream stream, IServer server, IEndPoint e
ResponseHandler = new ResponseHandler(Server, Stream, Configuration);
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- internal async PooledValueTask Run()
- {
+ internal async PooledValueTask Run()
+ {
try
{
await HandlePipe(PipeReader.Create(Stream, READER_OPTIONS));
@@ -103,8 +97,8 @@ internal async PooledValueTask Run()
}
}
- private async PooledValueTask HandlePipe(PipeReader reader)
- {
+ private async PooledValueTask HandlePipe(PipeReader reader)
+ {
try
{
using var buffer = new RequestBuffer(reader, Configuration);
@@ -142,8 +136,8 @@ private async PooledValueTask HandlePipe(PipeReader reader)
}
}
- private async PooledValueTask HandleRequest(RequestBuilder builder, bool dataRemaining)
- {
+ private async PooledValueTask HandleRequest(RequestBuilder builder, bool dataRemaining)
+ {
using var request = builder.Connection(Server, EndPoint, Connection.GetAddress()).Build();
KeepAlive ??= request["Connection"]?.Equals("Keep-Alive", StringComparison.InvariantCultureIgnoreCase) ?? (request.ProtocolType == HttpProtocol.Http_1_1);
@@ -157,8 +151,8 @@ private async PooledValueTask HandleRequest(RequestBuilder builder, bool d
return (success && keepAlive);
}
- private async PooledValueTask SendError(Exception e, ResponseStatus status)
- {
+ private async PooledValueTask SendError(Exception e, ResponseStatus status)
+ {
try
{
var message = Server.Development ? e.ToString() : e.Message;
@@ -172,8 +166,6 @@ private async PooledValueTask SendError(Exception e, ResponseStatus status)
catch { /* no recovery here */ }
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/CookieCollection.cs b/Engine/Protocol/CookieCollection.cs
index 5e095de5..036ef6b9 100644
--- a/Engine/Protocol/CookieCollection.cs
+++ b/Engine/Protocol/CookieCollection.cs
@@ -5,20 +5,19 @@
using GenHTTP.Engine.Utilities;
-namespace GenHTTP.Engine.Protocol
+namespace GenHTTP.Engine.Protocol;
+
+internal sealed class CookieCollection : PooledDictionary, ICookieCollection
{
+ internal const int DEFAULT_SIZE = 6;
- internal sealed class CookieCollection : PooledDictionary, ICookieCollection
+ internal CookieCollection() : base(DEFAULT_SIZE, StringComparer.InvariantCultureIgnoreCase)
{
- internal const int DEFAULT_SIZE = 6;
-
- internal CookieCollection() : base(DEFAULT_SIZE, StringComparer.InvariantCultureIgnoreCase)
- {
}
- internal void Add(string header)
- {
+ internal void Add(string header)
+ {
foreach (var cookie in Parse(header))
{
if (!ContainsKey(cookie.Name))
@@ -28,8 +27,8 @@ internal void Add(string header)
}
}
- private static List Parse(string value)
- {
+ private static List Parse(string value)
+ {
var result = new List(2);
var cookies = value.Split("; ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
@@ -47,6 +46,4 @@ private static List Parse(string value)
return result;
}
- }
-
}
diff --git a/Engine/Protocol/DateHeader.cs b/Engine/Protocol/DateHeader.cs
index 7fb2945d..055d1db1 100644
--- a/Engine/Protocol/DateHeader.cs
+++ b/Engine/Protocol/DateHeader.cs
@@ -1,22 +1,21 @@
using System;
-namespace GenHTTP.Engine.Protocol
+namespace GenHTTP.Engine.Protocol;
+
+///
+/// Caches the value of the date header for one second
+/// before creating a new value, saving some allocations.
+///
+public static class DateHeader
{
-
- ///
- /// Caches the value of the date header for one second
- /// before creating a new value, saving some allocations.
- ///
- public static class DateHeader
- {
- private static string _Value = string.Empty;
+ private static string _Value = string.Empty;
- private static byte _Second = 61;
+ private static byte _Second = 61;
- #region Functionality
+ #region Functionality
- public static string GetValue()
- {
+ public static string GetValue()
+ {
var now = DateTime.UtcNow;
var second = now.Second;
@@ -30,8 +29,6 @@ public static string GetValue()
return _Value;
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/ForwardingCollection.cs b/Engine/Protocol/ForwardingCollection.cs
index 4d8cc0d0..d0fbbc27 100644
--- a/Engine/Protocol/ForwardingCollection.cs
+++ b/Engine/Protocol/ForwardingCollection.cs
@@ -4,30 +4,29 @@
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Engine.Protocol
-{
+namespace GenHTTP.Engine.Protocol;
- ///
- /// Parses and stores forwarding information passed by proxy
- /// servers along with the request.
- ///
- internal sealed class ForwardingCollection : List, IForwardingCollection
- {
- private const int DEFAULT_SIZE = 1;
+///
+/// Parses and stores forwarding information passed by proxy
+/// servers along with the request.
+///
+internal sealed class ForwardingCollection : List, IForwardingCollection
+{
+ private const int DEFAULT_SIZE = 1;
- private const string HEADER_FOR = "X-Forwarded-For";
- private const string HEADER_HOST = "X-Forwarded-Host";
- private const string HEADER_PROTO = "X-Forwarded-Proto";
+ private const string HEADER_FOR = "X-Forwarded-For";
+ private const string HEADER_HOST = "X-Forwarded-Host";
+ private const string HEADER_PROTO = "X-Forwarded-Proto";
- internal ForwardingCollection() : base(DEFAULT_SIZE)
- {
+ internal ForwardingCollection() : base(DEFAULT_SIZE)
+ {
}
- internal void Add(string header) => AddRange(Parse(header));
+ internal void Add(string header) => AddRange(Parse(header));
- internal void TryAddLegacy(RequestHeaderCollection headers)
- {
+ internal void TryAddLegacy(RequestHeaderCollection headers)
+ {
IPAddress? address = null;
ClientProtocol? protocol = null;
@@ -49,8 +48,8 @@ internal void TryAddLegacy(RequestHeaderCollection headers)
}
}
- private static IEnumerable Parse(string value)
- {
+ private static IEnumerable Parse(string value)
+ {
var forwardings = value.Split(',', StringSplitOptions.RemoveEmptyEntries);
foreach (var forwarding in forwardings)
@@ -93,8 +92,8 @@ private static IEnumerable Parse(string value)
}
}
- private static ClientProtocol? ParseProtocol(string? protocol)
- {
+ private static ClientProtocol? ParseProtocol(string? protocol)
+ {
if (protocol != null)
{
if (string.Equals(protocol, "https", StringComparison.OrdinalIgnoreCase))
@@ -110,8 +109,8 @@ private static IEnumerable Parse(string value)
return null;
}
- private static IPAddress? ParseAddress(string? address)
- {
+ private static IPAddress? ParseAddress(string? address)
+ {
if (address != null)
{
if (IPAddress.TryParse(address, out var ip))
@@ -123,6 +122,4 @@ private static IEnumerable Parse(string value)
return null;
}
- }
-
}
diff --git a/Engine/Protocol/Parser/ChunkedContentParser.cs b/Engine/Protocol/Parser/ChunkedContentParser.cs
index 3e78ffa5..4353ada6 100644
--- a/Engine/Protocol/Parser/ChunkedContentParser.cs
+++ b/Engine/Protocol/Parser/ChunkedContentParser.cs
@@ -4,43 +4,41 @@
using System.Threading.Tasks;
using GenHTTP.Api.Protocol;
-
-using GenHTTP.Engine.Infrastructure.Configuration;
+using GenHTTP.Engine.Infrastructure;
using GenHTTP.Engine.Protocol.Parser.Conversion;
-namespace GenHTTP.Engine.Protocol.Parser
+namespace GenHTTP.Engine.Protocol.Parser;
+
+///
+/// Reads the chunked encoded body of a client request into
+/// a stream.
+///
+///
+/// As we cannot know the length of the request beforehand,
+/// this will always use a file stream for buffering.
+///
+internal sealed class ChunkedContentParser
{
- ///
- /// Reads the chunked encoded body of a client request into
- /// a stream.
- ///
- ///
- /// As we cannot know the length of the request beforehand,
- /// this will always use a file stream for buffering.
- ///
- internal sealed class ChunkedContentParser
- {
-
- #region Get-/Setters
+ #region Get-/Setters
- private NetworkConfiguration Configuration { get; }
+ private NetworkConfiguration Configuration { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal ChunkedContentParser(NetworkConfiguration networkConfiguration)
- {
+ internal ChunkedContentParser(NetworkConfiguration networkConfiguration)
+ {
Configuration = networkConfiguration;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- internal async ValueTask GetBody(RequestBuffer buffer)
- {
+ internal async ValueTask GetBody(RequestBuffer buffer)
+ {
var body = TemporaryFileStream.Create();
var bufferSize = Configuration.TransferBufferSize;
@@ -52,8 +50,8 @@ internal async ValueTask GetBody(RequestBuffer buffer)
return body;
}
- private static async ValueTask NextChunkAsync(RequestBuffer buffer, Stream target, uint bufferSize)
- {
+ private static async ValueTask NextChunkAsync(RequestBuffer buffer, Stream target, uint bufferSize)
+ {
await EnsureDataAsync(buffer);
//
@@ -81,8 +79,8 @@ private static async ValueTask NextChunkAsync(RequestBuffer buffer, Stream
}
}
- private static long GetChunkSize(RequestBuffer buffer)
- {
+ private static long GetChunkSize(RequestBuffer buffer)
+ {
var reader = new SequenceReader(buffer.Data);
if (reader.IsNext((byte)'0'))
@@ -109,8 +107,8 @@ private static long GetChunkSize(RequestBuffer buffer)
}
}
- private static async ValueTask EnsureDataAsync(RequestBuffer buffer)
- {
+ private static async ValueTask EnsureDataAsync(RequestBuffer buffer)
+ {
if (buffer.ReadRequired)
{
if (await buffer.ReadAsync() == null)
@@ -120,8 +118,6 @@ private static async ValueTask EnsureDataAsync(RequestBuffer buffer)
}
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/Parser/Conversion/HeaderConverter.cs b/Engine/Protocol/Parser/Conversion/HeaderConverter.cs
index 7eb3c08c..586603c6 100644
--- a/Engine/Protocol/Parser/Conversion/HeaderConverter.cs
+++ b/Engine/Protocol/Parser/Conversion/HeaderConverter.cs
@@ -1,16 +1,15 @@
using System.Buffers;
-namespace GenHTTP.Engine.Protocol.Parser.Conversion
-{
+namespace GenHTTP.Engine.Protocol.Parser.Conversion;
- internal static class HeaderConverter
- {
- private static readonly string[] KNOWN_HEADERS = new[] { "Host", "User-Agent", "Accept", "Content-Type", "Content-Length" };
+internal static class HeaderConverter
+{
+ private static readonly string[] KNOWN_HEADERS = new[] { "Host", "User-Agent", "Accept", "Content-Type", "Content-Length" };
- private static readonly string[] KNOWN_VALUES = new[] { "*/*" };
+ private static readonly string[] KNOWN_VALUES = new[] { "*/*" };
- internal static string ToKey(ReadOnlySequence value)
- {
+ internal static string ToKey(ReadOnlySequence value)
+ {
foreach (var known in KNOWN_HEADERS)
{
if (ValueConverter.CompareTo(value, known)) return known;
@@ -19,8 +18,8 @@ internal static string ToKey(ReadOnlySequence value)
return ValueConverter.GetString(value);
}
- internal static string ToValue(ReadOnlySequence value)
- {
+ internal static string ToValue(ReadOnlySequence value)
+ {
foreach (var known in KNOWN_VALUES)
{
if (ValueConverter.CompareTo(value, known)) return known;
@@ -29,6 +28,4 @@ internal static string ToValue(ReadOnlySequence value)
return ValueConverter.GetString(value);
}
- }
-
}
diff --git a/Engine/Protocol/Parser/Conversion/MethodConverter.cs b/Engine/Protocol/Parser/Conversion/MethodConverter.cs
index abf8c355..2f1e678f 100644
--- a/Engine/Protocol/Parser/Conversion/MethodConverter.cs
+++ b/Engine/Protocol/Parser/Conversion/MethodConverter.cs
@@ -3,24 +3,23 @@
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Engine.Protocol.Parser.Conversion
-{
+namespace GenHTTP.Engine.Protocol.Parser.Conversion;
- internal static class MethodConverter
+internal static class MethodConverter
+{
+ private static readonly Dictionary KNOWN_METHODS = new(7)
{
- private static readonly Dictionary KNOWN_METHODS = new(7)
- {
- { "GET", RequestMethod.GET },
- { "HEAD", RequestMethod.HEAD },
- { "POST", RequestMethod.POST },
- { "PUT", RequestMethod.PUT },
- { "PATCH", RequestMethod.PATCH },
- { "DELETE", RequestMethod.DELETE },
- { "OPTIONS", RequestMethod.OPTIONS }
- };
+ { "GET", RequestMethod.GET },
+ { "HEAD", RequestMethod.HEAD },
+ { "POST", RequestMethod.POST },
+ { "PUT", RequestMethod.PUT },
+ { "PATCH", RequestMethod.PATCH },
+ { "DELETE", RequestMethod.DELETE },
+ { "OPTIONS", RequestMethod.OPTIONS }
+ };
- internal static FlexibleRequestMethod ToRequestMethod(ReadOnlySequence value)
- {
+ internal static FlexibleRequestMethod ToRequestMethod(ReadOnlySequence value)
+ {
foreach (var kv in KNOWN_METHODS)
{
if (ValueConverter.CompareTo(value, kv.Key))
@@ -32,6 +31,4 @@ internal static FlexibleRequestMethod ToRequestMethod(ReadOnlySequence val
return FlexibleRequestMethod.Get(ValueConverter.GetString(value));
}
- }
-
}
diff --git a/Engine/Protocol/Parser/Conversion/PathConverter.cs b/Engine/Protocol/Parser/Conversion/PathConverter.cs
index c8c24e8d..11d4891a 100644
--- a/Engine/Protocol/Parser/Conversion/PathConverter.cs
+++ b/Engine/Protocol/Parser/Conversion/PathConverter.cs
@@ -3,16 +3,15 @@
using GenHTTP.Api.Routing;
-namespace GenHTTP.Engine.Protocol.Parser.Conversion
-{
+namespace GenHTTP.Engine.Protocol.Parser.Conversion;
- internal static class PathConverter
- {
+internal static class PathConverter
+{
- private static readonly WebPath ROOT = new(new List(), true);
+ private static readonly WebPath ROOT = new(new List(), true);
- internal static WebPath ToPath(ReadOnlySequence value)
- {
+ internal static WebPath ToPath(ReadOnlySequence value)
+ {
if (value.Length == 1)
{
return ROOT;
@@ -40,6 +39,4 @@ internal static WebPath ToPath(ReadOnlySequence value)
return new WebPath(parts, true);
}
- }
-
}
diff --git a/Engine/Protocol/Parser/Conversion/ProtocolConverter.cs b/Engine/Protocol/Parser/Conversion/ProtocolConverter.cs
index 83ff00c4..db159576 100644
--- a/Engine/Protocol/Parser/Conversion/ProtocolConverter.cs
+++ b/Engine/Protocol/Parser/Conversion/ProtocolConverter.cs
@@ -2,14 +2,13 @@
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Engine.Protocol.Parser.Conversion
+namespace GenHTTP.Engine.Protocol.Parser.Conversion;
+
+internal static class ProtocolConverter
{
- internal static class ProtocolConverter
+ internal static HttpProtocol ToProtocol(ReadOnlySequence value)
{
-
- internal static HttpProtocol ToProtocol(ReadOnlySequence value)
- {
var reader = new SequenceReader(value);
if (value.Length != 8)
@@ -35,6 +34,4 @@ internal static HttpProtocol ToProtocol(ReadOnlySequence value)
throw new ProtocolException($"Unexpected protocol version '{versionString}'");
}
- }
-
}
diff --git a/Engine/Protocol/Parser/Conversion/QueryConverter.cs b/Engine/Protocol/Parser/Conversion/QueryConverter.cs
index 955caff3..e7467b46 100644
--- a/Engine/Protocol/Parser/Conversion/QueryConverter.cs
+++ b/Engine/Protocol/Parser/Conversion/QueryConverter.cs
@@ -1,14 +1,13 @@
using System;
using System.Buffers;
-namespace GenHTTP.Engine.Protocol.Parser.Conversion
+namespace GenHTTP.Engine.Protocol.Parser.Conversion;
+
+internal static class QueryConverter
{
- internal static class QueryConverter
+ internal static RequestQuery? ToQuery(ReadOnlySequence value)
{
-
- internal static RequestQuery? ToQuery(ReadOnlySequence value)
- {
if (!value.IsEmpty)
{
var query = new RequestQuery();
@@ -32,8 +31,8 @@ internal static class QueryConverter
return null;
}
- private static void AppendSegment(RequestQuery query, ReadOnlySequence segment)
- {
+ private static void AppendSegment(RequestQuery query, ReadOnlySequence segment)
+ {
if (!segment.IsEmpty)
{
var reader = new SequenceReader(segment);
@@ -60,6 +59,4 @@ private static void AppendSegment(RequestQuery query, ReadOnlySequence seg
}
}
- }
-
}
diff --git a/Engine/Protocol/Parser/Conversion/ValueConverter.cs b/Engine/Protocol/Parser/Conversion/ValueConverter.cs
index 4076f594..22374f2f 100644
--- a/Engine/Protocol/Parser/Conversion/ValueConverter.cs
+++ b/Engine/Protocol/Parser/Conversion/ValueConverter.cs
@@ -1,16 +1,15 @@
using System.Buffers;
using System.Text;
-namespace GenHTTP.Engine.Protocol.Parser.Conversion
-{
+namespace GenHTTP.Engine.Protocol.Parser.Conversion;
- internal static class ValueConverter
- {
+internal static class ValueConverter
+{
- private static readonly Encoding ASCII = Encoding.ASCII;
+ private static readonly Encoding ASCII = Encoding.ASCII;
- internal static bool CompareTo(ReadOnlySequence buffer, string expected)
- {
+ internal static bool CompareTo(ReadOnlySequence buffer, string expected)
+ {
var i = 0;
if (buffer.Length != expected.Length)
@@ -32,8 +31,8 @@ internal static bool CompareTo(ReadOnlySequence buffer, string expected)
return true;
}
- internal static string GetString(ReadOnlySequence buffer)
- {
+ internal static string GetString(ReadOnlySequence buffer)
+ {
if (buffer.Length > 0)
{
var result = string.Create((int)buffer.Length, buffer, (span, sequence) =>
@@ -51,6 +50,4 @@ internal static string GetString(ReadOnlySequence buffer)
return string.Empty;
}
- }
-
}
diff --git a/Engine/Protocol/Parser/RequestContentParser.cs b/Engine/Protocol/Parser/RequestContentParser.cs
index 03f3841a..71854c5f 100644
--- a/Engine/Protocol/Parser/RequestContentParser.cs
+++ b/Engine/Protocol/Parser/RequestContentParser.cs
@@ -1,40 +1,39 @@
using System;
using System.IO;
using System.Threading.Tasks;
-using GenHTTP.Engine.Infrastructure.Configuration;
+using GenHTTP.Engine.Infrastructure;
-namespace GenHTTP.Engine.Protocol.Parser
-{
+namespace GenHTTP.Engine.Protocol.Parser;
- ///
- /// Efficiently reads the body from the HTTP request, storing it
- /// in a temporary file if it exceeds the buffering limits.
- ///
- internal sealed class RequestContentParser
- {
+///
+/// Efficiently reads the body from the HTTP request, storing it
+/// in a temporary file if it exceeds the buffering limits.
+///
+internal sealed class RequestContentParser
+{
- #region Get-/Setters
+ #region Get-/Setters
- internal long Length { get; }
+ internal long Length { get; }
- internal NetworkConfiguration Configuration { get; }
+ internal NetworkConfiguration Configuration { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal RequestContentParser(long length, NetworkConfiguration configuration)
- {
+ internal RequestContentParser(long length, NetworkConfiguration configuration)
+ {
Length = length;
Configuration = configuration;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- internal async Task GetBody(RequestBuffer buffer)
- {
+ internal async Task GetBody(RequestBuffer buffer)
+ {
var body = Length > Configuration.RequestMemoryLimit ? TemporaryFileStream.Create() : new MemoryStream((int)Length);
await CopyAsync(buffer, body, Length, Configuration.TransferBufferSize);
@@ -44,8 +43,8 @@ internal async Task GetBody(RequestBuffer buffer)
return body;
}
- internal static async ValueTask CopyAsync(RequestBuffer source, Stream target, long length, uint bufferSize)
- {
+ internal static async ValueTask CopyAsync(RequestBuffer source, Stream target, long length, uint bufferSize)
+ {
var toFetch = length;
while (toFetch > 0)
@@ -74,8 +73,6 @@ internal static async ValueTask CopyAsync(RequestBuffer source, Stream target, l
}
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/Parser/RequestParser.cs b/Engine/Protocol/Parser/RequestParser.cs
index d58b8496..072d627d 100644
--- a/Engine/Protocol/Parser/RequestParser.cs
+++ b/Engine/Protocol/Parser/RequestParser.cs
@@ -1,50 +1,49 @@
using GenHTTP.Api.Protocol;
-using GenHTTP.Engine.Infrastructure.Configuration;
+using GenHTTP.Engine.Infrastructure;
using GenHTTP.Engine.Protocol.Parser.Conversion;
using PooledAwait;
-namespace GenHTTP.Engine.Protocol.Parser
+namespace GenHTTP.Engine.Protocol.Parser;
+
+///
+/// Reads the next HTTP request to be handled by the server from
+/// the client connection.
+///
+///
+/// Be aware that this code path is heavily optimized for low
+/// memory allocations. Changes to this class should allocate
+/// as few memory as possible to avoid the performance of
+/// the server from being impacted in a negative manner.
+///
+internal sealed class RequestParser
{
+ private RequestBuilder? _Builder;
- ///
- /// Reads the next HTTP request to be handled by the server from
- /// the client connection.
- ///
- ///
- /// Be aware that this code path is heavily optimized for low
- /// memory allocations. Changes to this class should allocate
- /// as few memory as possible to avoid the performance of
- /// the server from being impacted in a negative manner.
- ///
- internal sealed class RequestParser
- {
- private RequestBuilder? _Builder;
-
- #region Get-/Setters
+ #region Get-/Setters
- private NetworkConfiguration Configuration { get; }
+ private NetworkConfiguration Configuration { get; }
- private RequestBuilder Request => _Builder ??= new();
+ private RequestBuilder Request => _Builder ??= new();
- private RequestScanner Scanner { get; }
+ private RequestScanner Scanner { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal RequestParser(NetworkConfiguration configuration)
- {
+ internal RequestParser(NetworkConfiguration configuration)
+ {
Configuration = configuration;
Scanner = new();
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- internal async PooledValueTask TryParseAsync(RequestBuffer buffer)
- {
+ internal async PooledValueTask TryParseAsync(RequestBuffer buffer)
+ {
if (!await Type(buffer))
{
if (!buffer.Data.IsEmpty)
@@ -69,8 +68,8 @@ internal RequestParser(NetworkConfiguration configuration)
return result;
}
- private async PooledValueTask Type(RequestBuffer buffer)
- {
+ private async PooledValueTask Type(RequestBuffer buffer)
+ {
Scanner.Mode = ScannerMode.Words;
if (await Scanner.Next(buffer, RequestToken.Word, allowNone: true))
@@ -84,8 +83,8 @@ private async PooledValueTask Type(RequestBuffer buffer)
}
}
- private async PooledValueTask Path(RequestBuffer buffer)
- {
+ private async PooledValueTask Path(RequestBuffer buffer)
+ {
Scanner.Mode = ScannerMode.Path;
var token = await Scanner.Next(buffer);
@@ -118,8 +117,8 @@ private async PooledValueTask Path(RequestBuffer buffer)
}
}
- private async PooledValueTask Protocol(RequestBuffer buffer)
- {
+ private async PooledValueTask Protocol(RequestBuffer buffer)
+ {
Scanner.Mode = ScannerMode.Words;
if (await Scanner.Next(buffer, RequestToken.Word))
@@ -128,8 +127,8 @@ private async PooledValueTask Protocol(RequestBuffer buffer)
}
}
- private async PooledValueTask Headers(RequestBuffer buffer)
- {
+ private async PooledValueTask Headers(RequestBuffer buffer)
+ {
Scanner.Mode = ScannerMode.HeaderKey;
while (await Scanner.Next(buffer) == RequestToken.Word)
@@ -147,8 +146,8 @@ private async PooledValueTask Headers(RequestBuffer buffer)
}
}
- private async PooledValueTask Body(RequestBuffer buffer)
- {
+ private async PooledValueTask Body(RequestBuffer buffer)
+ {
if (Request.Headers.TryGetValue("Content-Length", out var bodyLength))
{
if (long.TryParse(bodyLength, out var length))
@@ -176,8 +175,6 @@ private async PooledValueTask Body(RequestBuffer buffer)
}
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/Parser/RequestScanner.cs b/Engine/Protocol/Parser/RequestScanner.cs
index f53fabd4..5bb60cf6 100644
--- a/Engine/Protocol/Parser/RequestScanner.cs
+++ b/Engine/Protocol/Parser/RequestScanner.cs
@@ -4,26 +4,25 @@
using PooledAwait;
-namespace GenHTTP.Engine.Protocol.Parser
-{
+namespace GenHTTP.Engine.Protocol.Parser;
- internal sealed class RequestScanner
- {
+internal sealed class RequestScanner
+{
- internal RequestToken Current { get; private set; }
+ internal RequestToken Current { get; private set; }
- internal ReadOnlySequence Value { get; private set; }
+ internal ReadOnlySequence Value { get; private set; }
- internal ScannerMode Mode { get; set; }
+ internal ScannerMode Mode { get; set; }
- internal RequestScanner()
- {
+ internal RequestScanner()
+ {
Current = RequestToken.None;
Mode = ScannerMode.Words;
}
- internal async PooledValueTask Next(RequestBuffer buffer, RequestToken expectedToken, bool allowNone = false, bool includeWhitespace = false)
- {
+ internal async PooledValueTask Next(RequestBuffer buffer, RequestToken expectedToken, bool allowNone = false, bool includeWhitespace = false)
+ {
var read = await Next(buffer, forceRead: false, includeWhitespace: includeWhitespace);
if (allowNone && (read == RequestToken.None))
@@ -39,8 +38,8 @@ internal async PooledValueTask Next(RequestBuffer buffer, RequestToken exp
return true;
}
- internal async PooledValueTask Next(RequestBuffer buffer, bool forceRead = false, bool includeWhitespace = false)
- {
+ internal async PooledValueTask Next(RequestBuffer buffer, bool forceRead = false, bool includeWhitespace = false)
+ {
// ensure we have data to be scanned
if (await Fill(buffer, forceRead))
{
@@ -63,8 +62,8 @@ internal async PooledValueTask Next(RequestBuffer buffer, bool for
}
}
- private RequestToken? ScanData(RequestBuffer buffer, bool includeWhitespace = false)
- {
+ private RequestToken? ScanData(RequestBuffer buffer, bool includeWhitespace = false)
+ {
if (SkipWhitespace(buffer) && includeWhitespace)
{
Value = new();
@@ -115,8 +114,8 @@ internal async PooledValueTask Next(RequestBuffer buffer, bool for
return null;
}
- private static bool SkipWhitespace(RequestBuffer buffer)
- {
+ private static bool SkipWhitespace(RequestBuffer buffer)
+ {
var count = 0;
var done = false;
@@ -149,8 +148,8 @@ private static bool SkipWhitespace(RequestBuffer buffer)
return (count > 0);
}
- private static bool IsNewLine(RequestBuffer buffer)
- {
+ private static bool IsNewLine(RequestBuffer buffer)
+ {
if (buffer.Data.FirstSpan[0] == (byte)'\r')
{
buffer.Advance(2);
@@ -160,8 +159,8 @@ private static bool IsNewLine(RequestBuffer buffer)
return false;
}
- private bool ReadTo(RequestBuffer buffer, char delimiter, char? boundary = null, byte skipAdditionally = 0)
- {
+ private bool ReadTo(RequestBuffer buffer, char delimiter, char? boundary = null, byte skipAdditionally = 0)
+ {
var reader = new SequenceReader(buffer.Data);
if (reader.TryReadTo(out ReadOnlySequence value, (byte)delimiter, true))
@@ -188,8 +187,8 @@ private bool ReadTo(RequestBuffer buffer, char delimiter, char? boundary = null,
return false;
}
- private static async PooledValueTask Fill(RequestBuffer buffer, bool force = false)
- {
+ private static async PooledValueTask Fill(RequestBuffer buffer, bool force = false)
+ {
if (buffer.ReadRequired || force)
{
await buffer.ReadAsync(force);
@@ -198,6 +197,4 @@ private static async PooledValueTask Fill(RequestBuffer buffer, bool force
return !buffer.Data.IsEmpty;
}
- }
-
}
diff --git a/Engine/Protocol/Parser/RequestToken.cs b/Engine/Protocol/Parser/RequestToken.cs
index 9aafc5c7..298283cd 100644
--- a/Engine/Protocol/Parser/RequestToken.cs
+++ b/Engine/Protocol/Parser/RequestToken.cs
@@ -1,13 +1,10 @@
-namespace GenHTTP.Engine.Protocol.Parser
-{
-
- internal enum RequestToken
- {
- None,
- Word,
- Path,
- PathWithQuery,
- NewLine
- }
+namespace GenHTTP.Engine.Protocol.Parser;
+internal enum RequestToken
+{
+ None,
+ Word,
+ Path,
+ PathWithQuery,
+ NewLine
}
diff --git a/Engine/Protocol/Parser/ScannerMode.cs b/Engine/Protocol/Parser/ScannerMode.cs
index 88e0e41e..3aa8dbde 100644
--- a/Engine/Protocol/Parser/ScannerMode.cs
+++ b/Engine/Protocol/Parser/ScannerMode.cs
@@ -1,12 +1,9 @@
-namespace GenHTTP.Engine.Protocol.Parser
-{
-
- internal enum ScannerMode
- {
- Words,
- Path,
- HeaderKey,
- HeaderValue
- }
+namespace GenHTTP.Engine.Protocol.Parser;
+internal enum ScannerMode
+{
+ Words,
+ Path,
+ HeaderKey,
+ HeaderValue
}
diff --git a/Engine/Protocol/Request.cs b/Engine/Protocol/Request.cs
index df4e6f0b..836e8838 100644
--- a/Engine/Protocol/Request.cs
+++ b/Engine/Protocol/Request.cs
@@ -1,54 +1,50 @@
using System;
using System.IO;
-
using GenHTTP.Api.Infrastructure;
using GenHTTP.Api.Protocol;
using GenHTTP.Api.Routing;
-using GenHTTP.Engine.Protocol;
+namespace GenHTTP.Engine.Protocol;
-namespace GenHTTP.Engine
+///
+/// Provides methods to access a recieved http request.
+///
+internal sealed class Request : IRequest
{
+ private ICookieCollection? _Cookies;
- ///
- /// Provides methods to access a recieved http request.
- ///
- internal sealed class Request : IRequest
- {
- private ICookieCollection? _Cookies;
-
- private IForwardingCollection? _Forwardings;
+ private IForwardingCollection? _Forwardings;
- private IRequestQuery? _Query;
+ private IRequestQuery? _Query;
- private RequestProperties? _Properties;
+ private RequestProperties? _Properties;
- private FlexibleContentType? _ContentType;
+ private FlexibleContentType? _ContentType;
- #region Get-/Setters
+ #region Get-/Setters
- public IServer Server { get; }
+ public IServer Server { get; }
- public IEndPoint EndPoint { get; }
+ public IEndPoint EndPoint { get; }
- public IClientConnection Client { get; }
+ public IClientConnection Client { get; }
- public IClientConnection LocalClient { get; }
+ public IClientConnection LocalClient { get; }
- public HttpProtocol ProtocolType { get; }
+ public HttpProtocol ProtocolType { get; }
- public FlexibleRequestMethod Method { get; }
+ public FlexibleRequestMethod Method { get; }
- public RoutingTarget Target { get; }
+ public RoutingTarget Target { get; }
- public IHeaderCollection Headers { get; }
+ public IHeaderCollection Headers { get; }
- public Stream? Content { get; }
+ public Stream? Content { get; }
- public FlexibleContentType? ContentType
+ public FlexibleContentType? ContentType
+ {
+ get
{
- get
- {
if (_ContentType is not null)
{
return _ContentType;
@@ -63,18 +59,18 @@ public FlexibleContentType? ContentType
return null;
}
- }
+ }
- public string? Host => Client.Host;
+ public string? Host => Client.Host;
- public string? Referer => this["Referer"];
+ public string? Referer => this["Referer"];
- public string? UserAgent => this["User-Agent"];
+ public string? UserAgent => this["User-Agent"];
- public string? this[string additionalHeader]
+ public string? this[string additionalHeader]
+ {
+ get
{
- get
- {
if (Headers.ContainsKey(additionalHeader))
{
return Headers[additionalHeader];
@@ -82,36 +78,36 @@ public string? this[string additionalHeader]
return null;
}
- }
+ }
- public ICookieCollection Cookies
- {
- get { return _Cookies ??= new CookieCollection(); }
- }
+ public ICookieCollection Cookies
+ {
+ get { return _Cookies ??= new CookieCollection(); }
+ }
- public IForwardingCollection Forwardings
- {
- get { return _Forwardings ??= new ForwardingCollection(); }
- }
+ public IForwardingCollection Forwardings
+ {
+ get { return _Forwardings ??= new ForwardingCollection(); }
+ }
- public IRequestQuery Query
- {
- get { return _Query ??= new RequestQuery(); }
- }
+ public IRequestQuery Query
+ {
+ get { return _Query ??= new RequestQuery(); }
+ }
- public IRequestProperties Properties
- {
- get { return _Properties ??= new RequestProperties(); }
- }
+ public IRequestProperties Properties
+ {
+ get { return _Properties ??= new RequestProperties(); }
+ }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal Request(IServer server, IEndPoint endPoint, IClientConnection client, IClientConnection localClient, HttpProtocol protocol, FlexibleRequestMethod method,
- RoutingTarget target, IHeaderCollection headers, ICookieCollection? cookies, IForwardingCollection? forwardings,
- IRequestQuery? query, Stream? content)
- {
+ internal Request(IServer server, IEndPoint endPoint, IClientConnection client, IClientConnection localClient, HttpProtocol protocol, FlexibleRequestMethod method,
+ RoutingTarget target, IHeaderCollection headers, ICookieCollection? cookies, IForwardingCollection? forwardings,
+ IRequestQuery? query, Stream? content)
+ {
Client = client;
LocalClient = localClient;
@@ -131,23 +127,23 @@ internal Request(IServer server, IEndPoint endPoint, IClientConnection client, I
Content = content;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- public IResponseBuilder Respond()
- {
+ public IResponseBuilder Respond()
+ {
return new ResponseBuilder().Status(ResponseStatus.OK);
}
- #endregion
+ #endregion
- #region IDisposable Support
+ #region IDisposable Support
- private bool disposed = false;
+ private bool disposed = false;
- public void Dispose()
- {
+ public void Dispose()
+ {
if (!disposed)
{
Headers.Dispose();
@@ -166,8 +162,6 @@ public void Dispose()
GC.SuppressFinalize(this);
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/RequestBuffer.cs b/Engine/Protocol/RequestBuffer.cs
index 4523271a..0729444a 100644
--- a/Engine/Protocol/RequestBuffer.cs
+++ b/Engine/Protocol/RequestBuffer.cs
@@ -2,59 +2,56 @@
using System.Buffers;
using System.IO.Pipelines;
using System.Threading;
-
-using GenHTTP.Engine.Infrastructure.Configuration;
-
+using GenHTTP.Engine.Infrastructure;
using PooledAwait;
-namespace GenHTTP.Engine.Protocol
+namespace GenHTTP.Engine.Protocol;
+
+///
+/// Buffers the data received from a client, converting it into a contiguous chunk of data,
+/// therefore making it easier for the parser engine to be processed.
+///
+///
+/// Depending on how fast a client is able to upload request data,
+/// the server may need to wait for the whole request to be available.
+/// Additionally, keep alive connections will be held open by the client
+/// until there is a new request to be sent. The buffer implements request
+/// read timeouts by continuously reading data from the underlying network
+/// stream. If the read operation times out, the server will close the
+/// connection.
+///
+internal sealed class RequestBuffer : IDisposable
{
+ private ReadOnlySequence? _Data;
- ///
- /// Buffers the data received from a client, converting it into a contiguous chunk of data,
- /// therefore making it easier for the parser engine to be processed.
- ///
- ///
- /// Depending on how fast a client is able to upload request data,
- /// the server may need to wait for the whole request to be available.
- /// Additionally, keep alive connections will be held open by the client
- /// until there is a new request to be sent. The buffer implements request
- /// read timeouts by continuously reading data from the underlying network
- /// stream. If the read operation times out, the server will close the
- /// connection.
- ///
- internal sealed class RequestBuffer : IDisposable
- {
- private ReadOnlySequence? _Data;
+ #region Get-/Setters
- #region Get-/Setters
+ private PipeReader Reader { get; }
- private PipeReader Reader { get; }
+ private NetworkConfiguration Configuration { get; }
- private NetworkConfiguration Configuration { get; }
+ private CancellationTokenSource? Cancellation { get; set; }
- private CancellationTokenSource? Cancellation { get; set; }
+ internal ReadOnlySequence Data => _Data ?? new();
- internal ReadOnlySequence Data => _Data ?? new();
+ internal bool ReadRequired => (_Data == null) || _Data.Value.IsEmpty;
- internal bool ReadRequired => (_Data == null) || _Data.Value.IsEmpty;
+ #endregion
- #endregion
+ #region Initialization
- #region Initialization
-
- internal RequestBuffer(PipeReader reader, NetworkConfiguration configuration)
- {
+ internal RequestBuffer(PipeReader reader, NetworkConfiguration configuration)
+ {
Reader = reader;
Configuration = configuration;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- internal async PooledValueTask ReadAsync(bool force = false)
- {
+ internal async PooledValueTask ReadAsync(bool force = false)
+ {
if (ReadRequired || force)
{
if (Cancellation is null)
@@ -82,20 +79,20 @@ internal RequestBuffer(PipeReader reader, NetworkConfiguration configuration)
return Data.Length;
}
- internal void Advance(long bytes)
- {
+ internal void Advance(long bytes)
+ {
_Data = Data.Slice(bytes);
Reader.AdvanceTo(_Data.Value.Start);
}
- #endregion
+ #endregion
- #region Disposing
+ #region Disposing
- private bool disposedValue;
+ private bool disposedValue;
- public void Dispose()
- {
+ public void Dispose()
+ {
if (!disposedValue)
{
if (Cancellation is not null)
@@ -110,8 +107,6 @@ public void Dispose()
GC.SuppressFinalize(this);
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/RequestBuilder.cs b/Engine/Protocol/RequestBuilder.cs
index 8f0b804f..56bc18d4 100644
--- a/Engine/Protocol/RequestBuilder.cs
+++ b/Engine/Protocol/RequestBuilder.cs
@@ -6,58 +6,57 @@
using GenHTTP.Api.Protocol;
using GenHTTP.Api.Routing;
-namespace GenHTTP.Engine.Protocol
-{
+namespace GenHTTP.Engine.Protocol;
- internal sealed class RequestBuilder : IBuilder
- {
- private IServer? _Server;
- private IEndPoint? _EndPoint;
+internal sealed class RequestBuilder : IBuilder
+{
+ private IServer? _Server;
+ private IEndPoint? _EndPoint;
- private IPAddress? _Address;
+ private IPAddress? _Address;
- private FlexibleRequestMethod? _RequestMethod;
- private HttpProtocol? _Protocol;
+ private FlexibleRequestMethod? _RequestMethod;
+ private HttpProtocol? _Protocol;
- private RoutingTarget? _Target;
+ private RoutingTarget? _Target;
- private Stream? _Content;
+ private Stream? _Content;
- private RequestQuery? _Query;
+ private RequestQuery? _Query;
- private CookieCollection? _Cookies;
+ private CookieCollection? _Cookies;
- private ForwardingCollection? _Forwardings;
+ private ForwardingCollection? _Forwardings;
- #region Get-/Setters
+ #region Get-/Setters
- private CookieCollection Cookies
- {
- get { return _Cookies ??= new(); }
- }
+ private CookieCollection Cookies
+ {
+ get { return _Cookies ??= new(); }
+ }
- private ForwardingCollection Forwardings
- {
- get { return _Forwardings ??= new(); }
- }
+ private ForwardingCollection Forwardings
+ {
+ get { return _Forwardings ??= new(); }
+ }
- internal RequestHeaderCollection Headers { get; }
+ internal RequestHeaderCollection Headers { get; }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal RequestBuilder()
- {
+ internal RequestBuilder()
+ {
Headers = new();
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- public RequestBuilder Connection(IServer server, IEndPoint endPoint, IPAddress? address)
- {
+ public RequestBuilder Connection(IServer server, IEndPoint endPoint, IPAddress? address)
+ {
_Server = server;
_Address = address;
_EndPoint = endPoint;
@@ -65,32 +64,32 @@ public RequestBuilder Connection(IServer server, IEndPoint endPoint, IPAddress?
return this;
}
- public RequestBuilder Protocol(HttpProtocol version)
- {
+ public RequestBuilder Protocol(HttpProtocol version)
+ {
_Protocol = version;
return this;
}
- public RequestBuilder Type(FlexibleRequestMethod type)
- {
+ public RequestBuilder Type(FlexibleRequestMethod type)
+ {
_RequestMethod = type;
return this;
}
- public RequestBuilder Path(WebPath path)
- {
+ public RequestBuilder Path(WebPath path)
+ {
_Target = new(path);
return this;
}
- public RequestBuilder Query(RequestQuery query)
- {
+ public RequestBuilder Query(RequestQuery query)
+ {
_Query = query;
return this;
}
- public RequestBuilder Header(string key, string value)
- {
+ public RequestBuilder Header(string key, string value)
+ {
if (string.Equals(key, "cookie", StringComparison.OrdinalIgnoreCase))
{
Cookies.Add(value);
@@ -107,14 +106,14 @@ public RequestBuilder Header(string key, string value)
return this;
}
- public RequestBuilder Content(Stream content)
- {
+ public RequestBuilder Content(Stream content)
+ {
_Content = content;
return this;
}
- public IRequest Build()
- {
+ public IRequest Build()
+ {
try
{
if (_Server is null)
@@ -177,8 +176,8 @@ public IRequest Build()
}
}
- private ClientConnection? DetermineClient()
- {
+ private ClientConnection? DetermineClient()
+ {
if (_Forwardings is not null)
{
foreach (var forwarding in Forwardings)
@@ -193,8 +192,6 @@ public IRequest Build()
return null;
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/RequestHeaderCollection.cs b/Engine/Protocol/RequestHeaderCollection.cs
index 6d71ed1d..3890fc71 100644
--- a/Engine/Protocol/RequestHeaderCollection.cs
+++ b/Engine/Protocol/RequestHeaderCollection.cs
@@ -4,22 +4,19 @@
using GenHTTP.Engine.Utilities;
-namespace GenHTTP.Engine.Protocol
-{
+namespace GenHTTP.Engine.Protocol;
- internal sealed class RequestHeaderCollection : PooledDictionary, IHeaderCollection, IEditableHeaderCollection
- {
- private const int DEFAULT_SIZE = 18;
+internal sealed class RequestHeaderCollection : PooledDictionary, IHeaderCollection, IEditableHeaderCollection
+{
+ private const int DEFAULT_SIZE = 18;
- #region Initialization
+ #region Initialization
- internal RequestHeaderCollection() : base(DEFAULT_SIZE, StringComparer.InvariantCultureIgnoreCase)
- {
+ internal RequestHeaderCollection() : base(DEFAULT_SIZE, StringComparer.InvariantCultureIgnoreCase)
+ {
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/RequestProperties.cs b/Engine/Protocol/RequestProperties.cs
index 3b2438e5..a2710ae2 100644
--- a/Engine/Protocol/RequestProperties.cs
+++ b/Engine/Protocol/RequestProperties.cs
@@ -5,21 +5,20 @@
using GenHTTP.Engine.Utilities;
-namespace GenHTTP.Engine.Protocol
-{
+namespace GenHTTP.Engine.Protocol;
- public sealed class RequestProperties : IRequestProperties
- {
- private PooledDictionary? _Data;
+public sealed class RequestProperties : IRequestProperties
+{
+ private PooledDictionary? _Data;
- private bool _Disposed;
+ private bool _Disposed;
- #region Get-/Setters
+ #region Get-/Setters
- public object this[string key]
+ public object this[string key]
+ {
+ get
{
- get
- {
object? result = null;
if (Data.TryGetValue(key, out var value))
@@ -34,20 +33,20 @@ public object this[string key]
return result;
}
- set
- {
+ set
+ {
Data[key] = value;
}
- }
+ }
- private PooledDictionary Data => _Data ??= new();
+ private PooledDictionary Data => _Data ??= new();
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- public bool TryGet(string key, [MaybeNullWhen(returnValue: false)] out T entry)
- {
+ public bool TryGet(string key, [MaybeNullWhen(returnValue: false)] out T entry)
+ {
if (Data.TryGetValue(key, out var value))
{
if (value is T result)
@@ -61,17 +60,17 @@ public bool TryGet(string key, [MaybeNullWhen(returnValue: false)] out T entr
return false;
}
- public void Clear(string key)
- {
+ public void Clear(string key)
+ {
Data[key] = null;
}
- #endregion
+ #endregion
- #region Disposal
+ #region Disposal
- private void Dispose(bool disposing)
- {
+ private void Dispose(bool disposing)
+ {
if (!_Disposed)
{
if (disposing)
@@ -84,14 +83,12 @@ private void Dispose(bool disposing)
}
}
- public void Dispose()
- {
+ public void Dispose()
+ {
Dispose(disposing: true);
System.GC.SuppressFinalize(this);
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/RequestQuery.cs b/Engine/Protocol/RequestQuery.cs
index 5c3e257d..69a54e8b 100644
--- a/Engine/Protocol/RequestQuery.cs
+++ b/Engine/Protocol/RequestQuery.cs
@@ -3,18 +3,15 @@
using GenHTTP.Api.Protocol;
using GenHTTP.Engine.Utilities;
-namespace GenHTTP.Engine.Protocol
+namespace GenHTTP.Engine.Protocol;
+
+internal sealed class RequestQuery : PooledDictionary, IRequestQuery
{
-
- internal sealed class RequestQuery : PooledDictionary, IRequestQuery
- {
- private const int DEFAULT_SIZE = 12;
+ private const int DEFAULT_SIZE = 12;
- internal RequestQuery() : base(DEFAULT_SIZE, StringComparer.OrdinalIgnoreCase)
- {
+ internal RequestQuery() : base(DEFAULT_SIZE, StringComparer.OrdinalIgnoreCase)
+ {
}
- }
-
}
diff --git a/Engine/Protocol/Response.cs b/Engine/Protocol/Response.cs
index 1bf70f91..6b479527 100644
--- a/Engine/Protocol/Response.cs
+++ b/Engine/Protocol/Response.cs
@@ -1,45 +1,42 @@
using System;
-
using GenHTTP.Api.Protocol;
-using GenHTTP.Engine.Protocol;
-namespace GenHTTP.Engine
-{
+namespace GenHTTP.Engine.Protocol;
- internal sealed class Response : IResponse
- {
- private static readonly FlexibleResponseStatus STATUS_OK = new(ResponseStatus.OK);
+internal sealed class Response : IResponse
+{
+ private static readonly FlexibleResponseStatus STATUS_OK = new(ResponseStatus.OK);
- private CookieCollection? _Cookies;
+ private CookieCollection? _Cookies;
- private readonly ResponseHeaderCollection _Headers = new();
+ private readonly ResponseHeaderCollection _Headers = new();
- #region Get-/Setters
+ #region Get-/Setters
- public FlexibleResponseStatus Status { get; set; }
+ public FlexibleResponseStatus Status { get; set; }
- public DateTime? Expires { get; set; }
+ public DateTime? Expires { get; set; }
- public DateTime? Modified { get; set; }
+ public DateTime? Modified { get; set; }
- public FlexibleContentType? ContentType { get; set; }
+ public FlexibleContentType? ContentType { get; set; }
- public string? ContentEncoding { get; set; }
+ public string? ContentEncoding { get; set; }
- public ulong? ContentLength { get; set; }
+ public ulong? ContentLength { get; set; }
- public IResponseContent? Content { get; set; }
+ public IResponseContent? Content { get; set; }
- public ICookieCollection Cookies => WriteableCookies;
+ public ICookieCollection Cookies => WriteableCookies;
- public bool HasCookies => (_Cookies is not null) && (_Cookies.Count > 0);
+ public bool HasCookies => (_Cookies is not null) && (_Cookies.Count > 0);
- public IEditableHeaderCollection Headers => _Headers;
+ public IEditableHeaderCollection Headers => _Headers;
- public string? this[string field]
+ public string? this[string field]
+ {
+ get
{
- get
- {
if (_Headers.TryGetValue(field, out var value))
{
return value;
@@ -47,8 +44,8 @@ public string? this[string field]
return null;
}
- set
- {
+ set
+ {
if (value is not null)
{
_Headers[field] = value;
@@ -58,39 +55,39 @@ public string? this[string field]
_Headers.Remove(field);
}
}
- }
+ }
- internal CookieCollection WriteableCookies
- {
- get { return _Cookies ??= new(); }
- }
+ internal CookieCollection WriteableCookies
+ {
+ get { return _Cookies ??= new(); }
+ }
- #endregion
+ #endregion
- #region Initialization
+ #region Initialization
- internal Response()
- {
+ internal Response()
+ {
Status = STATUS_OK;
}
- #endregion
+ #endregion
- #region Functionality
+ #region Functionality
- public void SetCookie(Cookie cookie)
- {
+ public void SetCookie(Cookie cookie)
+ {
WriteableCookies[cookie.Name] = cookie;
}
- #endregion
+ #endregion
- #region IDisposable Support
+ #region IDisposable Support
- private bool disposed = false;
+ private bool disposed = false;
- public void Dispose()
- {
+ public void Dispose()
+ {
if (!disposed)
{
Headers.Dispose();
@@ -108,8 +105,6 @@ public void Dispose()
GC.SuppressFinalize(this);
}
- #endregion
-
- }
+ #endregion
}
diff --git a/Engine/Protocol/ResponseBuilder.cs b/Engine/Protocol/ResponseBuilder.cs
index 05fb3e1a..566bee74 100644
--- a/Engine/Protocol/ResponseBuilder.cs
+++ b/Engine/Protocol/ResponseBuilder.cs
@@ -2,81 +2,78 @@
using GenHTTP.Api.Protocol;
-namespace GenHTTP.Engine.Protocol
-{
+namespace GenHTTP.Engine.Protocol;
- internal sealed class ResponseBuilder : IResponseBuilder
- {
- private readonly Response _Response = new();
+internal sealed class ResponseBuilder : IResponseBuilder
+{
+ private readonly Response _Response = new();
- #region Functionality
+ #region Functionality
- public IResponseBuilder Length(ulong length)
- {
+ public IResponseBuilder Length(ulong length)
+ {
_Response.ContentLength = length;
return this;
}
- public IResponseBuilder Content(IResponseContent content)
- {
+ public IResponseBuilder Content(IResponseContent content)
+ {
_Response.Content = content;
_Response.ContentLength = content.Length;
return this;
}
- public IResponseBuilder Type(FlexibleContentType contentType)
- {
+ public IResponseBuilder Type(FlexibleContentType contentType)
+ {
_Response.ContentType = contentType;
return this;
}
- public IResponseBuilder Cookie(Cookie cookie)
- {
+ public IResponseBuilder Cookie(Cookie cookie)
+ {
_Response.WriteableCookies[cookie.Name] = cookie;
return this;
}
- public IResponseBuilder Header(string key, string value)
- {
+ public IResponseBuilder Header(string key, string value)
+ {
_Response.Headers.Add(key, value);
return this;
}
- public IResponseBuilder Encoding(string encoding)
- {
+ public IResponseBuilder Encoding(string encoding)
+ {
_Response.ContentEncoding = encoding;
return this;
}
- public IResponseBuilder Expires(DateTime expiryDate)
- {
+ public IResponseBuilder Expires(DateTime expiryDate)
+ {
_Response.Expires = expiryDate;
return this;
}
- public IResponseBuilder Modified(DateTime modificationDate)
- {
+ public IResponseBuilder Modified(DateTime modificationDate)
+ {
_Response.Modified = modificationDate;
return this;
}
- public IResponseBuilder Status(ResponseStatus status)
- {
+ public IResponseBuilder Status(ResponseStatus status)
+ {
_Response.Status = new(status);
return this;
}
- public IResponseBuilder Status(int status, string reason)
- {
+ public IResponseBuilder Status(int status, string reason)
+ {
_Response.Status = new(status, reason);
return this;
}
- public IResponse Build() => _Response;
-
- #endregion
+ public IResponse Build() => _Response;
- }
+ #endregion
}
diff --git a/Engine/Protocol/ResponseHandler.cs b/Engine/Protocol/ResponseHandler.cs
index 20609eb0..2f425d75 100644
--- a/Engine/Protocol/ResponseHandler.cs
+++ b/Engine/Protocol/ResponseHandler.cs
@@ -6,37 +6,35 @@
using GenHTTP.Api.Infrastructure;
using GenHTTP.Api.Protocol;
-
-using GenHTTP.Engine.Infrastructure.Configuration;
+using GenHTTP.Engine.Infrastructure;
using GenHTTP.Engine.Utilities;
-namespace GenHTTP.Engine.Protocol
-{
+namespace GenHTTP.Engine.Protocol;
- internal sealed class ResponseHandler
- {
- private const string SERVER_HEADER = "Server";
+internal sealed class ResponseHandler
+{
+ private const string SERVER_HEADER = "Server";
- private static readonly string NL = "\r\n";
+ private static readonly string NL = "\r\n";
- private static readonly Encoding ASCII = Encoding.ASCII;
+ private static readonly Encoding ASCII = Encoding.ASCII;
- private static readonly ArrayPool