Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit de913c4

Browse files
author
Cesar Blum Silveira
committed
Address some PR comments.
1 parent c4f160d commit de913c4

File tree

5 files changed

+64
-147
lines changed

5 files changed

+64
-147
lines changed

src/Microsoft.AspNet.Server.Kestrel/Http/Frame.FeatureCollection.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,5 +325,8 @@ void IHttpRequestLifetimeFeature.Abort()
325325
{
326326
Abort();
327327
}
328+
329+
// TODO: remove before merging.
330+
public bool IsLocal { get; set; }
328331
}
329332
}

src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -731,18 +731,18 @@ protected bool TakeStartLine(SocketInput input)
731731
// URI was encoded, unescape and then parse as utf8
732732
pathEnd = UrlPathDecoder.Unescape(pathBegin, pathEnd);
733733
requestUrlPath = pathBegin.GetUtf8String(pathEnd);
734-
735-
if (PathNormalizer.NeedsNormalization(requestUrlPath))
736-
{
737-
requestUrlPath = PathNormalizer.Normalize(requestUrlPath);
738-
}
739734
}
740735
else
741736
{
742737
// URI wasn't encoded, parse as ASCII
743738
requestUrlPath = pathBegin.GetAsciiString(pathEnd);
744739
}
745740

741+
if (PathNormalizer.NeedsNormalization(requestUrlPath))
742+
{
743+
requestUrlPath = PathNormalizer.Normalize(requestUrlPath);
744+
}
745+
746746
consumed = scan;
747747
Method = method;
748748
RequestUri = requestUrlPath;

src/Microsoft.AspNet.Server.Kestrel/Http/PathNormalizer.cs

Lines changed: 46 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -15,84 +15,57 @@ public static bool NeedsNormalization(string path)
1515

1616
public static string Normalize(string path)
1717
{
18-
// Skip leading . and .. segments
19-
var start = 0;
20-
while (start < path.Length && path[start] == '.')
18+
if (path.IndexOf('/') > -1)
2119
{
22-
if (start + 1 == path.Length)
23-
{
24-
start += 1;
25-
}
26-
else if (start + 2 == path.Length &&
27-
path[start + 1] == '.')
28-
{
29-
start += 2;
30-
}
31-
else if (start + 1 < path.Length &&
32-
path[start + 1] == '/')
33-
{
34-
start += 2;
35-
}
36-
else if (start + 2 < path.Length &&
37-
path[start + 1] == '.' &&
38-
path[start + 2] == '/')
39-
{
40-
start += 3;
41-
}
42-
else
43-
{
44-
break;
45-
}
46-
}
20+
var normalizedChars = new char[path.Length];
21+
var normalizedIndex = normalizedChars.Length;
22+
var pathIndex = path.Length - 1;
23+
var skipSegments = 0;
4724

48-
var normalizedChars = new char[path.Length];
49-
var normalizedIndex = normalizedChars.Length;
50-
var pathIndex = path.Length - 1;
51-
var skipSegments = 0;
52-
53-
while (pathIndex >= start)
54-
{
55-
if (pathIndex >= start + 2 && path[pathIndex] == '.' && path[pathIndex - 1] == '.' && path[pathIndex - 2] == '/')
25+
while (pathIndex >= 0)
5626
{
57-
if (normalizedIndex == normalizedChars.Length || normalizedChars[normalizedIndex] != '/')
27+
if (pathIndex >= 2 && path[pathIndex] == '.' && path[pathIndex - 1] == '.' && path[pathIndex - 2] == '/')
5828
{
59-
normalizedChars[--normalizedIndex] = '/';
60-
}
29+
if (normalizedIndex == normalizedChars.Length || normalizedChars[normalizedIndex] != '/')
30+
{
31+
normalizedChars[--normalizedIndex] = '/';
32+
}
6133

62-
skipSegments++;
63-
pathIndex -= 3;
64-
}
65-
else if (pathIndex >= start + 1 && path[pathIndex] == '.' && path[pathIndex - 1] == '/')
66-
{
67-
pathIndex -= 2;
68-
}
69-
else
70-
{
71-
while (pathIndex >= start)
34+
skipSegments++;
35+
pathIndex -= 3;
36+
}
37+
else if (pathIndex >= 1 && path[pathIndex] == '.' && path[pathIndex - 1] == '/')
7238
{
73-
var lastChar = path[pathIndex];
74-
75-
if (skipSegments == 0)
39+
pathIndex -= 2;
40+
}
41+
else
42+
{
43+
while (pathIndex >= 0)
7644
{
77-
normalizedChars[--normalizedIndex] = lastChar;
78-
}
45+
var lastChar = path[pathIndex];
7946

80-
pathIndex--;
47+
if (skipSegments == 0)
48+
{
49+
normalizedChars[--normalizedIndex] = lastChar;
50+
}
8151

82-
if (lastChar == '/')
83-
{
84-
break;
52+
pathIndex--;
53+
54+
if (lastChar == '/')
55+
{
56+
break;
57+
}
8558
}
86-
}
8759

88-
if (skipSegments > 0)
89-
{
90-
skipSegments--;
60+
if (skipSegments > 0)
61+
{
62+
skipSegments--;
63+
}
9164
}
9265
}
93-
}
9466

