Skip to content

Commit

Permalink
improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
CypherPotato committed Dec 8, 2024
1 parent d571a8c commit 009cf1f
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 40 deletions.
5 changes: 2 additions & 3 deletions extensions/Sisk.SslProxy/DnsUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ public static IPEndPoint ResolveEndpoint(ListeningPort port, bool onlyUseIPv4 =
else
{
resolvedAddress =
// try to return the last IPv6, or the last IPv4 if no IPv6 was found (#16)
hostEntry.AddressList.LastOrDefault(a => a.AddressFamily == AddressFamily.InterNetworkV6)
?? hostEntry.AddressList.LastOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork);
// try to return the last IPv6 or IPv4
hostEntry.AddressList.LastOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork || a.AddressFamily == AddressFamily.InterNetworkV6);
}

if (resolvedAddress is null)
Expand Down
11 changes: 11 additions & 0 deletions src/Helpers/PathHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ public static string CombinePaths(params string[] paths)
{
return PathUtility.CombinePaths(paths);
}

/// <summary>
/// Normalizes and combines the specified file-system paths into one.
/// </summary>
/// <param name="allowRelativeReturn">Specifies if relative paths should be merged and ".." returns should be respected.</param>
/// <param name="separator">Specifies the path separator character.</param>
/// <param name="paths">Specifies the array of paths to combine.</param>
public static string FilesystemCombinePaths(bool allowRelativeReturn, char separator, params string[] paths)
{
return PathUtility.NormalizedCombine(allowRelativeReturn, separator, paths);
}

