Skip to content

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

Open
@DeagleGross

Description

@DeagleGross

Is there an existing issue for this?

  • I have searched the existing issues

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.

  • It failed on IIS hosted app: after calling context.WebSockets.AcceptWebSocketAsync() websocket.State is Open
    image
  • but client immediately disconnected:
Could not connect to ws://localhost:21156
12:00:24
Error: Unexpected server response: 101
Handshake Details
Request URL: http://localhost:21156/
Request Method: GET
Status Code: 101 Switching Protocols
Request Headers
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: gCyKijP/CPAUtW3Cjyf8gA==
Connection: Upgrade
Upgrade: websocket, websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: localhost:21156
Response Headers
Transfer-Encoding: chunked
Upgrade: websocket
Server: Microsoft-IIS/10.0
Sec-WebSocket-Accept: fiwTshwZAtNTY2V2+ynOPK4kFNk=
X-Powered-By: ASP.NET
Date: Mon, 28 Aug 2023 10:00:24 GMT

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsbugThis issue describes a behavior which is not expected - a bug.feature-iisIncludes: IIS, ANCMfeature-websocketsIncludes: WebSocketshelp candidateIndicates that the issues may be a good fit for community to help with. Requires work from eng. team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions