Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ private void ParseRequestLine(TRequestHandler handler, ReadOnlySpan<byte> reques
// Consume space
offset++;

while ((uint)offset < (uint)requestLine.Length
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess there will be a small perf hit in HTTP/1.1 parsing from this extra check. Check benchmarks?

I wonder whether it would be faster to integrate logic to skip extra spaces to the for loops in path and query string that check for a space.

&& requestLine[offset] == ByteSpace)
{
// It's invalid to have multiple spaces between the url resource and version
// but some clients do it. Skip them.
offset++;
}

// Version + CR is 9 bytes which should take us to .Length
// LF should have been dropped prior to method call
if ((uint)offset + 9 != (uint)requestLine.Length || requestLine[offset + 8] != ByteCR)
Expand Down
18 changes: 16 additions & 2 deletions src/Servers/Kestrel/shared/test/HttpParsingData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ public static IEnumerable<string[]> RequestLineValidData
var httpVersions = new[]
{
"HTTP/1.0",
"HTTP/1.1"
"HTTP/1.1",
" HTTP/1.1",
" HTTP/1.1"
};

return from method in methods
Expand All @@ -91,7 +93,7 @@ select new[]
$"{path.Item1}",
$"{path.Item2}",
queryString,
httpVersion
httpVersion.Trim()
};
}
}
Expand Down Expand Up @@ -164,6 +166,12 @@ public static IEnumerable<string> RequestLineInvalidData
"GET / HTTP/1.1\n",
"GET / HTTP/1.0\rA\n",
"GET / HTTP/1.1\ra\n",
"GET / HTTP/1.1\r\n",
"GET / HTTP/1.1\r\n",
"GET / HTTP/1.1\r\n",
"GET / HTTP/1.1\r\n",
"GET / HTTP/1.1 \r\n",
"GET / HTTP/1.1 \r\n",
"GET / H\r\n",
"GET / HT\r\n",
"GET / HTT\r\n",
Expand Down Expand Up @@ -195,6 +203,12 @@ public static IEnumerable<string> RequestLineInvalidData
"CUSTOM / HTTP/1.1\n",
"CUSTOM / HTTP/1.0\rA\n",
"CUSTOM / HTTP/1.1\ra\n",
"CUSTOM / HTTP/1.1\r\n",
"CUSTOM / HTTP/1.1\r\n",
"CUSTOM / HTTP/1.1\r\n",
"CUSTOM / HTTP/1.1\r\n",
"CUSTOM / HTTP/1.1 \r\n",
"CUSTOM / HTTP/1.1 \r\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, do we know if HTTP.sys would accept any of the above invalid requests?

"CUSTOM / H\r\n",
"CUSTOM / HT\r\n",
"CUSTOM / HTT\r\n",
Expand Down