Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 33 additions & 0 deletions src/DiffEngineTray.Tests/PiperTest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System.Net;
using System.Net.Sockets;

public class PiperTest :
IDisposable
{
Expand Down Expand Up @@ -64,6 +67,36 @@ public async Task Move()
await Verify(received);
}

[Test]
public async Task ClientDisconnectsAbruptly()
{
DeletePayload? received = null;
var source = new CancelSource();
var task = PiperServer.Start(_ => { }, s => received = s, source.Token);

// Connect and immediately close with RST (no data sent),
// simulating a client that was canceled mid-connection.
using (var client = new TcpClient())
{
await client.ConnectAsync(IPAddress.Loopback, PiperClient.Port);
// Linger with timeout 0 causes a RST (forcible close) on Close
client.LingerState = new(true, 0);
}

// Give the server time to process the abrupt disconnect
await Task.Delay(500);

// Server should still work after the abrupt disconnect
await PiperClient.SendDeleteAsync("Foo", source.Token);
await Task.Delay(1000, source.Token);
source.Cancel();
await task;

// Verify the server recovered and processed the subsequent valid message
Assert.NotNull(received);
Assert.Equal("Foo", received!.File);
}

[Test]
public async Task SendOnly()
{
Expand Down
6 changes: 6 additions & 0 deletions src/DiffEngineTray/PiperServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public static async Task Start(
//when task is cancelled socket is disposed
break;
}
catch (IOException exception)
when (exception.InnerException is SocketException { SocketErrorCode: SocketError.ConnectionReset })
{
//client disconnected abruptly, e.g. test was canceled
}
catch (Exception exception)
{
if (cancel.IsCancellationRequested)
Expand All @@ -58,6 +63,7 @@ static async Task Handle(TcpListener listener, Action<MovePayload> move, Action<
{
using var client = await listener.AcceptTcpClientAsync(cancel);
using var reader = new StreamReader(client.GetStream());

var payload = await reader.ReadToEndAsync(cancel);

if (payload.Contains("\"Type\":\"Move\"") ||
Expand Down