Closed
Description
Description
ClientWebSocket
hangs when attempting to connect to HTTP/1.1 WebSocket server using RequestVersionOrHigher
policy. If this is expected behavior, it should probably be documented.
Reproduction Steps
This will hang unless HttpVersionPolicy
setting is commented out:
using System.Net.WebSockets;
using var ws = new ClientWebSocket();
ws.Options.HttpVersion = new(1, 1);
ws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher; // <--- causes problem
using var handler = new SocketsHttpHandler();
handler.ConnectTimeout = TimeSpan.FromSeconds(10);
using var invoker = new HttpMessageInvoker(handler);
await ws.ConnectAsync(new("wss://echo.websocket.org"), invoker, CancellationToken.None); // <-- hangs
Console.WriteLine(ws.State);
Expected behavior
Correctly determining that server doesn't support HTTP/2 and falling back to HTTP/1.1.
Actual behavior
Hangs indefinitely.
Regression?
Didn't test on .NET 7 yet, but seems to behave similarly on .NET 8 and .NET 9.
Known Workarounds
Using inverse options seems to work:
ws.Options.HttpVersion = new(2, 0);
ws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrLower;
Configuration
Tested on .NET 8, 9: win-x64, linux-x64, linux-arm64.
Other information
No response
Activity
dotnet-policy-service commentedon Jan 29, 2025
Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.
MihaZupan commentedon Jan 29, 2025
I think this is due to a lack of
()
in our version selection code here:runtime/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs
Lines 80 to 81 in d551abb
Right now it's effectively
(!tryDowngrade && options.HttpVersion >= HttpVersion.Version20) || (the rest)
instead of
!tryDowngrade && (options.HttpVersion >= HttpVersion.Version20 || the rest)
So we just keep retrying H2.
Clearly we're lacking test coverage here.