Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
de0ff55
Establish new API model
Kaliumhexacyanoferrat Mar 5, 2026
afa178f
Use BufferWriter for resources as well
Kaliumhexacyanoferrat Mar 5, 2026
e766fe2
Adjust workflows for testing
Kaliumhexacyanoferrat Mar 5, 2026
b88ae91
Hello World!
Kaliumhexacyanoferrat Mar 5, 2026
6c97bde
Might fix an issue with the nuget dependencies workflow
Kaliumhexacyanoferrat Mar 5, 2026
584127c
Set version to preview
Kaliumhexacyanoferrat Mar 5, 2026
ee1b1e5
Enable CI job
Kaliumhexacyanoferrat Mar 5, 2026
59c1ebb
Properly fix versioning
Kaliumhexacyanoferrat Mar 5, 2026
d10fe67
Switch to parsing mechanism recommended by Glpyh11
Kaliumhexacyanoferrat Mar 6, 2026
1c91986
Manual pipe reader for sockets
Kaliumhexacyanoferrat Mar 6, 2026
9e021cd
Pull all state into a single class
Kaliumhexacyanoferrat Mar 6, 2026
fc301c8
WIP
Kaliumhexacyanoferrat Mar 6, 2026
584cd32
Provide preview 2
Kaliumhexacyanoferrat Mar 6, 2026
487a529
Fix memory leak
Kaliumhexacyanoferrat Mar 7, 2026
9cfa363
Re-use CTS during the lifetime of a client handler
Kaliumhexacyanoferrat Mar 7, 2026
a84b76f
Bump
Kaliumhexacyanoferrat Mar 7, 2026
31cb9a4
...
Kaliumhexacyanoferrat Mar 7, 2026
459ecd5
Fix version
Kaliumhexacyanoferrat Mar 7, 2026
197893f
Remove not required reference from ASP adapter
Kaliumhexacyanoferrat Mar 9, 2026
79c0ccc
Error free?
Kaliumhexacyanoferrat Mar 9, 2026
3e809a4
Fix response generation async handling
Kaliumhexacyanoferrat Mar 9, 2026
ce1eec0
Improve header caching behavior
Kaliumhexacyanoferrat Mar 9, 2026
fb2d5db
Do not send the server header if it is contained
Kaliumhexacyanoferrat Mar 9, 2026
18a2dbf
Add json implementation
Kaliumhexacyanoferrat Mar 9, 2026
355cca6
OImplement chunked encoding
Kaliumhexacyanoferrat Mar 9, 2026
64c02e9
Implement chunked encoding
Kaliumhexacyanoferrat Mar 9, 2026
08bba6d
Copy status handling of wired
Kaliumhexacyanoferrat Mar 10, 2026
d36e7db
Restore redirect capabilities
Kaliumhexacyanoferrat Mar 31, 2026
d5d79d8
Refine request model
Kaliumhexacyanoferrat Mar 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ on:
branches:
- main
- 'release/*'
- 'feature/genhttp-next'
push:
branches:
- main
- 'release/*'
- 'release/*'
- 'feature/genhttp-next'

jobs:

Expand Down Expand Up @@ -43,19 +45,19 @@ jobs:
- name: Restore tools
run: dotnet tool restore

- name: Begin scan
if: env.SONAR_TOKEN != null && env.SONAR_TOKEN != ''
run: dotnet sonarscanner begin /k:"GenHTTP" /d:sonar.token="$SONAR_TOKEN" /d:sonar.cs.opencover.reportsPaths="**/coverage.opencover.xml" /d:sonar.exclusions="**/bin/**/*,**/obj/**/*,**/Playground/**/*,**/*.css,**/*.js,**/*.html" /o:"kaliumhexacyanoferrat" /k:"GenHTTP" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.branch.name="${GITHUB_REF##*/}" /d:sonar.dotnet.excludeTestProjects=true
#- name: Begin scan
# if: env.SONAR_TOKEN != null && env.SONAR_TOKEN != ''
# run: dotnet sonarscanner begin /k:"GenHTTP" /d:sonar.token="$SONAR_TOKEN" /d:sonar.cs.opencover.reportsPaths="**/coverage.opencover.xml" /d:sonar.exclusions="**/bin/**/*,**/obj/**/*,**/Playground/**/*,**/*.css,**/*.js,**/*.html" /o:"kaliumhexacyanoferrat" /k:"GenHTTP" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.branch.name="${GITHUB_REF##*/}" /d:sonar.dotnet.excludeTestProjects=true

- name: Build project
run: dotnet build GenHTTP.slnx -c Release

- name: Test project
run: dotnet test GenHTTP.slnx --no-build --collect:"XPlat Code Coverage" -c Release -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
#- name: Test project
# run: dotnet test GenHTTP.slnx --no-build --collect:"XPlat Code Coverage" -c Release -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover

- name: End scan
if: env.SONAR_TOKEN != null && env.SONAR_TOKEN != ''
run: dotnet sonarscanner end /d:sonar.token="$SONAR_TOKEN"
#- name: End scan
# if: env.SONAR_TOKEN != null && env.SONAR_TOKEN != ''
# run: dotnet sonarscanner end /d:sonar.token="$SONAR_TOKEN"

verify:

Expand Down Expand Up @@ -135,5 +137,8 @@ jobs:
9.0
10.0

- name: Build & Test (${{ matrix.runtime }})
run: dotnet test Testing/Acceptance/GenHTTP.Testing.Acceptance.csproj -c Release --logger "console;verbosity=detailed"
- name: Build (${{ matrix.runtime }})
run: dotnet build GenHTTP.slnx -c Release

#- name: Build & Test (${{ matrix.runtime }})
# run: dotnet test Testing/Acceptance/GenHTTP.Testing.Acceptance.csproj -c Release --logger "console;verbosity=detailed"
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
working-directory: Packages
run: |
nuget pack GenHTTP.Core.nuspec -OutputDirectory ../artifacts
nuget pack GenHTTP.Core.Kestrel.nuspec -OutputDirectory ../artifacts
# nuget pack GenHTTP.Core.Kestrel.nuspec -OutputDirectory ../artifacts

- name: List gathered packages
run: dir artifacts
Expand Down
5 changes: 4 additions & 1 deletion API/Content/IO/IResource.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GenHTTP.Api.Protocol;
using System.Buffers;
using GenHTTP.Api.Protocol;

namespace GenHTTP.Api.Content.IO;

Expand Down Expand Up @@ -66,4 +67,6 @@ async ValueTask WriteAsync(Stream target, uint bufferSize)
await content.CopyToAsync(target, (int)bufferSize);
}

void Write(IBufferWriter<byte> writer);

}
2 changes: 2 additions & 0 deletions API/Protocol/ClientProtocol.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace GenHTTP.Api.Protocol;

// todo: re-visit

