Skip to content

[HttpListener] Calling Abort() or Dispose() on a server WebSocket originating from a HttpListener does nothing on Linux #58614

Description

@iconics-milan

Description

Calling Abort() or Dispose() on a server WebSocket originating from a HttpListener does nothing with the underlying TCP connection, when run on Linux. The connection simply remains open.
On Windows, it properly aborts the TCP connection.

Configuration

Tried on .NET Core 2.1, 3.1, 5.0 on Ubuntu - all with the same result.
Works on Windows with all these versions.

Code

This code gets stuck on Linux, but finishes on Windows:

        using System;
        using System.IO;
        using System.Net;
        using System.Net.WebSockets;
        using System.Threading;
        using System.Threading.Tasks;

        namespace WebSocketCloseTest
        {
            public class Program
            {
                public static async Task Main(string[] args)
                {
                    var serverTask = Server("http://localhost:45000/test/ws/");
                    await Client("ws://localhost:45000/test/ws/");
                    await serverTask;
                }

                private static async Task Server(String serverAddress)
                {
                    var listener = new HttpListener();
                    listener.Prefixes.Add(serverAddress);
                    listener.Start();
                    HttpListenerContext ctx = await listener.GetContextAsync();
                    HttpListenerWebSocketContext wsCtx = await ctx.AcceptWebSocketAsync("subProtocol");
                    using (var webSocket = wsCtx.WebSocket)
                    {
                        webSocket.Abort();
                    }
                }

                private static async Task Client(String serverAddress)
                {
                    try
                    {
                        using (ClientWebSocket webSocket = new ClientWebSocket())
                        {
                            webSocket.Options.AddSubProtocol("subProtocol");
                            await webSocket.ConnectAsync(new Uri(serverAddress), CancellationToken.None).ConfigureAwait(false);
                            await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None);
                        }
                    }
                    catch (WebSocketException e)
                    {
                        Console.WriteLine($"Client WS exception: {e.Message}");
                    }
                    catch (IOException e)
                    {
                        Console.WriteLine($"Client WS exception: {e.Message}");
                    }
                }
            }
        }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions