diff --git a/.azure/pipelines/ci.yml b/.azure/pipelines/ci.yml index 61497948bb..9b6bb325f4 100644 --- a/.azure/pipelines/ci.yml +++ b/.azure/pipelines/ci.yml @@ -639,7 +639,7 @@ stages: publishInstallersAndChecksums: true # This is to enable SDL runs part of Post-Build Validation Stage SDLValidationParameters: - enable: false + enable: true continueOnError: false params: ' -SourceToolsList @("policheck","credscan") -TsaInstanceURL $(_TsaInstanceURL) @@ -650,4 +650,5 @@ stages: -TsaIterationPath $(_TsaIterationPath) -TsaRepositoryName "AspNetCore" -TsaCodebaseName "AspNetCore" - -TsaPublish $True' + -TsaPublish $True + -PoliCheckAdditionalRunConfigParams @("UserExclusionPath < $(Build.SourcesDirectory)/eng/PoliCheckExclusions.xml")' diff --git a/.azure/pipelines/jobs/default-build.yml b/.azure/pipelines/jobs/default-build.yml index 18efdb3783..d218c44531 100644 --- a/.azure/pipelines/jobs/default-build.yml +++ b/.azure/pipelines/jobs/default-build.yml @@ -58,7 +58,7 @@ parameters: installTar: true installNodeJs: true installJdk: true - timeoutInMinutes: 270 + timeoutInMinutes: 180 # We need longer than the default amount of 5 minutes to upload our logs/artifacts. (We currently take around 5 mins in the best case). # This makes sure we have time to upload everything in the case of a build timeout - really important for investigating a build diff --git a/NuGet.config b/NuGet.config index 67715b7e4e..ff2c367882 100644 --- a/NuGet.config +++ b/NuGet.config @@ -3,12 +3,8 @@ - - + - - - diff --git a/eng/PoliCheckExclusions.xml b/eng/PoliCheckExclusions.xml new file mode 100644 index 0000000000..73e3072f1c --- /dev/null +++ b/eng/PoliCheckExclusions.xml @@ -0,0 +1,3 @@ + + LINUX_TEST_RESULTS|MACOS_TEST_RESULTS|WINDOWS_TEST_RESULTS + \ No newline at end of file diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 376aca962b..d58c63097f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -9,289 +9,285 @@ --> - + https://github.com/aspnet/Blazor - c8cc48b96c4ef3405dfc1678b089650aec2845ff + 964edff52e79094ca3f241d315bb4970671a1de3 - + https://github.com/aspnet/AspNetCore-Tooling - 574d72c659f2b742de703f8de633c85984c4e87d + 4d6f2ea3abb46351be590e25d52ef2a5ab8fdc56 - + https://github.com/aspnet/AspNetCore-Tooling - 574d72c659f2b742de703f8de633c85984c4e87d + 4d6f2ea3abb46351be590e25d52ef2a5ab8fdc56 - + https://github.com/aspnet/AspNetCore-Tooling - 574d72c659f2b742de703f8de633c85984c4e87d + 4d6f2ea3abb46351be590e25d52ef2a5ab8fdc56 - + https://github.com/aspnet/AspNetCore-Tooling - 574d72c659f2b742de703f8de633c85984c4e87d + 4d6f2ea3abb46351be590e25d52ef2a5ab8fdc56 - + https://github.com/aspnet/EntityFrameworkCore - 50fcada1bcebe891009c461dc6ce8fec9230060d + a852a65fe0e5a9b458ca4d7e4428e71deca70bf7 - + https://github.com/aspnet/EntityFrameworkCore - 50fcada1bcebe891009c461dc6ce8fec9230060d + a852a65fe0e5a9b458ca4d7e4428e71deca70bf7 - + https://github.com/aspnet/EntityFrameworkCore - 50fcada1bcebe891009c461dc6ce8fec9230060d + a852a65fe0e5a9b458ca4d7e4428e71deca70bf7 - + https://github.com/aspnet/EntityFrameworkCore - 50fcada1bcebe891009c461dc6ce8fec9230060d + a852a65fe0e5a9b458ca4d7e4428e71deca70bf7 - + https://github.com/aspnet/EntityFrameworkCore - 50fcada1bcebe891009c461dc6ce8fec9230060d + a852a65fe0e5a9b458ca4d7e4428e71deca70bf7 - + https://github.com/aspnet/EntityFrameworkCore - 50fcada1bcebe891009c461dc6ce8fec9230060d + a852a65fe0e5a9b458ca4d7e4428e71deca70bf7 - + https://github.com/aspnet/EntityFrameworkCore - 50fcada1bcebe891009c461dc6ce8fec9230060d + a852a65fe0e5a9b458ca4d7e4428e71deca70bf7 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab - - - https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 https://github.com/dotnet/corefx @@ -381,26 +377,31 @@ https://github.com/dotnet/corefx 0f7f38c4fd323b26da10cce95f857f77f0f09b48 - + https://github.com/dotnet/core-setup - 4e1bb23ca12cfe3de0b7e834872ed7327377d420 - - - https://github.com/dotnet/core-setup - 4e1bb23ca12cfe3de0b7e834872ed7327377d420 + f15b6f92ec4c09d6e53dac4a890a1ceebb9b8ef1 - + https://github.com/dotnet/core-setup - 4e1bb23ca12cfe3de0b7e834872ed7327377d420 + f15b6f92ec4c09d6e53dac4a890a1ceebb9b8ef1 https://github.com/dotnet/core-setup 7d57652f33493fa022125b7f63aad0d70c52d810 + + + https://github.com/dotnet/core-setup + 65f04fb6db7a5e198d05dbebd5c4ad21eb018f89 + + + https://github.com/aspnet/Extensions + 4e1be2fb546751c773968d7b40ff7f4b62887153 + @@ -408,9 +409,9 @@ https://github.com/dotnet/corefx 0f7f38c4fd323b26da10cce95f857f77f0f09b48 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 https://github.com/dotnet/arcade @@ -424,9 +425,9 @@ https://github.com/dotnet/arcade a42a124635ce1a218309ecb31ec59d559cacb886 - + https://github.com/aspnet/Extensions - 1bb89c52182b66b9f1b569cfe780947fa77c5dab + 04bb33fefa1e681da5dd88ce9c0f50963443c646 https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index 3d71135e56..047f31a3e2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -69,9 +69,9 @@ 3.4.0-beta4-19569-03 - 3.1.0 + 3.1.1-servicing.19575.1 3.1.0 - 3.1.0 + 3.1.1-servicing.19575.1 2.1.0 1.1.0 @@ -99,82 +99,82 @@ 3.1.0 - 3.1.0-preview4.19562.1 + 3.1.0-preview4.19575.4 - 3.1.0-rtm.19571.4 - 3.1.0-rtm.19571.4 - 3.1.0-rtm.19571.4 - 3.1.0-rtm.19571.4 - 3.1.0-rtm.19571.4 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0-rtm.19571.4 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0-rtm.19571.4 - 3.1.0 - 3.1.0 - 3.1.0-rtm.19571.4 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0-rtm.19571.4 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0-rtm.19571.4 - 3.1.0 - 3.1.0-rtm.19571.4 - 3.1.0-rtm.19571.4 - 3.1.0 - 3.1.0-rtm.19571.4 - 3.1.0 - 3.1.0-preview4.19571.4 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19575.5 + 3.1.0-rtm.19565.4 + 3.1.0-rtm.19575.5 + 3.1.0-preview4.19575.5 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 + 3.1.1-servicing.19576.5 + 3.1.1-servicing.19576.5 + 3.1.1-servicing.19576.5 + 3.1.1-servicing.19576.5 + 3.1.1-servicing.19576.5 + 3.1.1-servicing.19576.5 + 3.1.1-servicing.19576.5 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 + 3.1.1-servicing.19577.2 + 3.1.1-servicing.19577.2 + 3.1.1-servicing.19577.2 + 3.1.1-servicing.19577.2 $(BlazorClientPreReleaseVersionLabel) + + false diff --git a/src/Http/Http/src/Internal/ItemsDictionary.cs b/src/Http/Http/src/Internal/ItemsDictionary.cs index 5dd44f6887..3ca7ae95e1 100644 --- a/src/Http/Http/src/Internal/ItemsDictionary.cs +++ b/src/Http/Http/src/Internal/ItemsDictionary.cs @@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Http EmptyDictionary.Collection.CopyTo(array, arrayIndex); } - _items.CopyTo(array, arrayIndex); + _items?.CopyTo(array, arrayIndex); } int ICollection>.Count => _items?.Count ?? 0; @@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.Http IEnumerator> IEnumerable>.GetEnumerator() => _items?.GetEnumerator() ?? EmptyEnumerator.Instance; - IEnumerator IEnumerable.GetEnumerator() => _items.GetEnumerator() ?? EmptyEnumerator.Instance; + IEnumerator IEnumerable.GetEnumerator() => _items?.GetEnumerator() ?? EmptyEnumerator.Instance; private class EmptyEnumerator : IEnumerator> { diff --git a/src/Http/Http/test/Internal/ItemsDictionaryTests.cs b/src/Http/Http/test/Internal/ItemsDictionaryTests.cs new file mode 100644 index 0000000000..d8319c1c43 --- /dev/null +++ b/src/Http/Http/test/Internal/ItemsDictionaryTests.cs @@ -0,0 +1,41 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.IO.Pipelines; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Primitives; +using Xunit; + +namespace Microsoft.AspNetCore.Http +{ + public class ItemsDictionaryTests + { + [Fact] + public void GetEnumerator_ShouldResolveWithoutNullReferenceException() + { + // Arrange + var dict = new ItemsDictionary(); + + // Act and Assert + IEnumerable en = (IEnumerable) dict; + Assert.NotNull(en.GetEnumerator()); + } + + [Fact] + public void CopyTo_ShouldCopyItemsWithoutNullReferenceException() { + // Arrange + var dict = new ItemsDictionary(); + var pairs = new KeyValuePair[] { new KeyValuePair("first", "value") }; + + // Act and Assert + ICollection> cl = (ICollection>) dict; + cl.CopyTo(pairs, 0); + } + } +} diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxr.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxr.cpp index 545791610b..a9d942aabf 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxr.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxr.cpp @@ -47,6 +47,7 @@ void HostFxr::Load(HMODULE moduleHandle) m_corehost_set_error_writer_fn = ModuleHelpers::GetKnownProcAddress(moduleHandle, "hostfxr_set_error_writer", /* optional */ true); m_hostfxr_initialize_for_dotnet_commandline_fn = ModuleHelpers::GetKnownProcAddress(moduleHandle, "hostfxr_initialize_for_dotnet_command_line", /* optional */ true); m_hostfxr_set_runtime_property_value_fn = ModuleHelpers::GetKnownProcAddress(moduleHandle, "hostfxr_set_runtime_property_value", /* optional */ true); + m_hostfxr_get_runtime_property_value_fn = ModuleHelpers::GetKnownProcAddress(moduleHandle, "hostfxr_get_runtime_property_value", /* optional */ true); m_hostfxr_run_app_fn = ModuleHelpers::GetKnownProcAddress(moduleHandle, "hostfxr_run_app", /* optional */ true); m_hostfxr_close_fn = ModuleHelpers::GetKnownProcAddress(moduleHandle, "hostfxr_close", /* optional */ true); } @@ -164,6 +165,15 @@ int HostFxr::SetRuntimePropertyValue(PCWSTR name, PCWSTR value) const noexcept return 0; } +int HostFxr::GetRuntimePropertyValue(PCWSTR name, PWSTR* value) const noexcept +{ + if (m_host_context_handle != nullptr && m_hostfxr_get_runtime_property_value_fn != nullptr) + { + return m_hostfxr_get_runtime_property_value_fn(m_host_context_handle, name, value); + } + return 0; +} + void HostFxr::Close() const noexcept { if (m_host_context_handle != nullptr && m_hostfxr_close_fn != nullptr) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxr.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxr.h index ced4dd1940..a6cf2bb889 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxr.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxr.h @@ -25,6 +25,7 @@ typedef void(*corehost_error_writer_fn) (const WCHAR* message); typedef corehost_error_writer_fn(*corehost_set_error_writer_fn) (corehost_error_writer_fn error_writer); typedef int(*hostfxr_initialize_for_dotnet_runtime_fn)(int argc, const PCWSTR* argv, hostfxr_initialize_parameters* parameters, void* const* host_context_handle); typedef int(*hostfxr_set_runtime_property_value_fn)(void* host_context_handle, PCWSTR name, PCWSTR value); +typedef int(*hostfxr_get_runtime_property_value_fn)(void* host_context_handle, PCWSTR name, PWSTR* value); typedef int(*hostfxr_run_app_fn)(void* host_context_handle); typedef int(*hostfxr_close_fn)(void* hostfxr_context_handle); @@ -73,6 +74,7 @@ public: HostFxrErrorRedirector RedirectOutput(RedirectionOutput* writer) const noexcept; int SetRuntimePropertyValue(PCWSTR name, PCWSTR value) const noexcept; + int GetRuntimePropertyValue(PCWSTR name, PWSTR* value) const noexcept; int InitializeForApp(int argc, PCWSTR* argv, const std::wstring& m_dotnetExeKnownLocation) const noexcept; void Close() const noexcept; @@ -82,6 +84,7 @@ private: hostfxr_get_native_search_directories_fn m_hostfxr_get_native_search_directories_fn; hostfxr_initialize_for_dotnet_runtime_fn m_hostfxr_initialize_for_dotnet_commandline_fn; hostfxr_set_runtime_property_value_fn m_hostfxr_set_runtime_property_value_fn; + hostfxr_get_runtime_property_value_fn m_hostfxr_get_runtime_property_value_fn; hostfxr_run_app_fn m_hostfxr_run_app_fn; corehost_set_error_writer_fn m_corehost_set_error_writer_fn; hostfxr_close_fn m_hostfxr_close_fn; diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/config_utility.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/config_utility.h index ae4aeb0466..05fd514bea 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/config_utility.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/config_utility.h @@ -14,6 +14,7 @@ class ConfigUtility #define CS_ASPNETCORE_HANDLER_SETTINGS L"handlerSettings" #define CS_ASPNETCORE_HANDLER_VERSION L"handlerVersion" #define CS_ASPNETCORE_DEBUG_FILE L"debugFile" + #define CS_ASPNETCORE_ENABLE_OUT_OF_PROCESS_CONSOLE_REDIRECTION L"enableOutOfProcessConsoleRedirection" #define CS_ASPNETCORE_DEBUG_LEVEL L"debugLevel" #define CS_ASPNETCORE_HANDLER_SETTINGS_NAME L"name" #define CS_ASPNETCORE_HANDLER_SETTINGS_VALUE L"value" @@ -40,6 +41,13 @@ public: return FindKeyValuePair(pElement, CS_ASPNETCORE_DEBUG_LEVEL, strDebugFile); } + static + HRESULT + FindEnableOutOfProcessConsoleRedirection(IAppHostElement* pElement, STRU& strEnableOutOfProcessConsoleRedirection) + { + return FindKeyValuePair(pElement, CS_ASPNETCORE_ENABLE_OUT_OF_PROCESS_CONSOLE_REDIRECTION, strEnableOutOfProcessConsoleRedirection); + } + private: static HRESULT diff --git a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp index b671e7dba2..be2e9055b7 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp @@ -252,7 +252,20 @@ IN_PROCESS_APPLICATION::ExecuteApplication() if (m_pConfig->QueryCallStartupHook()) { - RETURN_IF_NOT_ZERO(context->m_hostFxr.SetRuntimePropertyValue(DOTNETCORE_STARTUP_HOOK, ASPNETCORE_STARTUP_ASSEMBLY)); + PWSTR startupHookValue = NULL; + // Will get property not found if the enviroment variable isn't set. + context->m_hostFxr.GetRuntimePropertyValue(DOTNETCORE_STARTUP_HOOK, &startupHookValue); + + if (startupHookValue == NULL) + { + RETURN_IF_NOT_ZERO(context->m_hostFxr.SetRuntimePropertyValue(DOTNETCORE_STARTUP_HOOK, ASPNETCORE_STARTUP_ASSEMBLY)); + } + else + { + std::wstring startupHook(startupHookValue); + startupHook.append(L";").append(ASPNETCORE_STARTUP_ASSEMBLY); + RETURN_IF_NOT_ZERO(context->m_hostFxr.SetRuntimePropertyValue(DOTNETCORE_STARTUP_HOOK, startupHook.c_str())); + } } RETURN_IF_NOT_ZERO(context->m_hostFxr.SetRuntimePropertyValue(DOTNETCORE_USE_ENTRYPOINT_FILTER, L"1")); diff --git a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp index 80e70a187c..4837a94c72 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp @@ -158,6 +158,7 @@ PROCESS_MANAGER::GetProcess( pConfig->QueryAnonymousAuthEnabled(), pConfig->QueryEnvironmentVariables(), pConfig->QueryStdoutLogEnabled(), + pConfig->QueryEnableOutOfProcessConsoleRedirection(), fWebsocketSupported, pConfig->QueryStdoutLogFile(), pConfig->QueryApplicationPhysicalPath(), // physical path diff --git a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp index 5216e072d4..94e3279f75 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp @@ -25,6 +25,7 @@ SERVER_PROCESS::Initialize( BOOL fAnonymousAuthEnabled, std::map& pEnvironmentVariables, BOOL fStdoutLogEnabled, + BOOL fEnableOutOfProcessConsoleRedirection, BOOL fWebSocketSupported, STRU *pstruStdoutLogFile, STRU *pszAppPhysicalPath, @@ -43,6 +44,7 @@ SERVER_PROCESS::Initialize( m_fWindowsAuthEnabled = fWindowsAuthEnabled; m_fBasicAuthEnabled = fBasicAuthEnabled; m_fAnonymousAuthEnabled = fAnonymousAuthEnabled; + m_fEnableOutOfProcessConsoleRedirection = fEnableOutOfProcessConsoleRedirection; m_pProcessManager->ReferenceProcessManager(); m_fDebuggerAttached = FALSE; @@ -1030,6 +1032,15 @@ SERVER_PROCESS::SetupStdHandles( saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; + if (!m_fEnableOutOfProcessConsoleRedirection) + { + pStartupInfo->dwFlags = STARTF_USESTDHANDLES; + pStartupInfo->hStdInput = INVALID_HANDLE_VALUE; + pStartupInfo->hStdError = INVALID_HANDLE_VALUE; + pStartupInfo->hStdOutput = INVALID_HANDLE_VALUE; + return hr; + } + if (!m_fStdoutLogEnabled) { CreatePipe(&m_hStdoutHandle, &m_hStdErrWritePipe, &saAttr, 0 /*nSize*/); @@ -1770,6 +1781,8 @@ SERVER_PROCESS::SERVER_PROCESS() : m_dwListeningProcessId(0), m_hListeningProcessHandle(NULL), m_hShutdownHandle(NULL), + m_hStdErrWritePipe(NULL), + m_hReadThread(nullptr), m_randomGenerator(std::random_device()()) { //InterlockedIncrement(&g_dwActiveServerProcesses); @@ -1866,13 +1879,15 @@ SERVER_PROCESS::~SERVER_PROCESS() m_pProcessManager = NULL; } - if (m_hStdoutHandle != NULL) + if (m_hStdErrWritePipe != NULL) { - if (m_hStdoutHandle != INVALID_HANDLE_VALUE) + if (m_hStdErrWritePipe != INVALID_HANDLE_VALUE) { - CloseHandle(m_hStdoutHandle); + FlushFileBuffers(m_hStdErrWritePipe); + CloseHandle(m_hStdErrWritePipe); } - m_hStdoutHandle = NULL; + + m_hStdErrWritePipe = NULL; } // Forces ReadFile to cancel, causing the read loop to complete. @@ -1907,6 +1922,15 @@ SERVER_PROCESS::~SERVER_PROCESS() m_hReadThread = nullptr; } + if (m_hStdoutHandle != NULL) + { + if (m_hStdoutHandle != INVALID_HANDLE_VALUE) + { + CloseHandle(m_hStdoutHandle); + } + m_hStdoutHandle = NULL; + } + if (m_fStdoutLogEnabled) { m_Timer.CancelTimer(); diff --git a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h index 0d90dd47de..bfe3225dbd 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h @@ -37,6 +37,7 @@ public: _In_ BOOL fAnonymousAuthEnabled, _In_ std::map& pEnvironmentVariables, _In_ BOOL fStdoutLogEnabled, + _In_ BOOL fDisableRedirection, _In_ BOOL fWebSocketSupported, _In_ STRU *pstruStdoutLogFile, _In_ STRU *pszAppPhysicalPath, @@ -253,6 +254,7 @@ private: BOOL m_fBasicAuthEnabled; BOOL m_fAnonymousAuthEnabled; BOOL m_fDebuggerAttached; + BOOL m_fEnableOutOfProcessConsoleRedirection; STTIMER m_Timer; SOCKET m_socket; diff --git a/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp b/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp index f4507164df..d3a705e9a2 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp @@ -379,6 +379,12 @@ REQUESTHANDLER_CONFIG::Populate( goto Finished; } + hr = ConfigUtility::FindEnableOutOfProcessConsoleRedirection(pAspNetCoreElement, m_fEnableOutOfProcessConsoleRedirection); + if (FAILED(hr)) + { + goto Finished; + } + Finished: if (pAspNetCoreElement != NULL) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h b/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h index 90a2b5a365..5f06c12695 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h @@ -218,6 +218,12 @@ public: return &m_struConfigPath; } + BOOL + QueryEnableOutOfProcessConsoleRedirection() + { + return !m_fEnableOutOfProcessConsoleRedirection.Equals(L"false", 1); + } + protected: // @@ -255,6 +261,7 @@ protected: BOOL m_fWindowsAuthEnabled; BOOL m_fBasicAuthEnabled; BOOL m_fAnonymousAuthEnabled; + STRU m_fEnableOutOfProcessConsoleRedirection; APP_HOSTING_MODEL m_hostingModel; std::map m_pEnvironmentVariables; STRU m_struHostFxrLocation; diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs index 3acf1a86e0..1c070242e0 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs @@ -817,6 +817,42 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess VerifyDotnetRuntimeEventLog(deploymentResult); } + + [ConditionalFact] + [RequiresNewHandler] + public async Task CanAddCustomStartupHook() + { + var deploymentParameters = Fixture.GetBaseDeploymentParameters(); + + // Deployment parameters by default set ASPNETCORE_DETAILEDERRORS to true + deploymentParameters.WebConfigBasedEnvironmentVariables["DOTNET_STARTUP_HOOKS"] = "InProcessWebSite"; + + var deploymentResult = await DeployAsync(deploymentParameters); + var result = await deploymentResult.HttpClient.GetAsync("/StartupHook"); + var content = await result.Content.ReadAsStringAsync(); + Assert.Equal("True", content); + + StopServer(); + } + + [ConditionalFact] + [RequiresNewHandler] + public async Task CanAddCustomStartupHookWhenIISOneIsDisabled() + { + var deploymentParameters = Fixture.GetBaseDeploymentParameters(); + + // Deployment parameters by default set ASPNETCORE_DETAILEDERRORS to true + deploymentParameters.WebConfigBasedEnvironmentVariables["DOTNET_STARTUP_HOOKS"] = "InProcessWebSite"; + deploymentParameters.HandlerSettings["callStartupHook"] = "false"; + + var deploymentResult = await DeployAsync(deploymentParameters); + var result = await deploymentResult.HttpClient.GetAsync("/StartupHook"); + var content = await result.Content.ReadAsStringAsync(); + Assert.Equal("True", content); + + StopServer(); + } + [ConditionalFact] [RequiresNewHandler] public async Task StackOverflowIsAvoidedBySettingLargerStack() diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs index 699bd8b3ac..70f6a6b8b4 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs @@ -233,6 +233,22 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.OutOfProcessFailedToStart(deploymentResult, "Wow!"), Logger); } + [ConditionalFact] + [RequiresNewShim] + public async Task DisableRedirectionNoLogs() + { + var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess); + deploymentParameters.HandlerSettings["enableOutOfProcessConsoleRedirection"] = "false"; + deploymentParameters.TransformArguments((a, _) => $"{a} ConsoleWriteSingle"); + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("Test"); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.OutOfProcessFailedToStart(deploymentResult, ""), Logger); + } + [ConditionalFact] public async Task CaptureLogsForOutOfProcessWhenProcessFailsToStart30KbMax() { diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs index ddc981d7af..8557b89f94 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs @@ -84,6 +84,55 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.OutOfProcess Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode); } + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + [RequiresNewShim] + public async Task ShutdownMultipleTimesWorks(TestVariant variant) + { + // Must publish to set env vars in web.config + var deploymentParameters = Fixture.GetBaseDeploymentParameters(variant); + + var deploymentResult = await DeployAsync(deploymentParameters); + + // Shutdown once + var response = await deploymentResult.HttpClient.GetAsync("/Shutdown"); + + // Wait for server to start again. + int i; + for (i = 0; i < 10; i++) + { + // ANCM should eventually recover from being shutdown multiple times. + response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + if (response.IsSuccessStatusCode) + { + break; + } + } + + if (i == 10) + { + // Didn't restart after 10 retries + Assert.False(true); + } + + // Shutdown again + response = await deploymentResult.HttpClient.GetAsync("/Shutdown"); + + // return if server starts again. + for (i = 0; i < 10; i++) + { + // ANCM should eventually recover from being shutdown multiple times. + response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + if (response.IsSuccessStatusCode) + { + return; + } + } + + // Test failure if this happens. + Assert.False(true); + } + private static int GetUnusedRandomPort() { // Large number of retries to prevent test failures due to port collisions, but not infinite diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs index f25dca8633..7336dda665 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs @@ -32,6 +32,8 @@ namespace TestSite { public partial class Startup { + public static bool StartupHookCalled; + public void Configure(IApplicationBuilder app) { if (Environment.GetEnvironmentVariable("ENABLE_HTTPS_REDIRECTION") != null) @@ -900,6 +902,11 @@ namespace TestSite RecursiveFunction(i - 1); } + private async Task StartupHook(HttpContext ctx) + { + await ctx.Response.WriteAsync(StartupHookCalled.ToString()); + } + private async Task GetServerVariableStress(HttpContext ctx) { // This test simulates the scenario where native Flush call is being diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/StartupHook.cs b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/StartupHook.cs new file mode 100644 index 0000000000..5ea24a3175 --- /dev/null +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/StartupHook.cs @@ -0,0 +1,9 @@ +using TestSite; + +internal class StartupHook +{ + public static void Initialize() + { + Startup.StartupHookCalled = true; + } +}