Skip to content
24 changes: 23 additions & 1 deletion src/Servers/HttpSys/src/RequestProcessing/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Server.HttpSys;
Expand Down Expand Up @@ -134,9 +136,29 @@ public long? ContentLength
{
// Note Http.Sys adds the Transfer-Encoding: chunked header to HTTP/2 requests with bodies for back compat.
var transferEncoding = Headers[HeaderNames.TransferEncoding].ToString();
if (string.Equals("chunked", transferEncoding.Trim(), StringComparison.OrdinalIgnoreCase))
if (transferEncoding != null && string.Equals("chunked", transferEncoding.Split(',')[0].Trim(), StringComparison.OrdinalIgnoreCase))
{
_contentBoundaryType = BoundaryType.Chunked;

// https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2
// A sender MUST NOT send a Content-Length header field in any message
// that contains a Transfer-Encoding header field.
// https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3
// If a message is received with both a Transfer-Encoding and a
// Content-Length header field, the Transfer-Encoding overrides the
// Content-Length. Such a message might indicate an attempt to
// perform request smuggling (Section 9.5) or response splitting
// (Section 9.4) and ought to be handled as an error. A sender MUST
// remove the received Content-Length field prior to forwarding such
// a message downstream.
// We should remove the Content-Length request header in this case, for compatibility
// reasons, include X-Content-Length so that the original Content-Length is still available.
if (!StringValues.IsNullOrEmpty(Headers.ContentLength))
{
IHeaderDictionary headerDictionary = Headers;
headerDictionary.Add("X-Content-Length", headerDictionary[HeaderNames.ContentLength]);
Headers.ContentLength = StringValues.Empty;
}
}
else
{
Expand Down