Skip to content

Commit 744a5d2

Browse files
committed
Merged PR 27452: Merge from public
2 parents 1c11d81 + ac8b3b0 commit 744a5d2

File tree

20 files changed

+2185
-57
lines changed

20 files changed

+2185
-57
lines changed

.azure/pipelines/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,13 +489,13 @@ stages:
489489
$(_InternalRuntimeDownloadArgs)
490490
displayName: Run build.sh
491491
- script: git clean -xfd src/**/obj/;
492-
./dockerbuild.sh bionic --ci --nobl --arch x64 --build-installers --no-build-deps --no-build-nodejs
492+
./dockerbuild.sh bionic --ci --nobl --arch x64 --build-installers --no-build-deps --no-build-nodejs --init-nuget
493493
-p:OnlyPackPlatformSpecificPackages=true -p:BuildRuntimeArchive=false -p:LinuxInstallerType=deb
494494
$(_BuildArgs)
495495
$(_InternalRuntimeDownloadArgs)
496496
displayName: Build Debian installers
497497
- script: git clean -xfd src/**/obj/;
498-
./dockerbuild.sh rhel --ci --nobl --arch x64 --build-installers --no-build-deps --no-build-nodejs
498+
./dockerbuild.sh rhel --ci --nobl --arch x64 --build-installers --no-build-deps --no-build-nodejs --init-nuget
499499
-p:OnlyPackPlatformSpecificPackages=true -p:BuildRuntimeArchive=false -p:LinuxInstallerType=rpm
500500
-p:AssetManifestFileName=aspnetcore-Linux_x64.xml
501501
$(_BuildArgs)
@@ -568,7 +568,7 @@ stages:
568568
$(_InternalRuntimeDownloadArgs)
569569
displayName: Run build.sh
570570
- script: git clean -xfd src/**/obj/;
571-
./dockerbuild.sh rhel --ci --nobl --arch arm64 --build-installers --no-build-deps --no-build-nodejs
571+
./dockerbuild.sh rhel --ci --nobl --arch arm64 --build-installers --no-build-deps --no-build-nodejs --init-nuget
572572
-p:OnlyPackPlatformSpecificPackages=true -p:BuildRuntimeArchive=false -p:LinuxInstallerType=rpm
573573
-p:AssetManifestFileName=aspnetcore-Linux_arm64.xml
574574
$(_BuildArgs)

NuGet.config

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@
44
<clear />
55
<!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
66
<!-- Begin: Package sources from dotnet-efcore -->
7-
<add key="darc-int-dotnet-efcore-baac22d" value="https://pkgs.dev.azure.com/dnceng/internal/_packaging/darc-int-dotnet-efcore-baac22d8/nuget/v3/index.json" />
87
<!-- End: Package sources from dotnet-efcore -->
98
<!-- Begin: Package sources from dotnet-runtime -->
10-
<add key="darc-int-dotnet-runtime-d099f07" value="https://pkgs.dev.azure.com/dnceng/internal/_packaging/darc-int-dotnet-runtime-d099f075/nuget/v3/index.json" />
11-
<add key="darc-int-dotnet-runtime-d099f07-4" value="https://pkgs.dev.azure.com/dnceng/internal/_packaging/darc-int-dotnet-runtime-d099f075-4/nuget/v3/index.json" />
12-
<add key="darc-int-dotnet-runtime-d099f07-3" value="https://pkgs.dev.azure.com/dnceng/internal/_packaging/darc-int-dotnet-runtime-d099f075-3/nuget/v3/index.json" />
139
<!-- End: Package sources from dotnet-runtime -->
1410
<!--End: Package sources managed by Dependency Flow automation. Do not edit the sources above.-->
1511
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
@@ -28,12 +24,8 @@
2824
<clear />
2925
<!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
3026
<!-- Begin: Package sources from dotnet-efcore -->
31-
<add key="darc-int-dotnet-efcore-baac22d" value="true" />
3227
<!-- End: Package sources from dotnet-efcore -->
3328
<!-- Begin: Package sources from dotnet-runtime -->
34-
<add key="darc-int-dotnet-runtime-d099f07-3" value="true" />
35-
<add key="darc-int-dotnet-runtime-d099f07-4" value="true" />
36-
<add key="darc-int-dotnet-runtime-d099f07" value="true" />
3729
<!-- End: Package sources from dotnet-runtime -->
3830
<!--End: Package sources managed by Dependency Flow automation. Do not edit the sources above.-->
3931
</disabledPackageSources>

