Skip to content

WebSocket compression issues when testing server-side with Autobahn #52551

@BrennanConroy

Description

@BrennanConroy

When trying to add WebSockets compression support to ASP.NET Core I ran the Autobahn test suite against the server and hit multiple test cases failing.

I'm going to focus on a single one in this issue because it's already complicated enough (and hopefully same root issue).

This specific issue is looking at test 12.4.11 which states: "Send 1000 compressed messages each of payload size 8192, auto-fragment to 256 octets. Use default permessage-deflate offer." I modified the client window bits to be 12 (was testing various window bits and hitting issues on different tests with different window bits)

I manually looped over all the messages until I found one that wasn't 8192 in size and have isolated that individual message for the repro below.

Single message test bytes from client
compressed8192fromClient12bit.txt

[Fact]
public async Task CompressTest()
{
    WebSocketTestStream stream = new();
    using WebSocket server = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
    {
        IsServer = true,
        KeepAliveInterval = TimeSpan.Zero,
        DangerousDeflateOptions = new()
        {
            ClientMaxWindowBits = 12,
            ServerMaxWindowBits = 15,
            ClientContextTakeover = false,
        }
    });
    using WebSocket client = WebSocket.CreateFromStream(stream.Remote, new WebSocketCreationOptions
    {
        KeepAliveInterval = TimeSpan.Zero,
        DangerousDeflateOptions = new()
        {
            ClientMaxWindowBits = 12,
            ServerMaxWindowBits = 15,
            ClientContextTakeover = false,
        }
    });

    using var fileStream = File.OpenRead("<path to>/compressed8192fromClient12bit.txt");
    int r = 1;
    var fileBuf = new byte[2000];
    while (r != 0)
    {
        r = await fileStream.ReadAsync(fileBuf);
        await stream.Remote.WriteAsync(fileBuf.AsMemory(0, r), default);
    }

    var buf = new byte[8192];
    int total = 0;
    while (true)
    {
        var res = await server.ReceiveAsync(buf, default);
        total += res.Count;
        if (res.EndOfMessage == true)
        {
            Assert.Equal(8192, total);
            break;
        }
    }
}

Some more information about this specific message:
Inflated sections (bytes): 320, 3226, 822, 1736, 2115 - total = 8219
WebSocket frame lengths: 256, 256, 256, 256, 243

cc @zlatanov in case you're interested

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions