Is there an existing issue for this?
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
Is there an existing issue for this?
Describe the bug
A customer using YARP to proxy websockets has found that some 101 responses include a
Content-Length: 0header. The RFC says that a 1xx response can't have a body, butContent-Length: 0doesn't strictly violate that.https://datatracker.ietf.org/doc/html/rfc7231#section-6.2
Expected Behavior
Content-Length: 0should 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
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(ReadOnlyMemory
1 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