eng/Version.Details.xml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,22 +302,22 @@
302302
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-runtime</Uri>
303303
<Sha>d099f075e45d2aa6007a22b71b45a08758559f80</Sha>
304304
</Dependency>
305-
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="7.0.0-beta.22558.4">
305+
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="7.0.0-beta.22561.2">
306306
<Uri>https://github.com/dotnet/arcade</Uri>
307-
<Sha>3f3c360819c5c092d0e4505a67dfe59a33fba557</Sha>
307+
<Sha>f36ea231c234560514ede4c2747897a737ced28f</Sha>
308308
<SourceBuild RepoName="arcade" ManagedOnly="true" />
309309
</Dependency>
310-
<Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="7.0.0-beta.22558.4">
310+
<Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="7.0.0-beta.22561.2">
311311
<Uri>https://github.com/dotnet/arcade</Uri>
312-
<Sha>3f3c360819c5c092d0e4505a67dfe59a33fba557</Sha>
312+
<Sha>f36ea231c234560514ede4c2747897a737ced28f</Sha>
313313
</Dependency>
314-
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="7.0.0-beta.22558.4">
314+
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="7.0.0-beta.22561.2">
315315
<Uri>https://github.com/dotnet/arcade</Uri>
316-
<Sha>3f3c360819c5c092d0e4505a67dfe59a33fba557</Sha>
316+
<Sha>f36ea231c234560514ede4c2747897a737ced28f</Sha>
317317
</Dependency>
318-
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="7.0.0-beta.22558.4">
318+
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="7.0.0-beta.22561.2">
319319
<Uri>https://github.com/dotnet/arcade</Uri>
320-
<Sha>3f3c360819c5c092d0e4505a67dfe59a33fba557</Sha>
320+
<Sha>f36ea231c234560514ede4c2747897a737ced28f</Sha>
321321
</Dependency>
322322
</ToolsetDependencies>
323323
</Dependencies>

eng/Versions.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@
134134
<MicrosoftEntityFrameworkCoreVersion>7.0.1</MicrosoftEntityFrameworkCoreVersion>
135135
<MicrosoftEntityFrameworkCoreDesignVersion>7.0.1</MicrosoftEntityFrameworkCoreDesignVersion>
136136
<!-- Packages from dotnet/arcade -->
137-
<MicrosoftDotNetBuildTasksInstallersVersion>7.0.0-beta.22558.4</MicrosoftDotNetBuildTasksInstallersVersion>
138-
<MicrosoftDotNetBuildTasksTemplatingVersion>7.0.0-beta.22558.4</MicrosoftDotNetBuildTasksTemplatingVersion>
137+
<MicrosoftDotNetBuildTasksInstallersVersion>7.0.0-beta.22561.2</MicrosoftDotNetBuildTasksInstallersVersion>
138+
<MicrosoftDotNetBuildTasksTemplatingVersion>7.0.0-beta.22561.2</MicrosoftDotNetBuildTasksTemplatingVersion>
139139
<!-- Packages from dotnet/source-build-externals -->
140140
<MicrosoftSourceBuildIntermediatesourcebuildexternalsVersion>7.0.0-alpha.1.22505.1</MicrosoftSourceBuildIntermediatesourcebuildexternalsVersion>
141141
<!-- Packages from dotnet/xdt -->

eng/build.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ target_arch='x64'
3333
configuration=''
3434
runtime_source_feed=''
3535
runtime_source_feed_key=''
36+
init_nuget=false
3637