/// <summary>
/// Normalizes and combines the specified file-system paths into one.
Expand Down
8 changes: 5 additions & 3 deletions src/Http/HttpServer__Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,9 @@ private void ProcessRequest(HttpListenerContext context)
if (response.Content is ByteArrayContent barrayContent)
{
ApplyHttpContentHeaders(baseResponse, barrayContent.Headers);
ReadOnlySpan<byte> contentBytes = ByteArrayAccessors.UnsafeGetContent(barrayContent);
byte[] contentBytes = ByteArrayAccessors.UnsafeGetContent(barrayContent);
int offset = ByteArrayAccessors.UnsafeGetOffset(barrayContent);
int count = ByteArrayAccessors.UnsafeGetCount(barrayContent);

if (response.SendChunked)
{
Expand All @@ -366,10 +368,10 @@ private void ProcessRequest(HttpListenerContext context)
else
{
baseResponse.SendChunked = false;
baseResponse.ContentLength64 = contentBytes.Length;
baseResponse.ContentLength64 = count;
}

baseResponse.OutputStream.Write(contentBytes);
baseResponse.OutputStream.Write(contentBytes, offset, count);
}
else if (response.Content is HttpContent httpContent)
{
Expand Down
13 changes: 13 additions & 0 deletions src/Http/Streams/HttpStreamPingPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ public void Start()
{
this._timer = new Timer(new TimerCallback(this.OnCallback), null, 0, (int)this.Interval.TotalMilliseconds);
}

/// <summary>
/// Configures and starts sending periodic pings to the client.
/// </summary>
/// <param name="dataMessage">The payload message that is sent to the server as a ping message.</param>
/// <param name="interval">The sending interval for each ping message.</param>
public void Start(string dataMessage, TimeSpan interval)
{
this.DataMessage = dataMessage;
this.Interval = interval;

this.Start();
}

private void OnCallback(object? state)
{
Expand Down
82 changes: 54 additions & 28 deletions src/Http/Streams/HttpWebSocket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

using System.Net.WebSockets;
using System.Runtime.CompilerServices;
using System.Text;

namespace Sisk.Core.Http.Streams
{
Expand Down Expand Up @@ -78,7 +77,7 @@ public sealed class HttpWebSocket
/// Represents the event which is called when this web socket receives an message from
/// remote origin.
/// </summary>
public event WebSocketMessageReceivedEventHandler? OnReceive = null;
public event WebSocketMessageReceivedEventHandler? OnReceive;

internal HttpWebSocket(HttpListenerWebSocketContext ctx, HttpRequest req, string? identifier)
{
Expand Down Expand Up @@ -170,7 +169,7 @@ internal async void ReceiveTask()
}
else
{
if (OnReceive != null) OnReceive(this, message);
if (OnReceive != null) OnReceive.Invoke(this, message);
}
}
}
Expand Down Expand Up @@ -199,55 +198,81 @@ public HttpWebSocket WithPing(string probeMessage, TimeSpan interval)
}

/// <summary>
/// Sends an text message to the remote point.
/// Asynchronously sends an message to the remote point.
/// </summary>
/// <param name="message">The target message which will be as an encoded UTF-8 string.</param>
public void Send(object? message)
public Task<bool> SendAsync(object message)
{
string? t = message?.ToString();
this.Send(t ?? string.Empty);
return Task.FromResult(this.Send(message));
}

/// <summary>
/// Asynchronously sends an text message to the remote point.
/// </summary>
/// <param name="message">The target message which will be as an encoded UTF-8 string.</param>
public Task<bool> SendAsync(string message)
{
return Task.FromResult(this.Send(message));
}

/// <summary>
/// Asynchronously sends an binary message to the remote point.
/// </summary>
/// <param name="buffer">The target message which will be as an encoded UTF-8 string.</param>
public Task<bool> SendAsync(byte[] buffer)
{
return Task.FromResult(this.Send(buffer));
}

/// <summary>
/// Sends an text message to the remote point.
/// </summary>
/// <param name="message">The target message which will be as an encoded UTF-8 string.</param>
public void Send(string message)
public bool Send(object message)
{
string? t = message.ToString();
if (t is null) throw new ArgumentNullException(nameof(message));

return this.Send(t);
}

/// <summary>
/// Sends an text message to the remote point.
/// </summary>
/// <param name="message">The target message which will be as an encoded using the request preferred encoding.</param>
public bool Send(string message)
{
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
ReadOnlyMemory<byte> span = new ReadOnlyMemory<byte>(messageBytes);
this.SendInternal(span, WebSocketMessageType.Text);
ArgumentNullException.ThrowIfNull(message);

byte[] messageBytes = this.request.RequestEncoding.GetBytes(message);
return this.SendInternal(messageBytes, WebSocketMessageType.Text);
}

/// <summary>
/// Sends an binary message to the remote point.
/// </summary>
/// <param name="buffer">The target byte array.</param>
public void Send(byte[] buffer)
{
ReadOnlyMemory<byte> span = new ReadOnlyMemory<byte>(buffer);
this.SendInternal(span, WebSocketMessageType.Binary);
}
public bool Send(byte[] buffer) => this.Send(buffer, 0, buffer.Length);

/// <summary>
/// Sends an binary message to the remote point.
/// </summary>
/// <param name="buffer">The target byte array.</param>
/// <param name="start">The index at which to begin the memory.</param>
/// <param name="length">The number of items in the memory.</param>
public void Send(byte[] buffer, int start, int length)
public bool Send(byte[] buffer, int start, int length)
{
ReadOnlyMemory<byte> span = new ReadOnlyMemory<byte>(buffer, start, length);
this.SendInternal(span, WebSocketMessageType.Binary);
return this.SendInternal(span, WebSocketMessageType.Binary);
}

/// <summary>
/// Sends an binary message to the remote point.
/// </summary>
/// <param name="buffer">The target byte memory.</param>
public void Send(ReadOnlyMemory<byte> buffer)
public bool Send(ReadOnlyMemory<byte> buffer)
{
this.SendInternal(buffer, WebSocketMessageType.Binary);
return this.SendInternal(buffer, WebSocketMessageType.Binary);
}

/// <summary>
Expand Down Expand Up @@ -290,9 +315,9 @@ public HttpResponse Close()
}

[MethodImpl(MethodImplOptions.Synchronized)]
private void SendInternal(ReadOnlyMemory<byte> buffer, WebSocketMessageType msgType)
private bool SendInternal(ReadOnlyMemory<byte> buffer, WebSocketMessageType msgType)
{
if (this.isClosed) { return; }
if (this.isClosed) { return false; }

if (this.closeTimeout.TotalMilliseconds > 0)
this.asyncListenerToken?.CancelAfter(this.closeTimeout);
Expand Down Expand Up @@ -323,9 +348,10 @@ private void SendInternal(ReadOnlyMemory<byte> buffer, WebSocketMessageType msgT
if (this.MaxAttempts >= 0 && this.attempt >= this.MaxAttempts)
{
this.Close();
return;
return false;
}
}
return true;
}

