Skip to content

Commit b27739a

Browse files
benaadamsdavidfowl
authored andcommitted
Shrink ParseRequestLine inner loop (#6594)
1 parent c7f05c6 commit b27739a

File tree

1 file changed

+29
-40
lines changed

1 file changed

+29
-40
lines changed

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

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -73,62 +73,51 @@ public unsafe bool ParseRequestLine(TRequestHandler handler, in ReadOnlySequence
7373
private unsafe void ParseRequestLine(TRequestHandler handler, byte* data, int length)
7474
{
7575
// Get Method and set the offset
76-
var method = HttpUtilities.GetKnownMethod(data, length, out var offset);
76+
var method = HttpUtilities.GetKnownMethod(data, length, out var pathStartOffset);
7777

78-
Span<byte> customMethod = method == HttpMethod.Custom ?
79-
GetUnknownMethod(data, length, out offset) :
80-
default;
78+
Span<byte> customMethod = default;
79+
if (method == HttpMethod.Custom)
80+
{
81+
customMethod = GetUnknownMethod(data, length, out pathStartOffset);
82+
}
8183

84+
// Use a new offset var as pathStartOffset needs to be on stack
85+
// as its passed by reference above so can't be in register.
8286
// Skip space
83-
offset++;
87+
var offset = pathStartOffset + 1;
88+
if (offset >= length)
89+
{
90+
// Start of path not found
91+
RejectRequestLine(data, length);
92+
}
93+
94+
byte ch = data[offset];
95+
if (ch == ByteSpace || ch == ByteQuestionMark || ch == BytePercentage)
96+
{
97+
// Empty path is illegal, or path starting with percentage
98+
RejectRequestLine(data, length);
99+
}
84100

85-
byte ch = 0;
86101
// Target = Path and Query
87102
var pathEncoded = false;
88-
var pathStart = -1;
103+
var pathStart = offset;
104+
105+
// Skip first char (just checked)
106+
offset++;
107+
108+
// Find end of path and if path is encoded
89109
for (; offset < length; offset++)
90110
{
91111
ch = data[offset];
92-
if (ch == ByteSpace)
112+
if (ch == ByteSpace || ch == ByteQuestionMark)
93113
{
94-
if (pathStart == -1)
95-
{
96-
// Empty path is illegal
97-
RejectRequestLine(data, length);
98-
}
99-
100-
break;
101-
}
102-
else if (ch == ByteQuestionMark)
103-
{
104-
if (pathStart == -1)
105-
{
106-
// Empty path is illegal
107-
RejectRequestLine(data, length);
108-
}
109-
114+
// End of path
110115
break;
111116
}
112117
else if (ch == BytePercentage)
113118
{
114-
if (pathStart == -1)
115-
{
116-
// Path starting with % is illegal
117-
RejectRequestLine(data, length);
118-
}
119-
120119
pathEncoded = true;
121120
}
122-
else if (pathStart == -1)
123-
{
124-
pathStart = offset;
125-
}
126-
}
127-
128-
if (pathStart == -1)
129-
{
130-
// Start of path not found
131-
RejectRequestLine(data, length);
132121
}
133122

134123
var pathBuffer = new Span<byte>(data + pathStart, offset - pathStart);

0 commit comments

Comments
 (0)