diff --git a/Tunnelite.sln b/Tunnelite.sln
index 7db3f9d..8c1a902 100644
--- a/Tunnelite.sln
+++ b/Tunnelite.sln
@@ -17,7 +17,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test.TcpServer", "test\Test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test.TcpForwarder", "test\Test.TcpForwarder\Test.TcpForwarder.csproj", "{BCC3AD29-688B-4482-B952-F0095D104020}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.WebApi", "test\Test.WebApi\Test.WebApi.csproj", "{B2656A6C-79E5-41A1-93B2-F87D550FB02E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test.WebApi", "test\Test.WebApi\Test.WebApi.csproj", "{B2656A6C-79E5-41A1-93B2-F87D550FB02E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tunnelite.Sdk", "src\Tunnelite.Sdk\Tunnelite.Sdk.csproj", "{BCC85AF5-8BD0-4E4E-AB0E-306FF640537D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tunnelite.AspNetCore", "src\Tunnelite.AspNetCore\Tunnelite.AspNetCore.csproj", "{E66B7CBA-88CB-41EF-B0B2-8A57F2F9CE81}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -49,6 +53,14 @@ Global
{B2656A6C-79E5-41A1-93B2-F87D550FB02E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B2656A6C-79E5-41A1-93B2-F87D550FB02E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2656A6C-79E5-41A1-93B2-F87D550FB02E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BCC85AF5-8BD0-4E4E-AB0E-306FF640537D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BCC85AF5-8BD0-4E4E-AB0E-306FF640537D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BCC85AF5-8BD0-4E4E-AB0E-306FF640537D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BCC85AF5-8BD0-4E4E-AB0E-306FF640537D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E66B7CBA-88CB-41EF-B0B2-8A57F2F9CE81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E66B7CBA-88CB-41EF-B0B2-8A57F2F9CE81}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E66B7CBA-88CB-41EF-B0B2-8A57F2F9CE81}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E66B7CBA-88CB-41EF-B0B2-8A57F2F9CE81}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -60,6 +72,8 @@ Global
{9E529D00-D5E7-4E2E-80AD-83B793B77DF8} = {230DD554-CD20-4A77-874B-E9BA59A2DC18}
{BCC3AD29-688B-4482-B952-F0095D104020} = {230DD554-CD20-4A77-874B-E9BA59A2DC18}
{B2656A6C-79E5-41A1-93B2-F87D550FB02E} = {230DD554-CD20-4A77-874B-E9BA59A2DC18}
+ {BCC85AF5-8BD0-4E4E-AB0E-306FF640537D} = {AFD8CF9B-F8B9-47C9-BEAB-FC0161D2AFB8}
+ {E66B7CBA-88CB-41EF-B0B2-8A57F2F9CE81} = {AFD8CF9B-F8B9-47C9-BEAB-FC0161D2AFB8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E385A6C3-BECA-4888-B12B-31AA9984F86F}
diff --git a/src/Tunnelite.AspNetCore/Tunnelite.AspNetCore.csproj b/src/Tunnelite.AspNetCore/Tunnelite.AspNetCore.csproj
new file mode 100644
index 0000000..346111b
--- /dev/null
+++ b/src/Tunnelite.AspNetCore/Tunnelite.AspNetCore.csproj
@@ -0,0 +1,37 @@
+
+
+
+ net8.0
+ enable
+ enable
+ Tunnelite.AspNetCore
+ tunnel;tunneling;websockets;signalr;reverse-proxy;proxy;
+ Cristi Pufu
+ MIT
+ git
+ README.md
+ SDK for tunneling AspNetCore apps
+ https://github.com/cristipufu/ws-tunnel-signalr
+ https://github.com/cristipufu/ws-tunnel-signalr
+ 1.0.0
+ true
+ true
+ snupkg
+
+
+
+
+ True
+ \
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Tunnelite.AspNetCore/TunneliteExtensions.cs b/src/Tunnelite.AspNetCore/TunneliteExtensions.cs
new file mode 100644
index 0000000..ca8d942
--- /dev/null
+++ b/src/Tunnelite.AspNetCore/TunneliteExtensions.cs
@@ -0,0 +1,68 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.AspNetCore.Hosting.Server.Features;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Tunnelite.Sdk;
+
+#nullable disable
+namespace Tunnelite.AspNetCore;
+
+public static class TunneliteExtensions
+{
+ private static readonly Guid ClientId = Guid.NewGuid();
+
+ public static IApplicationBuilder UseTunnelite(this IApplicationBuilder app)
+ {
+ var lifetime = app.ApplicationServices.GetRequiredService();
+ var server = app.ApplicationServices.GetRequiredService();
+
+ lifetime.ApplicationStarted.Register(() =>
+ {
+ var addressFeature = server.Features.Get();
+ var localUrl = addressFeature?.Addresses.FirstOrDefault();
+
+ if (string.IsNullOrEmpty(localUrl))
+ {
+ throw new InvalidOperationException("Unable to determine the local URL of the application.");
+ }
+
+ Task.Run(async () =>
+ {
+ var httpTunnel = new HttpTunnelRequest
+ {
+ ClientId = ClientId,
+ LocalUrl = localUrl,
+ PublicUrl = "https://tunnelite.com",
+ };
+
+ var client = new HttpTunnelClient(httpTunnel, null);
+
+ client.Log += x => Console.WriteLine(x);
+ client.LogRequest += (method, path) => Console.WriteLine($"{DateTimeOffset.Now:HH:mm:ss} [{method}]: {path}");
+ client.LogFailedRequest += (method, path) => Console.Write($"{DateTimeOffset.Now:HH:mm:ss} [{method}]: {path}");
+ client.LogError += x => Console.WriteLine(x);
+ client.LogException += x => Console.WriteLine(x.Message);
+
+ await client.ConnectAsync();
+
+ LogTunnelInfo(client.TunnelUrl);
+
+ }, CancellationToken.None);
+
+ });
+
+ return app;
+ }
+
+ private static void LogTunnelInfo(string tunnelUrl)
+ {
+ Console.WriteLine();
+ Console.ForegroundColor = ConsoleColor.Cyan;
+ Console.WriteLine("╔══════════════════════════════════════════════════════════════════════════════╗");
+ Console.WriteLine($" Tunnelite URL: {tunnelUrl,-67}");
+ Console.WriteLine("╚══════════════════════════════════════════════════════════════════════════════╝");
+ Console.ResetColor();
+ Console.WriteLine();
+ }
+}
diff --git a/src/Tunnelite.Client/ITunnelClient.cs b/src/Tunnelite.Client/ITunnelClient.cs
deleted file mode 100644
index b8e59dd..0000000
--- a/src/Tunnelite.Client/ITunnelClient.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using Microsoft.AspNetCore.SignalR.Client;
-
-namespace Tunnelite.Client;
-
-public interface ITunnelClient
-{
- event Func? Connected;
-
- HubConnection Connection { get; }
-
- string? TunnelUrl { get; }
-
- Task ConnectAsync();
-}
diff --git a/src/Tunnelite.Client/Program.cs b/src/Tunnelite.Client/Program.cs
index 3e1508a..3d87374 100644
--- a/src/Tunnelite.Client/Program.cs
+++ b/src/Tunnelite.Client/Program.cs
@@ -2,8 +2,7 @@
using Microsoft.Extensions.Logging;
using Spectre.Console;
using System.CommandLine;
-using Tunnelite.Client.HttpTunnel;
-using Tunnelite.Client.TcpTunnel;
+using Tunnelite.Sdk;
namespace Tunnelite.Client;
@@ -100,6 +99,9 @@ private static async Task InitializeTcpTunnel(string localUrl, string publicUrl,
ctx.Status("Connecting to TCP tunnel...");
Client = new TcpTunnelClient(tcpTunnel, logLevel);
+
+ AddLogging(Client);
+
await Client.ConnectAsync();
ctx.Status("TCP tunnel established.");
@@ -117,6 +119,9 @@ private static async Task InitializeHttpTunnel(string localUrl, string publicUrl
ctx.Status("Connecting to HTTP tunnel...");
Client = new HttpTunnelClient(httpTunnel, logLevel);
+
+ AddLogging(Client);
+
await Client.ConnectAsync();
ctx.Status("HTTP tunnel established.");
@@ -176,7 +181,7 @@ private static async Task RunMainLoop(string localUrl)
}
}
- public static Table WriteStatusTable(string localUrl, string? tunnelUrl, string color, string currentStatus)
+ private static Table WriteStatusTable(string localUrl, string? tunnelUrl, string color, string currentStatus)
{
AnsiConsole.Clear();
@@ -199,32 +204,41 @@ private static void WriteHelp()
AnsiConsole.WriteLine();
}
- public static void Log(string log)
+ private static void Log(string log)
{
string entry = $"[yellow] {DateTimeOffset.Now:HH:mm:ss}[/]: {Markup.Escape(log)}";
AnsiConsole.MarkupLine(entry);
}
- public static void LogRequest(string method, string path)
+ private static void LogRequest(string method, string path)
{
string entry = $"[green] {DateTimeOffset.Now:HH:mm:ss} [[{method}]][/]: {Markup.Escape(path)}";
AnsiConsole.MarkupLine(entry);
}
- public static void LogFailedRequest(string method, string path)
+ private static void LogFailedRequest(string method, string path)
{
string entry = $"[red] {DateTimeOffset.Now:HH:mm:ss} [[{method}]][/]: {Markup.Escape(path)}";
AnsiConsole.MarkupLine(entry);
}
- public static void LogError(string message)
+ private static void LogError(string message)
{
string entry = $"[red] {DateTimeOffset.Now:HH:mm:ss}[/]: {Markup.Escape(message)}";
AnsiConsole.MarkupLine(entry);
}
- public static void LogException(Exception ex)
+ private static void LogException(Exception ex)
{
AnsiConsole.WriteException(ex);
}
+
+ private static void AddLogging(ITunnelClient client)
+ {
+ client.Log += Log;
+ client.LogRequest += LogRequest;
+ client.LogFailedRequest += LogFailedRequest;
+ client.LogError += LogError;
+ client.LogException += LogException;
+ }
}
\ No newline at end of file
diff --git a/src/Tunnelite.Client/Tunnelite.Client.csproj b/src/Tunnelite.Client/Tunnelite.Client.csproj
index 4755455..e7e7c6b 100644
--- a/src/Tunnelite.Client/Tunnelite.Client.csproj
+++ b/src/Tunnelite.Client/Tunnelite.Client.csproj
@@ -16,7 +16,8 @@
Tool for tunneling URLs
https://github.com/cristipufu/ws-tunnel-signalr
https://github.com/cristipufu/ws-tunnel-signalr
- 1.1.5
+ 1.1.6
+ true
@@ -27,11 +28,12 @@
-
-
-
+
+
+
+
diff --git a/src/Tunnelite.Client/HttpTunnel/HttpConnection.cs b/src/Tunnelite.Sdk/HttpTunnel/HttpConnection.cs
similarity index 89%
rename from src/Tunnelite.Client/HttpTunnel/HttpConnection.cs
rename to src/Tunnelite.Sdk/HttpTunnel/HttpConnection.cs
index 4c61c1e..4b0eebe 100644
--- a/src/Tunnelite.Client/HttpTunnel/HttpConnection.cs
+++ b/src/Tunnelite.Sdk/HttpTunnel/HttpConnection.cs
@@ -1,5 +1,5 @@
#nullable disable
-namespace Tunnelite.Client.HttpTunnel;
+namespace Tunnelite.Sdk;
public class HttpConnection
{
diff --git a/src/Tunnelite.Client/HttpTunnel/HttpTunnelClient.cs b/src/Tunnelite.Sdk/HttpTunnel/HttpTunnelClient.cs
similarity index 89%
rename from src/Tunnelite.Client/HttpTunnel/HttpTunnelClient.cs
rename to src/Tunnelite.Sdk/HttpTunnel/HttpTunnelClient.cs
index 78ee4b2..ae742e9 100644
--- a/src/Tunnelite.Client/HttpTunnel/HttpTunnelClient.cs
+++ b/src/Tunnelite.Sdk/HttpTunnel/HttpTunnelClient.cs
@@ -7,11 +7,17 @@
using System.Net.WebSockets;
using System.Runtime.CompilerServices;
-namespace Tunnelite.Client.HttpTunnel;
+namespace Tunnelite.Sdk;
public class HttpTunnelClient : ITunnelClient
{
public event Func? Connected;
+ public event Action? LogRequest;
+ public event Action? LogFailedRequest;
+ public event Action? LogException;
+ public event Action? Log;
+ public event Action? LogError;
+
public HubConnection Connection { get; }
public string? TunnelUrl
{
@@ -51,7 +57,7 @@ public HttpTunnelClient(HttpTunnelRequest tunnel, LogLevel? logLevel)
Connection.On("NewHttpConnection", (httpConnection) =>
{
- Program.LogRequest(httpConnection.Method, httpConnection.Path);
+ LogRequest?.Invoke(httpConnection.Method, httpConnection.Path);
_ = TunnelHttpConnectionAsync(httpConnection);
@@ -60,7 +66,7 @@ public HttpTunnelClient(HttpTunnelRequest tunnel, LogLevel? logLevel)
Connection.On("NewWsConnection", (wsConnection) =>
{
- Program.LogRequest("WS", wsConnection.Path);
+ LogRequest?.Invoke("WS", wsConnection.Path);
_ = TunnelWsConnectionAsync(wsConnection);
@@ -157,8 +163,8 @@ private async Task TunnelHttpConnectionAsync(HttpConnection httpConnection)
}
catch (Exception ex)
{
- Program.LogFailedRequest(httpConnection.Method, httpConnection.Path);
- Program.LogException(ex);
+ LogFailedRequest?.Invoke(httpConnection.Method, httpConnection.Path);
+ LogException?.Invoke(ex);
using var errorRequest = new HttpRequestMessage(HttpMethod.Delete, requestUrl);
using var response = await ServerHttpClient.SendAsync(errorRequest);
}
@@ -181,14 +187,14 @@ private async Task TunnelWsConnectionAsync(WsConnection wsConnection)
}
catch (Exception ex)
{
- Program.LogFailedRequest("WS", wsConnection.Path);
- Program.LogException(ex);
+ LogFailedRequest?.Invoke("WS", wsConnection.Path);
+ LogException?.Invoke(ex);
}
finally
{
await cts.CancelAsync();
- Program.Log($"[WS] Connection {wsConnection.RequestId} closed.");
+ Log?.Invoke($"[WS] Connection {wsConnection.RequestId} closed.");
}
}
@@ -217,7 +223,7 @@ private async Task StreamIncomingWsAsync(WebSocket webSocket, WsConnection wsCon
}
finally
{
- Program.Log($"[WS] Writing data to connection {wsConnection.RequestId} finished.");
+ Log?.Invoke($"[WS] Writing data to connection {wsConnection.RequestId} finished.");
}
}
@@ -226,7 +232,7 @@ private async Task StreamOutgoingWsAsync(WebSocket localWebSocket, WsConnection
await Connection.InvokeAsync("StreamOutgoingWsAsync", StreamLocalWsAsync(localWebSocket, wsConnection, cancellationToken), wsConnection, cancellationToken: cancellationToken);
}
- private static async IAsyncEnumerable<(ReadOnlyMemory, WebSocketMessageType)> StreamLocalWsAsync(WebSocket webSocket, WsConnection wsConnection, [EnumeratorCancellation] CancellationToken cancellationToken)
+ private async IAsyncEnumerable<(ReadOnlyMemory, WebSocketMessageType)> StreamLocalWsAsync(WebSocket webSocket, WsConnection wsConnection, [EnumeratorCancellation] CancellationToken cancellationToken)
{
const int chunkSize = 32 * 1024;
@@ -248,7 +254,7 @@ private async Task StreamOutgoingWsAsync(WebSocket localWebSocket, WsConnection
}
finally
{
- Program.Log($"[WS] Reading data from connection {wsConnection.RequestId} finished.");
+ Log?.Invoke($"[WS] Reading data from connection {wsConnection.RequestId} finished.");
ArrayPool.Shared.Return(buffer);
}
@@ -270,13 +276,13 @@ private async Task StreamOutgoingWsAsync(WebSocket localWebSocket, WsConnection
if (!response.IsSuccessStatusCode)
{
- Program.LogError($"{tunnelResponse!.Message}:{tunnelResponse.Error}");
+ LogError?.Invoke($"{tunnelResponse!.Message}:{tunnelResponse.Error}");
}
}
catch (Exception ex)
{
- Program.LogError($"[HTTP] An error occurred while registering the tunnel:");
- Program.LogException(ex);
+ LogError?.Invoke($"[HTTP] An error occurred while registering the tunnel:");
+ LogException?.Invoke(ex);
await Task.Delay(5000);
}
@@ -303,7 +309,7 @@ private async Task ConnectWithRetryAsync(HubConnection connection, Cancell
}
catch
{
- Program.LogError($"[HTTP] Cannot connect to the public server on {Tunnel.PublicUrl}.");
+ LogError?.Invoke($"[HTTP] Cannot connect to the public server on {Tunnel.PublicUrl}.");
await Task.Delay(5000, token);
}
diff --git a/src/Tunnelite.Client/HttpTunnel/HttpTunnelRequest.cs b/src/Tunnelite.Sdk/HttpTunnel/HttpTunnelRequest.cs
similarity index 85%
rename from src/Tunnelite.Client/HttpTunnel/HttpTunnelRequest.cs
rename to src/Tunnelite.Sdk/HttpTunnel/HttpTunnelRequest.cs
index d981010..f77b920 100644
--- a/src/Tunnelite.Client/HttpTunnel/HttpTunnelRequest.cs
+++ b/src/Tunnelite.Sdk/HttpTunnel/HttpTunnelRequest.cs
@@ -1,5 +1,5 @@
#nullable disable
-namespace Tunnelite.Client.HttpTunnel;
+namespace Tunnelite.Sdk;
public class HttpTunnelRequest
{
diff --git a/src/Tunnelite.Client/HttpTunnel/HttpTunnelResponse.cs b/src/Tunnelite.Sdk/HttpTunnel/HttpTunnelResponse.cs
similarity index 84%
rename from src/Tunnelite.Client/HttpTunnel/HttpTunnelResponse.cs
rename to src/Tunnelite.Sdk/HttpTunnel/HttpTunnelResponse.cs
index aa6a1ce..86e9cca 100644
--- a/src/Tunnelite.Client/HttpTunnel/HttpTunnelResponse.cs
+++ b/src/Tunnelite.Sdk/HttpTunnel/HttpTunnelResponse.cs
@@ -1,5 +1,5 @@
#nullable disable
-namespace Tunnelite.Client.HttpTunnel;
+namespace Tunnelite.Sdk;
public class HttpTunnelResponse
{
diff --git a/src/Tunnelite.Sdk/ITunnelClient.cs b/src/Tunnelite.Sdk/ITunnelClient.cs
new file mode 100644
index 0000000..d8dae46
--- /dev/null
+++ b/src/Tunnelite.Sdk/ITunnelClient.cs
@@ -0,0 +1,19 @@
+using Microsoft.AspNetCore.SignalR.Client;
+
+namespace Tunnelite.Sdk;
+
+public interface ITunnelClient
+{
+ event Func? Connected;
+ event Action? LogRequest;
+ event Action? LogFailedRequest;
+ event Action? LogException;
+ event Action? Log;
+ event Action? LogError;
+
+ HubConnection Connection { get; }
+
+ string? TunnelUrl { get; }
+
+ Task ConnectAsync();
+}
diff --git a/src/Tunnelite.Client/TcpTunnel/TcpConnection.cs b/src/Tunnelite.Sdk/TcpTunnel/TcpConnection.cs
similarity index 70%
rename from src/Tunnelite.Client/TcpTunnel/TcpConnection.cs
rename to src/Tunnelite.Sdk/TcpTunnel/TcpConnection.cs
index 12a72cf..7a1e987 100644
--- a/src/Tunnelite.Client/TcpTunnel/TcpConnection.cs
+++ b/src/Tunnelite.Sdk/TcpTunnel/TcpConnection.cs
@@ -1,5 +1,5 @@
#nullable disable
-namespace Tunnelite.Client.TcpTunnel;
+namespace Tunnelite.Sdk;
public class TcpConnection
{
diff --git a/src/Tunnelite.Client/TcpTunnel/TcpTunnelClient.cs b/src/Tunnelite.Sdk/TcpTunnel/TcpTunnelClient.cs
similarity index 85%
rename from src/Tunnelite.Client/TcpTunnel/TcpTunnelClient.cs
rename to src/Tunnelite.Sdk/TcpTunnel/TcpTunnelClient.cs
index ce53e7e..5d9dbb7 100644
--- a/src/Tunnelite.Client/TcpTunnel/TcpTunnelClient.cs
+++ b/src/Tunnelite.Sdk/TcpTunnel/TcpTunnelClient.cs
@@ -5,12 +5,19 @@
using System.Net.Sockets;
using System.Runtime.CompilerServices;
-namespace Tunnelite.Client.TcpTunnel;
+namespace Tunnelite.Sdk;
public class TcpTunnelClient : ITunnelClient
{
public event Func? Connected;
+ public event Action? LogRequest;
+ public event Action? LogFailedRequest;
+ public event Action? LogException;
+ public event Action? Log;
+ public event Action? LogError;
+
public HubConnection Connection { get; }
+
public string? TunnelUrl
{
get
@@ -42,7 +49,7 @@ public TcpTunnelClient(TcpTunnelRequest tunnel, LogLevel? logLevel)
Connection.On("NewTcpConnection", (tcpConnection) =>
{
- Program.LogRequest("TCP", $"New Connection {tcpConnection.RequestId}");
+ LogRequest?.Invoke("TCP", $"New Connection {tcpConnection.RequestId}");
_ = HandleNewTcpConnectionAsync(tcpConnection);
@@ -51,7 +58,7 @@ public TcpTunnelClient(TcpTunnelRequest tunnel, LogLevel? logLevel)
Connection.On("TcpTunnelClosed", async (errorMessage) =>
{
- Program.LogError($"[TCP] Tunnel closed by server: {errorMessage}.");
+ LogError?.Invoke($"[TCP] Tunnel closed by server: {errorMessage}.");
_currentTunnel = await RegisterTunnelAsync(tunnel);
});
@@ -94,13 +101,13 @@ public async Task ConnectAsync()
if (!string.IsNullOrEmpty(tunnelResponse.Error))
{
- Program.LogError($"[TCP] {tunnelResponse!.Message}:{tunnelResponse.Error}");
+ LogError?.Invoke($"[TCP] {tunnelResponse!.Message}:{tunnelResponse.Error}");
}
}
catch (Exception ex)
{
- Program.LogError($"[TCP] An error occurred while registering the tunnel:");
- Program.LogException(ex);
+ LogError?.Invoke($"[TCP] An error occurred while registering the tunnel:");
+ LogException?.Invoke(ex);
await Task.Delay(5000);
}
@@ -125,13 +132,13 @@ private async Task HandleNewTcpConnectionAsync(TcpConnection tcpConnection)
}
catch (Exception ex)
{
- Program.LogException(ex);
+ LogException?.Invoke(ex);
}
finally
{
await cts.CancelAsync();
- Program.Log($"[TCP] Connection {tcpConnection.RequestId} closed.");
+ Log?.Invoke($"[TCP] Connection {tcpConnection.RequestId} closed.");
}
}
@@ -162,7 +169,7 @@ private async Task StreamIncomingAsync(TcpClient localClient, TcpConnection tcpC
}
finally
{
- Program.Log($"[TCP] Writing data to connection {tcpConnection.RequestId} finished.");
+ Log?.Invoke($"[TCP] Writing data to connection {tcpConnection.RequestId} finished.");
}
}
@@ -171,7 +178,7 @@ private async Task StreamOutgoingAsync(TcpClient localClient, TcpConnection tcpC
await Connection.InvokeAsync("StreamOutgoingAsync", StreamLocalTcpAsync(localClient, tcpConnection, cancellationToken), tcpConnection, cancellationToken: cancellationToken);
}
- private static async IAsyncEnumerable> StreamLocalTcpAsync(TcpClient localClient, TcpConnection tcpConnection, [EnumeratorCancellation] CancellationToken cancellationToken)
+ private async IAsyncEnumerable> StreamLocalTcpAsync(TcpClient localClient, TcpConnection tcpConnection, [EnumeratorCancellation] CancellationToken cancellationToken)
{
const int chunkSize = 32 * 1024;
@@ -190,7 +197,7 @@ private static async IAsyncEnumerable> StreamLocalTcpAsync(
}
finally
{
- Program.Log($"[TCP] Reading data from connection {tcpConnection.RequestId} finished.");
+ Log?.Invoke($"[TCP] Reading data from connection {tcpConnection.RequestId} finished.");
ArrayPool.Shared.Return(buffer);
}
@@ -212,7 +219,7 @@ private async Task ConnectWithRetryAsync(HubConnection connection, Cancell
}
catch
{
- Program.LogError($"[TCP] Cannot connect to the public server on {Tunnel.PublicUrl}");
+ LogError?.Invoke($"[TCP] Cannot connect to the public server on {Tunnel.PublicUrl}");
await Task.Delay(5000, token);
}
diff --git a/src/Tunnelite.Client/TcpTunnel/TcpTunnelRequest.cs b/src/Tunnelite.Sdk/TcpTunnel/TcpTunnelRequest.cs
similarity index 88%
rename from src/Tunnelite.Client/TcpTunnel/TcpTunnelRequest.cs
rename to src/Tunnelite.Sdk/TcpTunnel/TcpTunnelRequest.cs
index 3bb218f..89331d7 100644
--- a/src/Tunnelite.Client/TcpTunnel/TcpTunnelRequest.cs
+++ b/src/Tunnelite.Sdk/TcpTunnel/TcpTunnelRequest.cs
@@ -1,5 +1,5 @@
#nullable disable
-namespace Tunnelite.Client.TcpTunnel;
+namespace Tunnelite.Sdk;
public class TcpTunnelRequest
{
diff --git a/src/Tunnelite.Client/TcpTunnel/TcpTunnelResponse.cs b/src/Tunnelite.Sdk/TcpTunnel/TcpTunnelResponse.cs
similarity index 84%
rename from src/Tunnelite.Client/TcpTunnel/TcpTunnelResponse.cs
rename to src/Tunnelite.Sdk/TcpTunnel/TcpTunnelResponse.cs
index 9496e2a..5879150 100644
--- a/src/Tunnelite.Client/TcpTunnel/TcpTunnelResponse.cs
+++ b/src/Tunnelite.Sdk/TcpTunnel/TcpTunnelResponse.cs
@@ -1,5 +1,5 @@
#nullable disable
-namespace Tunnelite.Client.TcpTunnel;
+namespace Tunnelite.Sdk;
public class TcpTunnelResponse
{
diff --git a/src/Tunnelite.Sdk/Tunnelite.Sdk.csproj b/src/Tunnelite.Sdk/Tunnelite.Sdk.csproj
new file mode 100644
index 0000000..b4a53de
--- /dev/null
+++ b/src/Tunnelite.Sdk/Tunnelite.Sdk.csproj
@@ -0,0 +1,35 @@
+
+
+
+ net8.0
+ enable
+ enable
+ Tunnelite.Sdk
+ tunnel;tunneling;websockets;signalr;reverse-proxy;proxy;
+ Cristi Pufu
+ MIT
+ git
+ README.md
+ SDK for tunneling URLs
+ https://github.com/cristipufu/ws-tunnel-signalr
+ https://github.com/cristipufu/ws-tunnel-signalr
+ 1.0.0
+ true
+ true
+ snupkg
+
+
+
+
+ True
+ \
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Tunnelite.Server/Tunnelite.Server.csproj b/src/Tunnelite.Server/Tunnelite.Server.csproj
index 988b8ee..cfa2a20 100644
--- a/src/Tunnelite.Server/Tunnelite.Server.csproj
+++ b/src/Tunnelite.Server/Tunnelite.Server.csproj
@@ -7,8 +7,8 @@
-
-
+
+
diff --git a/test/Test.WebApi/Program.cs b/test/Test.WebApi/Program.cs
index d0a1942..2f86cdc 100644
--- a/test/Test.WebApi/Program.cs
+++ b/test/Test.WebApi/Program.cs
@@ -1,4 +1,4 @@
-using Test.WebApi;
+using Tunnelite.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
diff --git a/test/Test.WebApi/Test.WebApi.csproj b/test/Test.WebApi/Test.WebApi.csproj
index 8342502..47bc4c4 100644
--- a/test/Test.WebApi/Test.WebApi.csproj
+++ b/test/Test.WebApi/Test.WebApi.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/test/Test.WebApi/TunneliteExtensions.cs b/test/Test.WebApi/TunneliteExtensions.cs
deleted file mode 100644
index 3115651..0000000
--- a/test/Test.WebApi/TunneliteExtensions.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using Microsoft.AspNetCore.Hosting.Server;
-using Microsoft.AspNetCore.Hosting.Server.Features;
-using Spectre.Console;
-using Tunnelite.Client.HttpTunnel;
-
-namespace Test.WebApi
-{
- public static class TunneliteExtensions
- {
- private static readonly Guid ClientId = Guid.NewGuid();
-
- public static IApplicationBuilder UseTunnelite(this IApplicationBuilder app)
- {
- var lifetime = app.ApplicationServices.GetRequiredService();
- var server = app.ApplicationServices.GetRequiredService();
- var logger = app.ApplicationServices.GetRequiredService>();
-
- lifetime.ApplicationStarted.Register(() =>
- {
- var addressFeature = server.Features.Get();
- var localUrl = addressFeature?.Addresses.FirstOrDefault();
-
- if (string.IsNullOrEmpty(localUrl))
- {
- throw new InvalidOperationException("Unable to determine the local URL of the application.");
- }
-
- var httpTunnel = new HttpTunnelRequest
- {
- ClientId = ClientId,
- LocalUrl = localUrl,
- PublicUrl = "https://tunnelite.com",
- };
-
- var client = new HttpTunnelClient(httpTunnel, null);
-
- client.ConnectAsync().GetAwaiter().GetResult();
-
- Table statusTable = Tunnelite.Client.Program.WriteStatusTable(localUrl, client.TunnelUrl, "green", "Connected");
-
- });
-
- return app;
- }
- }
-}