3738
if [ "$(uname)" = "Darwin" ]; then
3839
target_os_name='osx'
@@ -82,6 +83,8 @@ Options:
8283
--runtime-source-feed Additional feed that can be used when downloading .NET runtimes and SDKs
8384
--runtime-source-feed-key Key for feed that can be used when downloading .NET runtimes and SDKs
8485
86+
--init-nuget Run nuget --version.
87+
8588
Description:
8689
This build script installs required tools and runs an MSBuild command on this repository
8790
This script can be used to invoke various targets, such as targets to produce packages
@@ -208,6 +211,9 @@ while [[ $# -gt 0 ]]; do
208211
-ci)
209212
ci=true
210213
;;
214+
-init-nuget)
215+
init_nuget=true
216+
;;
211217
-binarylog|-bl)
212218
binary_log=true
213219
;;
@@ -359,6 +365,30 @@ export MSBUILDDEBUGPATH="$log_dir"
359365
_tmp_restore=$restore
360366
restore=true
361367

368+
if [[ "$init_nuget" == true ]]; then
369+
InitializeBuildTool
370+
371+
function RunBuildTool {
372+
"$_InitializeBuildTool" "$@" || {
373+
local exit_code=$?
374+
# We should not Write-PipelineTaskError here because that message shows up in the build summary
375+
# The build already logged an error, that's the reason it failed. Producing an error here only adds noise.
376+
echo "Build failed with exit code $exit_code. Check errors above."
377+
if [[ "$ci" == "true" ]]; then
378+
Write-PipelineSetResult -result "Failed" -message "nuget execution failed."
379+
# Exiting with an exit code causes the azure pipelines task to log yet another "noise" error
380+
# The above Write-PipelineSetResult will cause the task to be marked as failure without adding yet another error
381+
ExitWithExitCode 0
382+
else
383+
ExitWithExitCode $exit_code
384+
fi
385+
}
386+
}
387+
388+
echo 'Running dotnet nuget --version (issue: https://github.com/NuGet/Home/issues/12159#issuecomment-1278360511)'
389+
RunBuildTool "nuget" "--version"
390+
fi
391+
362392
InitializeToolset
363393

364394
restore=$_tmp_restore=

global.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
},
2828
"msbuild-sdks": {
2929
"Yarn.MSBuild": "1.22.10",
30-
"Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22558.4",
31-
"Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22558.4"
30+
"Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22561.2",
31+
"Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22561.2"
3232
}
3333
}

src/Servers/HttpSys/src/RequestProcessing/Request.cs

Lines changed: 86 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,39 +58,106 @@ internal Request(RequestContext requestContext)
5858

5959
PathBase = string.Empty;
6060
Path = originalPath;
61+
var prefix = requestContext.Server.Options.UrlPrefixes.GetPrefix((int)requestContext.UrlContext);
6162

