dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.45k stars 10.03k forks source link

Inconsistency between IIS and Kestrel for websocket connect operation with duplicate 'Upgrade: websocket, websocket' header #50364

Open DeagleGross opened 1 year ago

DeagleGross commented 1 year ago

Is there an existing issue for this?

Describe the bug

Accidentally I've sent a websocket connect request with duplicate websocket header like here: image

It worked on a Kestrel based app: websocket connection was established, and I could send \ receive messages and gracefully terminate a connection.

Expected Behavior

As per my understanding, either Kestrel implementation should fail as well, or IIS should handle duplicate Upgrade: websocket, websocket header. Let me know, if I am doing something wrong.

Steps To Reproduce

repro is as simple as creating an ASP.NET core project and using such setup in Program.cs:

app.UseWebSockets();
app.Use(async (context, next) =>
{
    if (context.WebSockets.IsWebSocketRequest)
    {
        using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
        await Echo(webSocket);
    }
    else
    {
        await next(context);
    }
});

app.Run();

and make a websocket connect call with Upgrade: websocket, websocket header.

if you need a repro in a repository:

Exceptions (if any)

Unhandled exception. System.Net.WebSockets.WebSocketException (203): The server's response was missing the required header 'Connection'.
   at System.Net.WebSockets.WebSocketHandle.ValidateHeader(HttpHeaders headers, String name, String expectedValue)
   at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options)
   at System.Net.WebSockets.ClientWebSocket.ConnectAsyncCore(Uri uri, CancellationToken cancellationToken)
   at Program.<Main>$(String[] args) in C:\code\personal\repro-1\WebApp\Client\Program.cs:line 10
   at Program.<Main>(String[] args)

.NET Version

net6.0 (local 6.0.316)

Anything else?

No response

amcasey commented 1 year ago

I don't see anything in the RFC about the values needing to be distinct, so it does seem like IIS is being unnecessarily restrictive.