public enum ClientProtocol
{
Http,
Expand Down
2 changes: 2 additions & 0 deletions API/Protocol/Connection.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace GenHTTP.Api.Protocol;

// todo: re-visit

public enum Connection
{

Expand Down
2 changes: 2 additions & 0 deletions API/Protocol/ContentType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace GenHTTP.Api.Protocol;

// todo: re-visit

#region Known Types

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions API/Protocol/Cookie.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace GenHTTP.Api.Protocol;

// todo: re-visit

/// <summary>
/// Represents a cookie that can be send to or received from a client.
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions API/Protocol/Forwarding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace GenHTTP.Api.Protocol;

// todo: re-visit

/// <summary>
/// Stores information how a request has been proxied
/// to the server.
Expand Down
2 changes: 2 additions & 0 deletions API/Protocol/HttpProtocol.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace GenHTTP.Api.Protocol;

// todo: re-visit

/// <summary>
/// The protocol version of a request.
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions API/Protocol/ICookieCollection.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace GenHTTP.Api.Protocol;

// todo: re-visit

/// <summary>
/// A collection representing the cookies of an <see cref="IRequest" />
/// or <see cref="IResponse" />.
Expand Down
2 changes: 2 additions & 0 deletions API/Protocol/IEditableHeaderCollection.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
namespace GenHTTP.Api.Protocol;

// todo: re-visit

public interface IEditableHeaderCollection : IDictionary<string, string>;
2 changes: 2 additions & 0 deletions API/Protocol/IForwardingCollection.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
namespace GenHTTP.Api.Protocol;

// todo: re-visit

public interface IForwardingCollection : IList<Forwarding>;
4 changes: 3 additions & 1 deletion API/Protocol/IHeaderCollection.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace GenHTTP.Api.Protocol;

// todo: re-visit

/// <summary>
/// The headers of an <see cref="IRequest" /> or <see cref="IResponse" />.
/// </summary>
public interface IHeaderCollection : IReadOnlyDictionary<string, string>;
public interface IHeaderCollection : IReadOnlyDictionary<string, string>;
10 changes: 10 additions & 0 deletions API/Protocol/IKeyValueList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace GenHTTP.Api.Protocol;

public interface IKeyValueList
{

string? GetValue(string key);

string? GetValue(ReadOnlyMemory<byte> key);

}
141 changes: 9 additions & 132 deletions API/Protocol/IRequest.cs
Original file line number Diff line number Diff line change
@@ -1,145 +1,22 @@
using GenHTTP.Api.Infrastructure;
using GenHTTP.Api.Routing;
using GenHTTP.Api.Protocol.Raw;

namespace GenHTTP.Api.Protocol;

/// <summary>
/// A request send by the currently connected client.
/// </summary>
public interface IRequest : IDisposable
public interface IRequest
{

#region Extensibility
IRawRequest Raw { get; }

/// <summary>
/// Additional properties that have been attached to the request.
/// </summary>
/// <remarks>
/// Can be used to store additional state on request level if needed.
/// Should be avoided in favor of more strict coupling.
/// </remarks>
IRequestProperties Properties { get; }
IKeyValueList Headers { get; }

#endregion
IKeyValueList Query { get; }

#region Functionality
IRequestBody? Body { get; }

/// <summary>
/// Generates a new response for this request to be send to the client.
/// </summary>
/// <returns>The newly created response</returns>
IResponseBuilder Respond();

#endregion

#region General Infrastructure

/// <summary>
/// The server handling the request.
/// </summary>
IServer Server { get; }

/// <summary>
/// The endpoint the request originates from.
/// </summary>
IEndPoint EndPoint { get; }

/// <summary>
/// The client which sent the request.
/// </summary>
IClientConnection Client { get; }

/// <summary>
/// If the request has been forwarded by a proxy, the client property
/// will return the originating client while this property will return
/// the information of the proxy.
/// </summary>
IClientConnection LocalClient { get; }

#endregion

#region HTTP Protocol

/// <summary>
/// The requested protocol type.
/// </summary>
HttpProtocol ProtocolType { get; }

/// <summary>
/// The HTTP method used by the client to issue this request.
/// </summary>
FlexibleRequestMethod Method { get; }

/// <summary>
/// The path requested by the client (with no query parameters attached).
/// </summary>
RoutingTarget Target { get; }

#endregion
RequestMethod Method { get; }

#region Headers
string Host { get; }

/// <summary>
/// The user agent which issued this request, if any.
/// </summary>
string? UserAgent { get; }

/// <summary>
/// The referrer which caused the invocation of this request, if any.
/// </summary>
string? Referer { get; }

/// <summary>
/// The host requested by the client, if any.
/// </summary>
string? Host { get; }

/// <summary>
/// Read an additional header value from the request.
/// </summary>
/// <param name="additionalHeader">The name of the header field to be read</param>
/// <returns>The value of the header field, if specified by the client</returns>
string? this[string additionalHeader] { get; }

/// <summary>
/// The query parameters passed by the client.
/// </summary>
IRequestQuery Query { get; }

/// <summary>
/// The cookies passed by the client.
/// </summary>
ICookieCollection Cookies { get; }

/// <summary>
/// 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.
/// </summary>
/// <remarks>
/// Use <see cref="Client" /> to quickly access the requesting client without the need
/// of scrolling through the forwardings.
/// </remarks>
IForwardingCollection Forwardings { get; }

/// <summary>
/// The headers of this HTTP request.
/// </summary>
IHeaderCollection Headers { get; }

#endregion

#region Body

/// <summary>
/// The content transmitted by the client, if any.
/// </summary>
Stream? Content { get; }

/// <summary>
/// The type of content transmitted by the client, if any.
/// </summary>
FlexibleContentType? ContentType { get; }

#endregion
IResponseBuilder Respond();

}
18 changes: 18 additions & 0 deletions API/Protocol/IRequestBody.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace GenHTTP.Api.Protocol;

public interface IRequestBody
{

/// <summary>
/// Provides the body of the request as a stream.
/// </summary>
/// <returns>The stream created to access the body</returns>
Stream AsStream();

/// <summary>
/// Reads the whole request body into a byte array.
/// </summary>
/// <returns>The byte array read from the request body</returns>
byte[] AsArray();

}
2 changes: 2 additions & 0 deletions API/Protocol/IRequestProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace GenHTTP.Api.Protocol;

// todo: re-visit

/// <summary>
/// Property bag to store additional data within the
/// currently running request context.
Expand Down
2 changes: 2 additions & 0 deletions API/Protocol/IRequestQuery.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace GenHTTP.Api.Protocol;

// todo: re-visit

/// <summary>
/// Stores the query sent by the client.
/// </summary>
Expand Down
Loading
Loading