diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs index 1c38bf462d1b..4dc4ac37b6d2 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -701,7 +701,7 @@ private bool TryValidatePseudoHeaders() var requestLineLength = _methodText!.Length + Scheme!.Length + hostText.Length + path.Length; if (requestLineLength > ServerOptions.Limits.MaxRequestLineSize) { - Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestLineTooLong), Http3ErrorCode.ProtocolError); + Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestLineTooLong), Http3ErrorCode.RequestRejected); return false; } diff --git a/src/Servers/Kestrel/Core/src/KestrelServerLimits.cs b/src/Servers/Kestrel/Core/src/KestrelServerLimits.cs index 0f19226dea42..be0bf72314f6 100644 --- a/src/Servers/Kestrel/Core/src/KestrelServerLimits.cs +++ b/src/Servers/Kestrel/Core/src/KestrelServerLimits.cs @@ -91,7 +91,7 @@ public long? MaxRequestBufferSize /// Defaults to 8,192 bytes (8 KB). /// /// - /// For HTTP/2 this measures the total size of the required pseudo headers + /// For HTTP/2 and HTTP/3 this measures the total size of the required pseudo headers /// :method, :scheme, :authority, and :path. /// public int MaxRequestLineSize diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs index b683b6b08e68..92a3a9b16015 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs @@ -2612,6 +2612,24 @@ await ExpectAsync(Http2FrameType.HEADERS, await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false); } + [Fact] + public async Task HEADERS_Received_RequestLineLength_StreamError() + { + var headers = new[] + { + new KeyValuePair(HeaderNames.Method, new string('A', 8192 / 2)), + new KeyValuePair(HeaderNames.Path, "/" + new string('A', 8192 / 2)), + new KeyValuePair(HeaderNames.Scheme, "http") + }; + + await InitializeConnectionAsync(_noopApplication); + await StartStreamAsync(1, headers, endStream: true); + + await WaitForStreamErrorAsync(1, Http2ErrorCode.PROTOCOL_ERROR, CoreStrings.BadRequest_RequestLineTooLong); + + await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false); + } + [Fact] public async Task PRIORITY_Received_StreamIdZero_ConnectionError() { diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs index 27f402a2ddc8..46e5c2ffbcb7 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs @@ -485,7 +485,7 @@ public async Task MaxRequestLineSize_Reset() var requestStream = await InitializeConnectionAndStreamsAsync(_noopApplication); await requestStream.SendHeadersAsync(headers, endStream: true); - await requestStream.WaitForStreamErrorAsync(Http3ErrorCode.ProtocolError, + await requestStream.WaitForStreamErrorAsync(Http3ErrorCode.RequestRejected, CoreStrings.BadRequest_RequestLineTooLong); } @@ -2358,5 +2358,18 @@ public async Task MaxRequestBodySize_AppCanRaiseLimit(bool includeContentLength) Assert.Equal("200", receivedHeaders[HeaderNames.Status]); Assert.Equal("0", receivedHeaders[HeaderNames.ContentLength]); } + + [Fact] + public Task HEADERS_Received_RequestLineLength_Error() + { + var headers = new[] + { + new KeyValuePair(HeaderNames.Method, new string('A', 8192 / 2)), + new KeyValuePair(HeaderNames.Path, "/" + new string('A', 8192 / 2)), + new KeyValuePair(HeaderNames.Scheme, "http") + }; + + return HEADERS_Received_InvalidHeaderFields_StreamError(headers, CoreStrings.BadRequest_RequestLineTooLong, Http3ErrorCode.RequestRejected); + } } }