diff --git a/.azure/pipelines/ci.yml b/.azure/pipelines/ci.yml index 23668b1d6ac7..cb0b5ed8a62a 100644 --- a/.azure/pipelines/ci.yml +++ b/.azure/pipelines/ci.yml @@ -93,17 +93,17 @@ variables: - name: _InternalRuntimeDownloadCodeSignArgs value: '' - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - group: DotNet-MSRC-Storage + - group: DotNetBuilds storage account read tokens - name: _InternalRuntimeDownloadArgs - value: -RuntimeSourceFeed https://dotnetclimsrc.blob.core.windows.net/dotnet - -RuntimeSourceFeedKey $(dotnetclimsrc-read-sas-token-base64) - /p:DotNetAssetRootAccessTokenSuffix='$(dotnetclimsrc-read-sas-token-base64)' + value: -RuntimeSourceFeed https://dotnetbuilds.blob.core.windows.net/internal + -RuntimeSourceFeedKey $(dotnetbuilds-internal-container-read-token-base64) + /p:DotNetAssetRootAccessTokenSuffix='$(dotnetbuilds-internal-container-read-token-base64)' # The code signing doesn't use the aspnet build scripts, so the msbuild parameters have to be passed directly. This # is awkward but necessary because the eng/common/ build scripts don't add the msbuild properties automatically. - name: _InternalRuntimeDownloadCodeSignArgs value: $(_InternalRuntimeDownloadArgs) - /p:DotNetRuntimeSourceFeed=https://dotnetclimsrc.blob.core.windows.net/dotnet - /p:DotNetRuntimeSourceFeedKey=$(dotnetclimsrc-read-sas-token-base64) + /p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal + /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) - group: DotNet-HelixApi-Access - name: _UseHelixOpenQueues value: 'false' @@ -528,7 +528,7 @@ stages: jobName: Linux_musl_x64_build jobDisplayName: "Build: Linux Musl x64" agentOs: Linux - container: mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.9-WithNode-0fc54a3-20190918214015 + container: mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-WithNode-20210910135833-c401c85 buildArgs: --arch x64 --os-name linux-musl @@ -736,7 +736,7 @@ stages: platform: name: 'Managed' container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-20210714125435-9b5bbc2' - buildScript: './eng/build.sh $(_PublishArgs) --no-build-repo-tasks' + buildScript: './eng/build.sh $(_PublishArgs) --no-build-repo-tasks $(_InternalRuntimeDownloadArgs)' skipPublishValidation: true # Publish to the BAR diff --git a/.azure/pipelines/jobs/default-build.yml b/.azure/pipelines/jobs/default-build.yml index 71156daac720..46899dd8c334 100644 --- a/.azure/pipelines/jobs/default-build.yml +++ b/.azure/pipelines/jobs/default-build.yml @@ -220,6 +220,7 @@ jobs: # Include the variables we always want. COMPlus_DbgEnableMiniDump: 1 COMPlus_DbgMiniDumpName: "$(System.DefaultWorkingDirectory)/dotnet-%d.%t.core" + DotNetBuildsInternalReadSasToken: $(dotnetbuilds-internal-container-read-token) # Expand provided `env:` properties, if any. ${{ if step.env }}: ${{ step.env }} @@ -230,12 +231,14 @@ jobs: env: COMPlus_DbgEnableMiniDump: 1 COMPlus_DbgMiniDumpName: "$(System.DefaultWorkingDirectory)/dotnet-%d.%t.core" + DotNetBuildsInternalReadSasToken: $(dotnetbuilds-internal-container-read-token) - ${{ if ne(parameters.agentOs, 'Windows') }}: - script: $(BuildDirectory)/build.sh --ci --nobl --configuration $(BuildConfiguration) $(BuildScriptArgs) displayName: Run build.sh env: COMPlus_DbgEnableMiniDump: 1 COMPlus_DbgMiniDumpName: "$(System.DefaultWorkingDirectory)/dotnet-%d.%t.core" + DotNetBuildsInternalReadSasToken: $(dotnetbuilds-internal-container-read-token) - ${{ parameters.afterBuild }} diff --git a/NuGet.config b/NuGet.config index 4b821f800992..050fda0b4dcd 100644 --- a/NuGet.config +++ b/NuGet.config @@ -4,8 +4,10 @@ + + @@ -25,8 +27,10 @@ + + diff --git a/eng/Baseline.Designer.props b/eng/Baseline.Designer.props index 7da0830be28e..f8c3f2116444 100644 --- a/eng/Baseline.Designer.props +++ b/eng/Baseline.Designer.props @@ -2,28 +2,28 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - - - + + + @@ -34,120 +34,120 @@ - 6.0.0 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 @@ -155,114 +155,114 @@ - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - + - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - + - 6.0.1 + 6.0.2 - - - + + + - + - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - - + + @@ -270,7 +270,7 @@ - 6.0.1 + 6.0.2 @@ -278,50 +278,50 @@ - 6.0.1 + 6.0.2 - + - + - - + + - + - + - - + + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - - + + @@ -331,8 +331,8 @@ - - + + @@ -340,8 +340,8 @@ - - + + @@ -352,58 +352,58 @@ - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - + - 6.0.1 + 6.0.2 @@ -411,71 +411,71 @@ - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - + - + - + - + - 6.0.1 + 6.0.2 - - + + - + - - + + - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 @@ -491,195 +491,195 @@ - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - + - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - - + + - 6.0.1 + 6.0.2 - + - + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - + - 6.0.1 + 6.0.2 - - + + - - + + - - + + - 6.0.1 + 6.0.2 - - + + - - + + - - + + - - + + - 6.0.1 + 6.0.2 - + - + - + - + - + - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - - - - + + + + - 6.0.1 + 6.0.2 @@ -688,69 +688,69 @@ - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - + - 6.0.1 + 6.0.2 - + - 6.0.1 + 6.0.2 - + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 @@ -769,7 +769,7 @@ - 6.0.1 + 6.0.2 @@ -788,7 +788,7 @@ - 6.0.1 + 6.0.2 @@ -804,46 +804,46 @@ - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - - - + + + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 @@ -853,7 +853,7 @@ - 6.0.1 + 6.0.2 @@ -862,76 +862,76 @@ - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - + - + - + - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - + @@ -940,7 +940,7 @@ - + @@ -948,7 +948,7 @@ - + @@ -957,11 +957,11 @@ - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 @@ -979,13 +979,13 @@ - 6.0.1 + 6.0.2 - 6.0.1 + 6.0.2 - + \ No newline at end of file diff --git a/eng/Baseline.xml b/eng/Baseline.xml index 6a0991dc7477..24d6ccfa45b2 100644 --- a/eng/Baseline.xml +++ b/eng/Baseline.xml @@ -4,111 +4,111 @@ This file contains a list of all the packages and their versions which were rele Update this list when preparing for a new patch. --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d65c67657d8a..47c199246913 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -9,45 +9,45 @@ --> - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 41e6aaaf6216de904530de11b0bfd4af43fb13f7 + d93f389536054e13de2f820fe89197aa374c01eb - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 41e6aaaf6216de904530de11b0bfd4af43fb13f7 + d93f389536054e13de2f820fe89197aa374c01eb - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 41e6aaaf6216de904530de11b0bfd4af43fb13f7 + d93f389536054e13de2f820fe89197aa374c01eb - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 41e6aaaf6216de904530de11b0bfd4af43fb13f7 + d93f389536054e13de2f820fe89197aa374c01eb - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 41e6aaaf6216de904530de11b0bfd4af43fb13f7 + d93f389536054e13de2f820fe89197aa374c01eb - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 41e6aaaf6216de904530de11b0bfd4af43fb13f7 + d93f389536054e13de2f820fe89197aa374c01eb - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 41e6aaaf6216de904530de11b0bfd4af43fb13f7 + d93f389536054e13de2f820fe89197aa374c01eb - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 41e6aaaf6216de904530de11b0bfd4af43fb13f7 + d93f389536054e13de2f820fe89197aa374c01eb https://github.com/dotnet/runtime 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 - - https://github.com/dotnet/runtime - 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 https://github.com/dotnet/runtime @@ -61,9 +61,9 @@ https://github.com/dotnet/runtime 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 - - https://github.com/dotnet/runtime - 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 https://github.com/dotnet/runtime @@ -77,9 +77,9 @@ https://github.com/dotnet/runtime 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 - - https://github.com/dotnet/runtime - 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 https://github.com/dotnet/runtime @@ -121,9 +121,9 @@ https://github.com/dotnet/runtime 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 - - https://github.com/dotnet/runtime - 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 https://github.com/dotnet/runtime @@ -177,9 +177,9 @@ https://github.com/dotnet/runtime 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 3a25a7f1cc446b60678ed25c9d829420d6321eba + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 https://github.com/dotnet/runtime @@ -189,13 +189,13 @@ https://github.com/dotnet/runtime 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 - - https://github.com/dotnet/runtime - 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 3a25a7f1cc446b60678ed25c9d829420d6321eba + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 https://github.com/dotnet/runtime @@ -233,9 +233,9 @@ https://github.com/dotnet/runtime 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 3a25a7f1cc446b60678ed25c9d829420d6321eba + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 https://github.com/dotnet/runtime @@ -245,33 +245,33 @@ https://github.com/dotnet/runtime 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 3a25a7f1cc446b60678ed25c9d829420d6321eba + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 3a25a7f1cc446b60678ed25c9d829420d6321eba + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 3a25a7f1cc446b60678ed25c9d829420d6321eba + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 3a25a7f1cc446b60678ed25c9d829420d6321eba + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 3a25a7f1cc446b60678ed25c9d829420d6321eba + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 3a25a7f1cc446b60678ed25c9d829420d6321eba + 839cdfb0ecca5e0be3dbccd926e7651ef50fdf10 diff --git a/eng/Versions.props b/eng/Versions.props index 77919564fec2..db7431f077fa 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -9,7 +9,7 @@ 6 0 3 - false + true @@ -63,23 +63,23 @@ 6.0.0 - 6.0.1 - 6.0.1 - 6.0.1 - 6.0.1 - 6.0.1 - 6.0.1-servicing.21567.5 + 6.0.2 + 6.0.2 + 6.0.2 + 6.0.2 + 6.0.2 + 6.0.2-servicing.22064.6 6.0.0 - 6.0.0 + 6.0.1 6.0.0 6.0.0 6.0.0 - 6.0.0 + 6.0.1 6.0.0 6.0.0 6.0.0 6.0.0 - 6.0.0 + 6.0.1 6.0.0 6.0.0 6.0.0 @@ -89,7 +89,7 @@ 6.0.0 6.0.1-servicing.21567.5 6.0.0 - 6.0.0 + 6.0.1 6.0.0 6.0.0 6.0.0 @@ -103,11 +103,11 @@ 6.0.0 6.0.0 6.0.0 - 6.0.1-servicing.21567.5 + 6.0.2-servicing.22064.6 6.0.0 6.0.0 - 6.0.0 - 6.0.1 + 6.0.1 + 6.0.2 6.0.0 6.0.0 6.0.0 @@ -117,19 +117,19 @@ 6.0.0 6.0.0 6.0.0 - 6.0.1 + 6.0.2 6.0.0 6.0.1 - 6.0.1 - 6.0.1 - 6.0.1 - 6.0.1 - 6.0.1 - 6.0.1 - 6.0.1 - 6.0.1 + 6.0.2 + 6.0.2 + 6.0.2 + 6.0.2 + 6.0.2 + 6.0.2 + 6.0.2 + 6.0.2 6.0.0-beta.22107.2 6.0.0-beta.22107.2 @@ -215,7 +215,7 @@ 3.1.22-servicing-21579-4 $(MicrosoftAspNetCoreAzureAppServicesSiteExtension31Version) $(MicrosoftAspNetCoreAzureAppServicesSiteExtension31Version) - 5.0.13-servicing-21572-2 + 5.0.14-servicing.22063.24 $(MicrosoftAspNetCoreAzureAppServicesSiteExtension50Version) $(MicrosoftAspNetCoreAzureAppServicesSiteExtension50Version) @@ -270,6 +270,6 @@ https://dotnetcli.azureedge.net/dotnet/ - https://dotnetclimsrc.blob.core.windows.net/dotnet/ + https://dotnetbuilds.azureedge.net/internal/ diff --git a/eng/helix/helix.proj b/eng/helix/helix.proj index 392c90bd1e07..3f354ab1872d 100644 --- a/eng/helix/helix.proj +++ b/eng/helix/helix.proj @@ -1,5 +1,18 @@ + + + false + + $(RepoRoot)artifacts\bin\$(MSBuildProjectName)\ @@ -37,8 +53,15 @@ - + + + runtime diff --git a/eng/targets/Helix.Common.props b/eng/targets/Helix.Common.props index c82fe494c85f..f17314b89e81 100644 --- a/eng/targets/Helix.Common.props +++ b/eng/targets/Helix.Common.props @@ -62,4 +62,11 @@ + + + false + true + false + true + diff --git a/eng/targets/Helix.props b/eng/targets/Helix.props index bc0dfe046eae..dc2bad9552b9 100644 --- a/eng/targets/Helix.props +++ b/eng/targets/Helix.props @@ -14,10 +14,6 @@ 00:30:00 00:40:00 false - false - true - false - true $(MSBuildProjectName)--$(TargetFramework) false 14.17.6 diff --git a/global.json b/global.json index fa2553f085a4..3ed497ccfba5 100644 --- a/global.json +++ b/global.json @@ -1,9 +1,9 @@ { "sdk": { - "version": "6.0.101" + "version": "6.0.102" }, "tools": { - "dotnet": "6.0.101", + "dotnet": "6.0.102", "runtimes": { "dotnet/x64": [ "2.1.30", diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index a9e10b912dc1..2f54decb91b6 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -977,6 +977,8 @@ private Task DecodeHeadersAsync(bool endHeaders, in ReadOnlySequence paylo if (endHeaders) { + _currentHeadersStream.OnHeadersComplete(); + StartStream(); ResetRequestHeaderParsingState(); } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Connection.cs index 3452bd52d7a0..3d601eff2a2a 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Connection.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 { internal class Http3Connection : IHttp3StreamLifetimeHandler, IRequestProcessor { - private static readonly object StreamPersistentStateKey = new object(); + internal static readonly object StreamPersistentStateKey = new object(); // Internal for unit testing internal readonly Dictionary _streams = new Dictionary(); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs index ea69197bc27e..c1086dc02a85 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -662,6 +662,8 @@ private static Task ProcessUnknownFrameAsync() InputRemaining = HttpRequestHeaders.ContentLength; + OnHeadersComplete(); + // If the stream is complete after receiving the headers then run OnEndStreamReceived. // If there is a bad content length then this will throw before the request delegate is called. if (isCompleted) diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs index 3016d57237f5..6a9656d9f730 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Net.Http; using System.Net.Http.HPack; +using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -211,6 +212,73 @@ public async Task RequestHeaderStringReuse_MultipleStreams_KnownHeaderReused() await StopConnectionAsync(expectedLastStreamId: 3, ignoreNonGoAwayFrames: false); } + [Fact] + public async Task RequestHeaderStringReuse_MultipleStreams_KnownHeaderClearedIfNotReused() + { + const BindingFlags privateFlags = BindingFlags.NonPublic | BindingFlags.Instance; + + IEnumerable> requestHeaders1 = new[] + { + new KeyValuePair(HeaderNames.Method, "GET"), + new KeyValuePair(HeaderNames.Path, "/hello"), + new KeyValuePair(HeaderNames.Scheme, "http"), + new KeyValuePair(HeaderNames.Authority, "localhost:80"), + new KeyValuePair(HeaderNames.ContentType, "application/json") + }; + + // Note: No content-type + IEnumerable> requestHeaders2 = new[] + { + new KeyValuePair(HeaderNames.Method, "GET"), + new KeyValuePair(HeaderNames.Path, "/hello"), + new KeyValuePair(HeaderNames.Scheme, "http"), + new KeyValuePair(HeaderNames.Authority, "localhost:80") + }; + + await InitializeConnectionAsync(_noopApplication); + + await StartStreamAsync(1, requestHeaders1, endStream: true); + + await ExpectAsync(Http2FrameType.HEADERS, + withLength: 36, + withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM), + withStreamId: 1); + + // TriggerTick will trigger the stream to be returned to the pool so we can assert it + TriggerTick(_serviceContext.MockSystemClock.UtcNow); + + // Stream has been returned to the pool + Assert.Equal(1, _connection.StreamPool.Count); + Assert.True(_connection.StreamPool.TryPeek(out var stream1)); + + // Hacky but required because header references is private. + var headerReferences1 = typeof(HttpRequestHeaders).GetField("_headers", privateFlags).GetValue(stream1.RequestHeaders); + var contentTypeValue1 = (StringValues)headerReferences1.GetType().GetField("_ContentType").GetValue(headerReferences1); + + await StartStreamAsync(3, requestHeaders2, endStream: true); + + await ExpectAsync(Http2FrameType.HEADERS, + withLength: 6, + withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM), + withStreamId: 3); + + // TriggerTick will trigger the stream to be returned to the pool so we can assert it + TriggerTick(_serviceContext.MockSystemClock.UtcNow); + + // Stream has been returned to the pool + Assert.Equal(1, _connection.StreamPool.Count); + Assert.True(_connection.StreamPool.TryPeek(out var stream2)); + + // Hacky but required because header references is private. + var headerReferences2 = typeof(HttpRequestHeaders).GetField("_headers", privateFlags).GetValue(stream2.RequestHeaders); + var contentTypeValue2 = (StringValues)headerReferences2.GetType().GetField("_ContentType").GetValue(headerReferences2); + + Assert.Equal("application/json", contentTypeValue1); + Assert.Equal(StringValues.Empty, contentTypeValue2); + + await StopConnectionAsync(expectedLastStreamId: 3, ignoreNonGoAwayFrames: false); + } + private class ResponseTrailersWrapper : IHeaderDictionary { readonly IHeaderDictionary _innerHeaders; diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3ConnectionTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3ConnectionTests.cs index ead3a1656bdc..b83f3b64deb4 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3ConnectionTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3ConnectionTests.cs @@ -6,14 +6,18 @@ using System.Collections.Generic; using System.Globalization; using System.Net.Http; +using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Connections.Features; using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3; using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Primitives; using Microsoft.Net.Http.Headers; using Xunit; using Http3SettingType = Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.Http3SettingType; @@ -334,6 +338,49 @@ public async Task StreamPool_MultipleStreamsInSequence_PooledStreamReused() Assert.Same(streamContext1, streamContext2); } + [Fact] + public async Task RequestHeaderStringReuse_MultipleStreams_KnownHeaderClearedIfNotReused() + { + const BindingFlags privateFlags = BindingFlags.NonPublic | BindingFlags.Instance; + + KeyValuePair[] requestHeaders1 = new[] + { + new KeyValuePair(HeaderNames.Method, "GET"), + new KeyValuePair(HeaderNames.Path, "/hello"), + new KeyValuePair(HeaderNames.Scheme, "http"), + new KeyValuePair(HeaderNames.Authority, "localhost:80"), + new KeyValuePair(HeaderNames.ContentType, "application/json") + }; + + // Note: No content-type + KeyValuePair[] requestHeaders2 = new[] + { + new KeyValuePair(HeaderNames.Method, "GET"), + new KeyValuePair(HeaderNames.Path, "/hello"), + new KeyValuePair(HeaderNames.Scheme, "http"), + new KeyValuePair(HeaderNames.Authority, "localhost:80") + }; + + await Http3Api.InitializeConnectionAsync(_echoApplication); + + var streamContext1 = await MakeRequestAsync(0, requestHeaders1, sendData: true, waitForServerDispose: true); + var http3Stream1 = (Http3Stream)streamContext1.Features.Get().State[Http3Connection.StreamPersistentStateKey]; + + // Hacky but required because header references is private. + var headerReferences1 = typeof(HttpRequestHeaders).GetField("_headers", privateFlags).GetValue(http3Stream1.RequestHeaders); + var contentTypeValue1 = (StringValues)headerReferences1.GetType().GetField("_ContentType").GetValue(headerReferences1); + + var streamContext2 = await MakeRequestAsync(1, requestHeaders2, sendData: true, waitForServerDispose: true); + var http3Stream2 = (Http3Stream)streamContext2.Features.Get().State[Http3Connection.StreamPersistentStateKey]; + + // Hacky but required because header references is private. + var headerReferences2 = typeof(HttpRequestHeaders).GetField("_headers", privateFlags).GetValue(http3Stream2.RequestHeaders); + var contentTypeValue2 = (StringValues)headerReferences1.GetType().GetField("_ContentType").GetValue(headerReferences2); + + Assert.Equal("application/json", contentTypeValue1); + Assert.Equal(StringValues.Empty, contentTypeValue2); + } + [Theory] [InlineData(10)] [InlineData(100)]