/// <summary>
Expand Down Expand Up @@ -419,18 +445,18 @@ public sealed class WebSocketMessage
/// <summary>
/// Reads the message bytes as string using the specified encoding.
/// </summary>
/// <param name="encoder">The encoding which will be used to decode the message.</param>
public string GetString(System.Text.Encoding encoder)
/// <param name="encoding">The encoding which will be used to decode the message.</param>
public string GetString(System.Text.Encoding encoding)
{
return encoder.GetString(this.MessageBytes);
return encoding.GetString(this.MessageBytes);
}

/// <summary>
/// Reads the message bytes as string using the UTF-8 text encoding.
/// Reads the message bytes as string using the HTTP request encoding.
/// </summary>
public string GetString()
{
return this.GetString(Encoding.UTF8);
return this.GetString(this.Sender.HttpRequest.RequestEncoding);
}

internal WebSocketMessage(HttpWebSocket httpws, int bufferLen)
Expand Down
6 changes: 6 additions & 0 deletions src/Internal/ByteArrayAccessors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,10 @@ class ByteArrayAccessors
{
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_content")]
public extern static ref byte[] UnsafeGetContent(ByteArrayContent bcontent);

[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_offset")]
public extern static ref int UnsafeGetOffset(ByteArrayContent bcontent);

[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_count")]
public extern static ref int UnsafeGetCount(ByteArrayContent bcontent);
}
2 changes: 1 addition & 1 deletion tcp/Sisk.ManagedHttpListener/HttpConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public int HandleConnectionEvents()
{
//try
//{
using var bufferedStreamSession = new Streams.HttpBufferedStream(_connectionStream);
using var bufferedStreamSession = new Streams.HttpBufferedReadStream(_connectionStream);

if (!HttpRequestSerializer.TryReadHttp1Request(
bufferedStreamSession,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Sisk.ManagedHttpListener.HttpSerializer;

internal static class HttpRequestSerializer
{
static ReadOnlySpan<byte> ReadUntil(Span<byte> readBuffer, Streams.HttpBufferedStream bufferStream, byte intercept, out bool found)
static ReadOnlySpan<byte> ReadUntil(Span<byte> readBuffer, Streams.HttpBufferedReadStream bufferStream, byte intercept, out bool found)
{
int accumulatedPosition = (int)bufferStream.Position;
while (bufferStream.Read(readBuffer) > 0)
Expand All @@ -29,7 +29,7 @@ static ReadOnlySpan<byte> ReadUntil(Span<byte> readBuffer, Streams.HttpBufferedS
}

public static bool TryReadHttp1Request(
Streams.HttpBufferedStream inboundStream,
Streams.HttpBufferedReadStream inboundStream,
scoped Span<byte> lineMemory,
[NotNullWhen(true)] out string? method,
[NotNullWhen(true)] out string? path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@

namespace Sisk.ManagedHttpListener.Streams;

internal class HttpBufferedStream : Stream
internal class HttpBufferedReadStream : Stream
{
private const int INITIAL_BUFFER = 4096;

private readonly Stream _stream;
private readonly byte[] _b;

private long _position;
private int _read;

public HttpBufferedStream(Stream stream)
public HttpBufferedReadStream(Stream stream)
{
_stream = stream;
_position = 0;
_read = 0;
_b = ArrayPool<byte>.Shared.Rent(4096);
_b = ArrayPool<byte>.Shared.Rent(INITIAL_BUFFER);
}

public Span<byte> BufferedBytes => _b;
Expand Down Expand Up @@ -100,4 +102,10 @@ public void Move(int toPosition)
ArgumentOutOfRangeException.ThrowIfGreaterThan(toPosition, _read);
_position = toPosition;
}

protected override void Dispose(bool disposing)
{
ArrayPool<byte>.Shared.Return(_b);
base.Dispose(disposing);
}
}

0 comments on commit 009cf1f

Please sign in to comment.