Skip to content

Kestrel should ignore Content-Length: 0 on a WebSocket upgrade #40882

@Tratcher

Description

@Tratcher

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

A customer using YARP to proxy websockets has found that some 101 responses include a Content-Length: 0 header. The RFC says that a 1xx response can't have a body, but Content-Length: 0 doesn't strictly violate that.

https://datatracker.ietf.org/doc/html/rfc7231#section-6.2

1xx responses are terminated by the first empty line after
the status-line (the empty line signaling the end of the header
section).

Expected Behavior

Content-Length: 0 should be ignored on upgraded responses. A non-zero content-length should cause an exception from UpgradeAsync, not later when writing to the stream.

Steps To Reproduce

app.MapGet("/", async context => 
{
    context.Response.ContentLength = 0;
    var upgradeStream = await context.Features.Get<IHttpUpgradeFeature>().UpgradeAsync();
    await upgradeStream.WriteAsync(new byte[1]);
});

Put something like var ws = new WebSocket("wss://localhost:5001"); in a browser developer window works.

Exceptions (if any)

ProxyError: UpgradeResponseClient, ProxyException: System.InvalidOperationException: Response Content-Length mismatch: too many bytes written (211 of 0).
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.VerifyAndUpdateWrite(Int32 count)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.WritePipeAsync(ReadOnlyMemory1 data, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.WriteAsync(ReadOnlyMemory1 source, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpUpgradeStream.WriteAsync(ReadOnlyMemory`1 source, CancellationToken cancellationToken)
at Yarp.ReverseProxy.Forwarder.StreamCopier.CopyAsync(Stream input, Stream output, Int64 promisedContentLength, StreamCopierTelemetry telemetry, ActivityCancellationTokenSource activityToken, CancellationToken cancellation)

.NET Version

6

Anything else?

No response

Metadata

Metadata

Assignees

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-kestrel

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions