Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs')
-rw-r--r--src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs58
1 files changed, 39 insertions, 19 deletions
diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs
index 6bc2b7c168..6fb8c2c1e7 100644
--- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs
+++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs
@@ -288,6 +288,11 @@ public class HttpParser<TRequestHandler> : IHttpParser<TRequestHandler> where TR
// This was a multi-line header. Advance the reader.
reader.Advance(length);
+ if (reader.End)
+ {
+ return true;
+ }
+
continue;
}
@@ -384,36 +389,51 @@ public class HttpParser<TRequestHandler> : IHttpParser<TRequestHandler> where TR
header = currentSlice.Slice(reader.Position, lineEnd);
}
- var headerSpan = header.ToSpan();
+ byte[]? array = null;
+ int length = (int)header.Length;
+ Span<byte> span = length <= 256 ? stackalloc byte[length] : array = ArrayPool<byte>.Shared.Rent(length);
- // 'a:b\n' or 'a:b\r\n'
- var minHeaderSpan = _disableHttp1LineFeedTerminators ? 5 : 4;
- if (headerSpan.Length < minHeaderSpan)
+ try
{
- RejectRequestHeader(headerSpan);
- }
+ header.CopyTo(span);
+ span = span.Slice(0, length);
- var terminatorSize = -1;
+ // 'a:b\n' or 'a:b\r\n'
+ var minHeaderSpan = _disableHttp1LineFeedTerminators ? 5 : 4;
+ if (span.Length < minHeaderSpan)
+ {
+ RejectRequestHeader(span);
+ }
- if (headerSpan[^1] == ByteLF)
- {
- if (headerSpan[^2] == ByteCR)
+ var terminatorSize = -1;
+
+ if (span[^1] == ByteLF)
{
- terminatorSize = 2;
+ if (span[^2] == ByteCR)
+ {
+ terminatorSize = 2;
+ }
+ else if (!_disableHttp1LineFeedTerminators)
+ {
+ terminatorSize = 1;
+ }
}
- else if (!_disableHttp1LineFeedTerminators)
+
+ // Last chance to bail if the terminator size is not valid or the header doesn't parse.
+ if (terminatorSize == -1 || !TryTakeSingleHeader(handler, span.Slice(0, span.Length - terminatorSize)))
{
- terminatorSize = 1;
+ RejectRequestHeader(span);
}
- }
- // Last chance to bail if the terminator size is not valid or the header doesn't parse.
- if (terminatorSize == -1 || !TryTakeSingleHeader(handler, headerSpan.Slice(0, headerSpan.Length - terminatorSize)))
+ return span.Length;
+ }
+ finally
{
- RejectRequestHeader(headerSpan);
+ if (array is not null)
+ {
+ ArrayPool<byte>.Shared.Return(array);
+ }
}
-
- return headerSpan.Length;
}
private static bool TryTakeSingleHeader(TRequestHandler handler, ReadOnlySpan<byte> headerLine)