Skip to content

Commit a15f83c

Browse files
committed
WIP
1 parent d1dc519 commit a15f83c

File tree

4 files changed

+30
-29
lines changed

4 files changed

+30
-29
lines changed

src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Diagnostics;
66
using System.IO.Pipelines;
77
using Microsoft.AspNetCore.Connections;
8+
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
89

910
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
1011

@@ -136,6 +137,7 @@ private async Task PumpAsync()
136137
// Read() will have already have greedily consumed the entire request body if able.
137138
if (result.IsCompleted)
138139
{
140+
KestrelMetrics.AddConnectionEndReason(_context.MetricsContext, ConnectionEndReason.UnexpectedEndOfRequestContent);
139141
ThrowUnexpectedEndOfRequestContent();
140142
}
141143
}

src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ bool TrimAndTakeStartLine(ref SequenceReader<byte> reader)
229229
if (!_parser.ParseRequestLine(new Http1ParsingHandler(this), ref trimmedReader))
230230
{
231231
// We read the maximum allowed but didn't complete the start line.
232-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.InvalidRequestLine);
233232
KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestLineTooLong);
234233
}
235234

@@ -273,7 +272,6 @@ bool TrimAndTakeMessageHeaders(ref SequenceReader<byte> reader, bool trailers)
273272
if (!_parser.ParseHeaders(new Http1ParsingHandler(this, trailers), ref trimmedReader))
274273
{
275274
// We read the maximum allowed but didn't complete the headers.
276-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.InvalidRequestHeaders);
277275
KestrelBadHttpRequestException.Throw(RequestRejectionReason.HeadersExceedMaxTotalSize);
278276
}
279277

@@ -608,12 +606,10 @@ internal void EnsureHostHeaderExists()
608606
return;
609607
}
610608

611-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.InvalidRequestHeaders);
612609
KestrelBadHttpRequestException.Throw(RequestRejectionReason.MissingHostHeader);
613610
}
614611
else if (hostCount > 1)
615612
{
616-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.InvalidRequestHeaders);
617613
KestrelBadHttpRequestException.Throw(RequestRejectionReason.MultipleHostHeaders);
618614
}
619615
else if (_requestTargetForm != HttpRequestTarget.OriginForm)
@@ -722,7 +718,6 @@ protected override bool TryParseRequest(ReadResult result, out bool endConnectio
722718
}
723719
catch (InvalidOperationException) when (_requestProcessingStatus == RequestProcessingStatus.ParsingHeaders)
724720
{
725-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.InvalidRequestHeaders);
726721
KestrelBadHttpRequestException.Throw(RequestRejectionReason.MalformedRequestInvalidHeaders);
727722
throw;
728723
}
@@ -751,11 +746,9 @@ protected override bool TryParseRequest(ReadResult result, out bool endConnectio
751746
endConnection = true;
752747
return true;
753748
case RequestProcessingStatus.ParsingRequestLine:
754-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.InvalidRequestHeaders);
755749
KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidRequestLine);
756750
break;
757751
case RequestProcessingStatus.ParsingHeaders:
758-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.InvalidRequestHeaders);
759752
KestrelBadHttpRequestException.Throw(RequestRejectionReason.MalformedRequestInvalidHeaders);
760753
break;
761754
}
@@ -771,7 +764,6 @@ protected override bool TryParseRequest(ReadResult result, out bool endConnectio
771764
{
772765
// In this case, there is an ongoing request but the start line/header parsing has timed out, so send
773766
// a 408 response.
774-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.RequestHeadersTimeout);
775767
KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestHeadersTimeout);
776768
}
777769

@@ -787,26 +779,20 @@ protected override bool TryParseRequest(ReadResult result, out bool endConnectio
787779
}
788780
}
789781

782+
internal static ConnectionEndReason GetConnectionEndReason(Microsoft.AspNetCore.Http.BadHttpRequestException ex)
783+
{
790784
#pragma warning disable CS0618 // Type or member is obsolete
791-
private void OnBadRequest(ReadOnlySequence<byte> requestData, BadHttpRequestException ex)
785+
var kestrelEx = ex as BadHttpRequestException;
792786
#pragma warning restore CS0618 // Type or member is obsolete
793-
{
794-
var reason = ex.Reason;
795787

796-
// Some code shared between HTTP versions throws errors. For example, HttpRequestHeaders collection
797-
// throws when an invalid content length is set.
798-
// Only want to set a reasons for HTTP/1.1 connection, so set end reason by catching the exception here.
799-
switch (reason)
788+
switch (kestrelEx?.Reason)
800789
{
801790
case RequestRejectionReason.UnrecognizedHTTPVersion:
802-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.InvalidHttpVersion);
803-
DetectHttp2Preface(requestData);
804-
break;
791+
return ConnectionEndReason.InvalidHttpVersion;
805792
case RequestRejectionReason.InvalidRequestLine:
806793
case RequestRejectionReason.RequestLineTooLong:
807794
case RequestRejectionReason.InvalidRequestTarget:
808-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.InvalidRequestLine);
809-
break;
795+
return ConnectionEndReason.InvalidRequestLine;
810796
case RequestRejectionReason.InvalidRequestHeadersNoCRLF:
811797
case RequestRejectionReason.InvalidRequestHeader:
812798
case RequestRejectionReason.InvalidContentLength:
@@ -821,16 +807,31 @@ private void OnBadRequest(ReadOnlySequence<byte> requestData, BadHttpRequestExce
821807
case RequestRejectionReason.MissingHostHeader:
822808
case RequestRejectionReason.MultipleHostHeaders:
823809
case RequestRejectionReason.InvalidHostHeader:
824-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.InvalidRequestHeaders);
825-
break;
810+
return ConnectionEndReason.InvalidRequestHeaders;
826811
case RequestRejectionReason.TlsOverHttpError:
827-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.TlsOverHttp);
828-
break;
812+
return ConnectionEndReason.TlsOverHttp;
813+
case RequestRejectionReason.UnexpectedEndOfRequestContent:
814+
return ConnectionEndReason.UnexpectedEndOfRequestContent;
829815
default:
830816
// In some scenarios the end reason might already be set to a more specific error
831817
// and attempting to set the reason again has no impact.
832-
KestrelMetrics.AddConnectionEndReason(MetricsContext, ConnectionEndReason.OtherError);
833-
break;
818+
return ConnectionEndReason.OtherError;
819+
}
820+
}
821+
822+
#pragma warning disable CS0618 // Type or member is obsolete
823+
private void OnBadRequest(ReadOnlySequence<byte> requestData, BadHttpRequestException ex)
824+
#pragma warning restore CS0618 // Type or member is obsolete
825+
{
826+
// Some code shared between HTTP versions throws errors. For example, HttpRequestHeaders collection
827+
// throws when an invalid content length is set.
828+
// Only want to set a reasons for HTTP/1.1 connection, so set end reason by catching the exception here.
829+
var reason = GetConnectionEndReason(ex);
830+
KestrelMetrics.AddConnectionEndReason(MetricsContext, reason);
831+
832+
if (ex.Reason == RequestRejectionReason.UnrecognizedHTTPVersion)
833+
{
834+
DetectHttp2Preface(requestData);
834835
}
835836
}
836837

src/Servers/Kestrel/Core/src/Internal/Http/Http1ContentLengthMessageBody.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ private void VerifyIsNotReading()
270270
{
271271
if (_readResult.IsCompleted)
272272
{
273-
KestrelMetrics.AddConnectionEndReason(_context.MetricsContext, ConnectionEndReason.UnexpectedEndOfRequestContent);
274273
KestrelBadHttpRequestException.Throw(RequestRejectionReason.UnexpectedEndOfRequestContent);
275274
}
276275

src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,8 +1408,7 @@ public void SetBadRequestState(BadHttpRequestException ex)
14081408
WriteDiagnosticEvent(ServiceContext.DiagnosticSource, badRequestEventName, this);
14091409
}
14101410

1411-
// TODO: A specific error should be set. Pass unset here
1412-
DisableKeepAlive(ConnectionEndReason.Unexpected);
1411+
DisableKeepAlive(Http1Connection.GetConnectionEndReason(ex));
14131412
}
14141413

14151414
internal virtual void DisableKeepAlive(ConnectionEndReason reason)

0 commit comments

Comments
 (0)