95-
path = new string(normalizedChars, normalizedIndex, normalizedChars.Length - normalizedIndex);
67+
path = new string(normalizedChars, normalizedIndex, normalizedChars.Length - normalizedIndex);
68+
}
9669

9770
if (!path.IsNormalized(NormalizationForm.FormC))
9871
{
@@ -102,14 +75,21 @@ public static string Normalize(string path)
10275
return path;
10376
}
10477

105-
public static bool ContainsDotSegments(string path)
78+
private static bool ContainsDotSegments(string path)
10679
{
10780
if (path.Length == 0)
10881
{
10982
return false;
11083
}
11184

112-
for (var i = 0; i < path.Length; i++)
85+
var start = path.IndexOf('/');
86+
87+
if (start == -1)
88+
{
89+
return false;
90+
}
91+
92+
for (var i = start; i < path.Length; i++)
11393
{
11494
if (path[i] == '/')
11595
{

test/Microsoft.AspNet.Server.Kestrel.FunctionalTests/RequestTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public async Task RequestPathIsNormalized()
134134
{ "server.urls", "http://localhost:8795" }
135135
}).Build();
136136

137-
var builder = new WebApplicationBuilder()
137+
var builder = new WebHostBuilder()
138138
.UseConfiguration(config)
139139
.UseServer("Microsoft.AspNet.Server.Kestrel")
140140
.Configure(app =>

test/Microsoft.AspNet.Server.KestrelTests/PathNormalizerTests.cs

Lines changed: 9 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,6 @@ public class PathNormalizerTests
1515
[InlineData("/a/", "/a/")]
1616
[InlineData("/a/b", "/a/b")]
1717
[InlineData("/a/b/", "/a/b/")]
18-
[InlineData("", ".")]
19-
[InlineData("", "..")]
20-
[InlineData("", "./")]
21-
[InlineData("", "../")]
22-
[InlineData("", "./.")]
23-
[InlineData("", "./..")]
24-
[InlineData("", "../.")]
25-
[InlineData("", "../..")]
26-
[InlineData("", "././")]
27-
[InlineData("", "./../")]
28-
[InlineData("", ".././")]
29-
[InlineData("", "../../")]
30-
[InlineData("a", "./a")]
31-
[InlineData("a", "../a")]
3218
[InlineData("/a", "/./a")]
3319
[InlineData("/a", "/../a")]
3420
[InlineData("/a/b", "/a/./b")]
@@ -42,31 +28,22 @@ public class PathNormalizerTests
4228
[InlineData("/b", "/a/.././../b")]
4329
[InlineData("/b/", "/a/.././../b/")]
4430
[InlineData("/a/d", "/a/b/c/./../../d")]
45-
[InlineData("a/d", "./a/b/c/./../../d")]
46-
[InlineData("a/d", "../a/b/c/./../../d")]
47-
[InlineData("a/d", "./../a/b/c/./../../d")]
48-
[InlineData("a/d", ".././a/b/c/./../../d")]
4931
[InlineData("/a/d", "/./a/b/c/./../../d")]
5032
[InlineData("/a/d", "/../a/b/c/./../../d")]
5133
[InlineData("/a/d", "/./../a/b/c/./../../d")]
5234
[InlineData("/a/d", "/.././a/b/c/./../../d")]
53-
[InlineData(".a", ".a")]
54-
[InlineData("..a", "..a")]
55-
[InlineData("...", "...")]
5635
[InlineData("/.a", "/.a")]
5736
[InlineData("/..a", "/..a")]
5837
[InlineData("/...", "/...")]
5938
[InlineData("/a/.../b", "/a/.../b")]
60-
[InlineData("a/.../b", "a/.../b")]
6139
[InlineData("/b", "/a/../.../../b")]
6240
[InlineData("/a/.b", "/a/.b")]
6341
[InlineData("/a/..b", "/a/..b")]
64-
[InlineData("a/.b", "a/.b")]
65-
[InlineData("a/..b", "a/..b")]
6642
[InlineData("/a/b.", "/a/b.")]
67-
[InlineData("a/b.", "a/b.")]
6843
[InlineData("/a/b..", "/a/b..")]
69-
[InlineData("a/b..", "a/b..")]
44+
[InlineData("a/b", "a/b")]
45+
[InlineData("a/c", "a/b/../c")]
46+
[InlineData("*", "*")]
7047
public void RemovesDotSegments(string expected, string input)
7148
{
7249
var result = PathNormalizer.Normalize(input);
@@ -81,55 +58,6 @@ public void NormalizesToNFC()
8158
Assert.Equal("/\u00C5", result);
8259
}
8360

84-
[Theory]
85-
[InlineData(".")]
86-
[InlineData("..")]
87-
[InlineData("/.")]
88-
[InlineData("/..")]
89-
[InlineData("./")]
90-
[InlineData("../")]
91-
[InlineData("/./")]
92-
[InlineData("/../")]
93-
[InlineData("a/.")]
94-
[InlineData("a/..")]
95-
[InlineData("a/./")]
96-
[InlineData("a/..")]
97-
[InlineData("a/../")]
98-
[InlineData("/a/.")]
99-
[InlineData("/a/..")]
100-
[InlineData("/a/./")]
101-
[InlineData("/a/..")]
102-
[InlineData("/a/../")]
103-
[InlineData("a/./b")]
104-
[InlineData("a/../b")]
105-
[InlineData("/a/./b")]
106-
[InlineData("/a/../b")]
107-
[InlineData("/a/./b/")]
108-
[InlineData("/a/../b/")]
109-
public void ContainsDotSegmentsTrue(string path)
110-
{
111-
Assert.True(PathNormalizer.ContainsDotSegments(path));
112-
}
113-
114-
[Theory]
115-
[InlineData("")]
116-
[InlineData("a")]
117-
[InlineData("/a")]
118-
[InlineData("/a/b")]
119-
[InlineData("...")]
120-
[InlineData(".a")]
121-
[InlineData("..a")]
122-
[InlineData("/.a")]
123-
[InlineData("/..a")]
124-
[InlineData("/a/.b")]
125-
[InlineData("/a/..b")]
126-
[InlineData("/a/..b")]
127-
[InlineData("/a/...")]
128-
public void ContainsDotSegmentsFalse(string path)
129-
{
130-
Assert.False(PathNormalizer.ContainsDotSegments(path));
131-
}
132-
13361
[Fact]
13462
public void PathNeedsNormalizationIfNotInNFC()
13563
{
@@ -141,5 +69,11 @@ public void PathNeedsNormalizationIfItContainsDotSegments()
14169
{
14270
Assert.True(PathNormalizer.NeedsNormalization("/a/../b"));
14371
}
72+
73+
[Fact]
74+
public void PathDoesNotNeedNormalizationIfInNFCAndDoesNotContainDotSegments()
75+
{
76+
Assert.False(PathNormalizer.NeedsNormalization("/a/\u00C5"));
77+
}
14478
}
14579
}

0 commit comments

Comments
 (0)