6263
// 'OPTIONS * HTTP/1.1'
6364
if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawUrl, "*", StringComparison.Ordinal))
6465
{
6566
PathBase = string.Empty;
6667
Path = string.Empty;
6768
}
68-
else
69+
// Prefix may be null if the requested has been transfered to our queue
70+
else if (prefix is not null)
6971
{
70-
var prefix = requestContext.Server.Options.UrlPrefixes.GetPrefix((int)requestContext.UrlContext);
71-
// Prefix may be null if the requested has been transfered to our queue
72-
if (!(prefix is null))
72+
var pathBase = prefix.PathWithoutTrailingSlash;
73+
74+
// url: /base/path, prefix: /base/, base: /base, path: /path
75+
// url: /, prefix: /, base: , path: /
76+
if (originalPath.Equals(pathBase, StringComparison.Ordinal))
7377
{
74-
if (originalPath.Length == prefix.PathWithoutTrailingSlash.Length)
75-
{
76-
// They matched exactly except for the trailing slash.
77-
PathBase = originalPath;
78-
Path = string.Empty;
79-
}
80-
else
81-
{
82-
// url: /base/path, prefix: /base/, base: /base, path: /path
83-
// url: /, prefix: /, base: , path: /
84-
PathBase = originalPath.Substring(0, prefix.PathWithoutTrailingSlash.Length); // Preserve the user input casing
85-
Path = originalPath.Substring(prefix.PathWithoutTrailingSlash.Length);
86-
}
78+
// Exact match, no need to preserve the casing
79+
PathBase = pathBase;
80+
Path = string.Empty;
8781
}
88-
else if (requestContext.Server.Options.UrlPrefixes.TryMatchLongestPrefix(IsHttps, cookedUrl.GetHost()!, originalPath, out var pathBase, out var path))
82+
else if (originalPath.Equals(pathBase, StringComparison.OrdinalIgnoreCase))
8983
{
84+
// Preserve the user input casing
85+
PathBase = originalPath;
86+
Path = string.Empty;
87+
}
88+
else if (originalPath.StartsWith(prefix.Path, StringComparison.Ordinal))
89+
{
90+
// Exact match, no need to preserve the casing
9091
PathBase = pathBase;
91-
Path = path;
92+
Path = originalPath[pathBase.Length..];
93+
}
94+
else if (originalPath.StartsWith(prefix.Path, StringComparison.OrdinalIgnoreCase))
95+
{
96+
// Preserve the user input casing
97+
PathBase = originalPath[..pathBase.Length];
98+
Path = originalPath[pathBase.Length..];
99+
}
100+
else
101+
{
102+
// Http.Sys path base matching is based on the cooked url which applies some non-standard normalizations that we don't use
103+
// like collapsing duplicate slashes "//", converting '\' to '/', and un-escaping "%2F" to '/'. Find the right split and
104+
// ignore the normalizations.
105+
var originalOffset = 0;
106+
var baseOffset = 0;
107+
while (originalOffset < originalPath.Length && baseOffset < pathBase.Length)
108+
{
109+
var baseValue = pathBase[baseOffset];
110+
var offsetValue = originalPath[originalOffset];
111+
if (baseValue == offsetValue
112+
|| char.ToUpperInvariant(baseValue) == char.ToUpperInvariant(offsetValue))
113+
{
114+
// case-insensitive match, continue
115+
originalOffset++;
116+
baseOffset++;
117+
}
118+
else if (baseValue == '/' && offsetValue == '\\')
119+
{
120+
// Http.Sys considers these equivalent
121+
originalOffset++;
122+
baseOffset++;
123+
}
124+
else if (baseValue == '/' && originalPath.AsSpan(originalOffset).StartsWith("%2F", StringComparison.OrdinalIgnoreCase))
125+
{
126+
// Http.Sys un-escapes this
127+
originalOffset += 3;
128+
baseOffset++;
129+
}
130+
else if (baseOffset > 0 && pathBase[baseOffset - 1] == '/'
131+
&& (offsetValue == '/' || offsetValue == '\\'))
132+
{
133+
// Duplicate slash, skip
134+
originalOffset++;
135+
}
136+
else if (baseOffset > 0 && pathBase[baseOffset - 1] == '/'
137+
&& originalPath.AsSpan(originalOffset).StartsWith("%2F", StringComparison.OrdinalIgnoreCase))
138+
{
139+
// Duplicate slash equivalent, skip
140+
originalOffset += 3;
141+
}
142+
else
143+
{
144+
// Mismatch, fall back
145+
// The failing test case here is "/base/call//../bat//path1//path2", reduced to "/base/call/bat//path1//path2",
146+
// where http.sys collapses "//" before "../", but we do "../" first. We've lost the context that there were dot segments,
147+
// or duplicate slashes, how do we figure out that "call/" can be eliminated?
148+
originalOffset = 0;
149+
break;
150+
}
151+
}
152+
PathBase = originalPath[..originalOffset];
153+
Path = originalPath[originalOffset..];
92154
}
93155
}
156+
else if (requestContext.Server.Options.UrlPrefixes.TryMatchLongestPrefix(IsHttps, cookedUrl.GetHost()!, originalPath, out var pathBase, out var path))
157+
{
158+
PathBase = pathBase;
159+
Path = path;
160+
}
94161

95162
ProtocolVersion = RequestContext.GetVersion();
96163

src/Servers/HttpSys/test/FunctionalTests/Listener/RequestTests.cs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
@@ -138,6 +138,42 @@ public async Task Request_OverlongUTF8Path(string requestPath, string expectedPa
138138
}
139139
}
140140

141+
[ConditionalTheory]
142+
[InlineData("/", "/", "", "/")]
143+
[InlineData("/base", "/base", "/base", "")]
144+
[InlineData("/base", "/baSe", "/baSe", "")]
145+
[InlineData("/base", "/base/path", "/base", "/path")]
146+
[InlineData("/base", "///base/path1/path2", "///base", "/path1/path2")]
147+
[InlineData("/base/ball", @"/baSe\ball//path1//path2", @"/baSe\ball", "//path1//path2")]
148+
[InlineData("/base/ball", @"/base%2fball//path1//path2", @"/base%2fball", "//path1//path2")]
149+
[InlineData("/base/ball", @"/base%2Fball//path1//path2", @"/base%2Fball", "//path1//path2")]
150+
[InlineData("/base/ball", @"/base%5cball//path1//path2", @"/base\ball", "//path1//path2")]
151+
[InlineData("/base/ball", @"/base%5Cball//path1//path2", @"/base\ball", "//path1//path2")]
152+
[InlineData("/base/ball", "///baSe//ball//path1//path2", "///baSe//ball", "//path1//path2")]
153+
[InlineData("/base/ball", @"/base/\ball//path1//path2", @"/base/\ball", "//path1//path2")]
154+
[InlineData("/base/ball", @"/base/%2fball//path1//path2", @"/base/%2fball", "//path1//path2")]
155+
[InlineData("/base/ball", @"/base/%2Fball//path1//path2", @"/base/%2Fball", "//path1//path2")]
156+
[InlineData("/base/ball", @"/base/%5cball//path1//path2", @"/base/\ball", "//path1//path2")]
157+
[InlineData("/base/ball", @"/base/%5Cball//path1//path2", @"/base/\ball", "//path1//path2")]
158+
[InlineData("/base/ball", @"/base/call/../ball//path1//path2", @"/base/ball", "//path1//path2")]
159+
// The results should be "/base/ball", "//path1//path2", but Http.Sys collapses the "//" before the "../"
160+
// and we don't have a good way of emulating that.
161+
[InlineData("/base/ball", @"/base/call//../ball//path1//path2", @"", "/base/call/ball//path1//path2")]
162+
[InlineData("/base/ball", @"/base/call/.%2e/ball//path1//path2", @"/base/ball", "//path1//path2")]
163+
[InlineData("/base/ball", @"/base/call/.%2E/ball//path1//path2", @"/base/ball", "//path1//path2")]
164+
public async Task Request_WithPathBase(string pathBase, string requestPath, string expectedPathBase, string expectedPath)
165+
{
166+
using var server = Utilities.CreateHttpServerReturnRoot(pathBase, out var root);
167+
var responseTask = SendSocketRequestAsync(root, requestPath);
168+
var context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
169+
Assert.Equal(expectedPathBase, context.Request.PathBase);
170+
Assert.Equal(expectedPath, context.Request.Path);
171+
context.Dispose();
172+
173+
var response = await responseTask;
174+
Assert.Equal("200", response.Substring(9));
175+
}
176+
141177
private async Task<string> SendSocketRequestAsync(string address, string path, string method = "GET")
142178
{
143179
var uri = new Uri(address);

src/Servers/HttpSys/test/FunctionalTests/RequestTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ public async Task Request_FieldsCanBeSetToNull_Set()
208208
[InlineData("/base path/", "/base%20path/sub%20path", "/base path", "/sub path")]
209209
[InlineData("/base葉path/", "/base%E8%91%89path/sub%E8%91%89path", "/base葉path", "/sub葉path")]
210210
[InlineData("/basepath/", "/basepath/sub%2Fpath", "/basepath", "/sub%2Fpath")]
211+
[InlineData("/base", "///base/path1/path2", "///base", "/path1/path2")]
211212
public async Task Request_PathSplitting(string pathBase, string requestPath, string expectedPathBase, string expectedPath)
212213
{
213214
string root;

0 commit comments

Comments
 (0)