diff --git a/NuGet.config b/NuGet.config index cb901c7182ff..1ccd39949f02 100644 --- a/NuGet.config +++ b/NuGet.config @@ -6,24 +6,16 @@ - - - - - - - - - - + + - + @@ -44,24 +36,16 @@ - - - - - - - - - - + - + + diff --git a/eng/Baseline.Designer.props b/eng/Baseline.Designer.props index fdced6323d23..d0138a65e8de 100644 --- a/eng/Baseline.Designer.props +++ b/eng/Baseline.Designer.props @@ -2,117 +2,117 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - - + + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 @@ -120,281 +120,281 @@ - 8.0.8 + 8.0.10 - - + + - - + + - - + + - 8.0.8 + 8.0.10 - + - + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - - + + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - - + + - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - - + + - 8.0.8 + 8.0.10 - - - - + + + + - 8.0.8 + 8.0.10 - - + + - - + + - 8.0.8 + 8.0.10 - - + + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - - + + - + - + - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - + - + - + - + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - + - + - + - 8.0.8 + 8.0.10 - - - - - + + + + + - + - - - - - + + + + + - + - - - - - + + + + + - + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - - + + - 8.0.8 + 8.0.10 - - + + - - + + - - + + - 8.0.8 + 8.0.10 - + - + - + - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 @@ -403,79 +403,79 @@ - 8.0.8 + 8.0.10 - - + + - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - - + + - - + + - - + + - - + + - 8.0.8 + 8.0.10 - - + + - + - - + + - 8.0.8 + 8.0.10 - - + + - 8.0.8 + 8.0.10 - - + + - 8.0.8 + 8.0.10 @@ -491,192 +491,192 @@ - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - - - + + + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - - + + - - + + - - + + - 8.0.8 + 8.0.10 - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + - 8.0.8 + 8.0.10 - + - + - + - + - + - 8.0.8 + 8.0.10 - + - + - + - 8.0.8 + 8.0.10 - + - + - + - 8.0.8 + 8.0.10 - + - + - + - 8.0.8 + 8.0.10 - - - - + + + + - 8.0.8 + 8.0.10 @@ -685,64 +685,64 @@ - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 @@ -764,29 +764,29 @@ - 8.0.8 + 8.0.10 - + - + - + - 8.0.8 + 8.0.10 @@ -802,48 +802,48 @@ - 8.0.8 + 8.0.10 - + - - + + - - - + + + - + - - + + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - - - + + + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 @@ -853,144 +853,144 @@ - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 - - + + - - + + - - + + - 8.0.8 + 8.0.10 - + - + - + - + - + - + - 8.0.8 + 8.0.10 - - - + + + - - - + + + - - - + + + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - - - - + + + + - - - - + + + + - - - - + + + + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - + - + - + - 8.0.8 + 8.0.10 - 8.0.8 + 8.0.10 - + - 8.0.8 + 8.0.10 diff --git a/eng/Baseline.xml b/eng/Baseline.xml index 199a62d5c74a..b69677446aba 100644 --- a/eng/Baseline.xml +++ b/eng/Baseline.xml @@ -4,110 +4,110 @@ 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 c0042cb37012..eadef3782912 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -9,45 +9,45 @@ --> - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 90d079985f33ae91c05b98ecf65e0ce38270ba55 + 4315fa43c9573671f8f5be21497d59f9c99cd829 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 90d079985f33ae91c05b98ecf65e0ce38270ba55 + 4315fa43c9573671f8f5be21497d59f9c99cd829 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 90d079985f33ae91c05b98ecf65e0ce38270ba55 + 4315fa43c9573671f8f5be21497d59f9c99cd829 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 90d079985f33ae91c05b98ecf65e0ce38270ba55 + 4315fa43c9573671f8f5be21497d59f9c99cd829 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 90d079985f33ae91c05b98ecf65e0ce38270ba55 + 4315fa43c9573671f8f5be21497d59f9c99cd829 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 90d079985f33ae91c05b98ecf65e0ce38270ba55 + 4315fa43c9573671f8f5be21497d59f9c99cd829 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 90d079985f33ae91c05b98ecf65e0ce38270ba55 + 4315fa43c9573671f8f5be21497d59f9c99cd829 - + https://dev.azure.com/dnceng/internal/_git/dotnet-efcore - 90d079985f33ae91c05b98ecf65e0ce38270ba55 + 4315fa43c9573671f8f5be21497d59f9c99cd829 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -73,37 +73,37 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -121,53 +121,53 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -185,9 +185,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://github.com/dotnet/source-build-externals @@ -199,17 +199,17 @@ 27e584661980ee6d82c419a2a471ae505b7d122e - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 2d7eea252964e69be94cb9c847b371b23e4dd470 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -219,45 +219,45 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 05e0f2d2c881def48961d3b83fa11ae84df8e534 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2aade6beb02ea367fd97c4070a4198802fe61c03 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2aade6beb02ea367fd97c4070a4198802fe61c03 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -271,21 +271,21 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2aade6beb02ea367fd97c4070a4198802fe61c03 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -300,38 +300,38 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 81cabf2857a01351e5ab578947c7403a5b128ad1 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://github.com/dotnet/xdt @@ -368,9 +368,9 @@ - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 08338fcaa5c9b9a8190abb99222fed12aaba956c + 81cabf2857a01351e5ab578947c7403a5b128ad1 https://github.com/dotnet/winforms diff --git a/eng/Versions.props b/eng/Versions.props index 820ca89f97af..0e5104d2ebd0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -11,7 +11,7 @@ 11 - false + true 7.1.2 7.* - 8.0.1 - 8.0.8 - 8.0.8 - 8.0.8 - 8.0.8 - 8.0.8 - 8.0.8-servicing.24366.12 + 8.0.2 + 8.0.10 + 8.0.10 + 8.0.10 + 8.0.10 + 8.0.10 + 8.0.10-servicing.24466.10 8.0.0 - 8.0.0 + 8.0.1 8.0.0 8.0.2 8.0.0 8.0.0 8.0.1 8.0.0 - 8.0.0 + 8.0.1 8.0.0 - 8.0.0 - 8.0.0 - 8.0.1 - 8.0.0 - 8.0.0 - 8.0.0 + 8.0.1 + 8.0.1 + 8.0.2 + 8.0.1 + 8.0.1 + 8.0.1 8.0.0 8.0.0 8.0.0 8.0.0 - 8.0.8-servicing.24366.12 - 8.0.0 - 8.0.0 - 8.0.0 - 8.0.1 - 8.0.0 - 8.0.0 - 8.0.0 - 8.0.0 - 8.0.0 - 8.0.0 - 8.0.0 + 8.0.10-servicing.24466.10 + 8.0.1 + 8.0.1 + 8.0.1 + 8.0.2 + 8.0.1 + 8.0.1 + 8.0.1 + 8.0.1 + 8.0.1 + 8.0.1 + 8.0.1 8.0.0 8.0.0 8.0.2 8.0.0 - 8.0.8-servicing.24366.12 - 8.0.0 + 8.0.10-servicing.24466.10 + 8.0.1 8.0.1 - 8.0.0 + 8.0.1 8.0.0 8.0.0-rtm.23520.14 8.0.0 - 8.0.0 + 8.0.1 8.0.2 - 8.0.0 + 8.0.1 8.0.0 - 8.0.0 - 8.0.1 + 8.0.1 + 8.0.2 8.0.0 - 8.0.0 + 8.0.1 8.0.0 - 8.0.4 + 8.0.5 8.0.0 8.0.0 8.0.0 - 8.0.8-servicing.24366.12 + 8.0.10-servicing.24466.10 - 8.0.8-servicing.24366.12 + 8.0.10-servicing.24466.10 8.0.0 8.0.1 8.0.0 - 8.0.0 + 8.0.1 8.0.0 - 8.0.0 + 8.0.1 8.1.0-preview.23604.1 8.1.0-preview.23604.1 - 8.0.8 - 8.0.8 - 8.0.8 - 8.0.8 - 8.0.8 - 8.0.8 - 8.0.8 - 8.0.8 + 8.0.10 + 8.0.10 + 8.0.10 + 8.0.10 + 8.0.10 + 8.0.10 + 8.0.10 + 8.0.10 4.8.0-3.23518.7 4.8.0-3.23518.7 diff --git a/global.json b/global.json index 28c2449f2525..4c706ad995e3 100644 --- a/global.json +++ b/global.json @@ -1,9 +1,9 @@ { "sdk": { - "version": "8.0.108" + "version": "8.0.110" }, "tools": { - "dotnet": "8.0.108", + "dotnet": "8.0.110", "runtimes": { "dotnet/x86": [ "$(MicrosoftNETCoreBrowserDebugHostTransportVersion)" diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs index d387d3629662..cd135fa3d319 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs @@ -68,25 +68,21 @@ public void StreamReset() _dataWriteProcessingTask = ProcessDataWrites().Preserve(); } - public void Dispose() + // Called once Application code has exited + // Or on Dispose which also would occur after Application code finished + public void Complete() { lock (_dataWriterLock) { - if (_disposed) - { - return; - } - - _disposed = true; - Stop(); + _pipeWriter.Complete(); + if (_fakeMemoryOwner != null) { _fakeMemoryOwner.Dispose(); _fakeMemoryOwner = null; } - if (_fakeMemory != null) { ArrayPool.Shared.Return(_fakeMemory); @@ -95,6 +91,21 @@ public void Dispose() } } + public void Dispose() + { + lock (_dataWriterLock) + { + if (_disposed) + { + return; + } + + _disposed = true; + + Complete(); + } + } + void IHttpOutputAborter.Abort(ConnectionAbortedException abortReason) { _stream.Abort(abortReason, Http3ErrorCode.InternalError); @@ -285,7 +296,9 @@ public void Stop() _streamCompleted = true; - _pipeWriter.Complete(new OperationCanceledException()); + // Application code could be using this PipeWriter, we cancel the next (or in progress) flush so they can observe this Stop + // Additionally, _streamCompleted will cause any future PipeWriter operations to noop + _pipeWriter.CancelPendingFlush(); } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs index bb42d0e18e6d..61625f180cd2 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -559,6 +559,8 @@ private void CompleteStream(bool errored) TryClose(); } + _http3Output.Complete(); + // Stream will be pooled after app completed. // Wait to signal app completed after any potential aborts on the stream. _appCompletedTaskSource.SetResult(null); diff --git a/src/Servers/Kestrel/Transport.Sockets/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj b/src/Servers/Kestrel/Transport.Sockets/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj index 9258e26fcba1..055f5f8e297e 100644 --- a/src/Servers/Kestrel/Transport.Sockets/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj +++ b/src/Servers/Kestrel/Transport.Sockets/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj @@ -44,5 +44,6 @@ + diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3RequestTests.cs b/src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3RequestTests.cs index 1c71550c2a68..180664d7c136 100644 --- a/src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3RequestTests.cs +++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3RequestTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers; using System.Diagnostics; using System.Diagnostics.Metrics; using System.Net; @@ -1143,6 +1144,137 @@ public async Task POST_Bidirectional_LargeData_Cancellation_Error(HttpProtocols } } + internal class MemoryPoolFeature : IMemoryPoolFeature + { + public MemoryPool MemoryPool { get; set; } + } + + [ConditionalTheory] + [MsQuicSupported] + [InlineData(HttpProtocols.Http3)] + [InlineData(HttpProtocols.Http2)] + public async Task ApplicationWriteWhenConnectionClosesPreservesMemory(HttpProtocols protocol) + { + // Arrange + var memoryPool = new DiagnosticMemoryPool(new PinnedBlockMemoryPool(), allowLateReturn: true); + + var writingTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + var cancelTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + var completionTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + var builder = CreateHostBuilder(async context => + { + try + { + var requestBody = context.Request.Body; + + await context.Response.BodyWriter.FlushAsync(); + + // Test relies on Htt2Stream/Http3Stream aborting the token after stopping Http2OutputProducer/Http3OutputProducer + // It's very fragile but it is sort of a best effort test anyways + // Additionally, Http2 schedules it's stopping, so doesn't directly do anything to the PipeWriter when calling stop on Http2OutputProducer + context.RequestAborted.Register(() => + { + cancelTcs.SetResult(); + }); + + while (true) + { + var memory = context.Response.BodyWriter.GetMemory(); + + // Unblock client-side to close the connection + writingTcs.TrySetResult(); + + await cancelTcs.Task; + + // Verify memory is still rented from the memory pool after the producer has been stopped + Assert.True(memoryPool.ContainsMemory(memory)); + + context.Response.BodyWriter.Advance(memory.Length); + var flushResult = await context.Response.BodyWriter.FlushAsync(); + + if (flushResult.IsCanceled || flushResult.IsCompleted) + { + break; + } + } + + completionTcs.SetResult(); + } + catch (Exception ex) + { + writingTcs.TrySetException(ex); + // Exceptions annoyingly don't show up on the client side when doing E2E + cancellation testing + // so we need to use a TCS to observe any unexpected errors + completionTcs.TrySetException(ex); + throw; + } + }, protocol: protocol, + configureKestrel: o => + { + o.Listen(IPAddress.Parse("127.0.0.1"), 0, listenOptions => + { + listenOptions.Protocols = protocol; + listenOptions.UseHttps(TestResources.GetTestCertificate()).Use(@delegate => + { + // Connection middleware for Http/1.1 and Http/2 + return (context) => + { + // Set the memory pool used by the connection so we can observe if memory from the PipeWriter is still rented from the pool + context.Features.Set(new MemoryPoolFeature() { MemoryPool = memoryPool }); + return @delegate(context); + }; + }); + + IMultiplexedConnectionBuilder multiplexedConnectionBuilder = listenOptions; + multiplexedConnectionBuilder.Use(@delegate => + { + // Connection middleware for Http/3 + return (context) => + { + // Set the memory pool used by the connection so we can observe if memory from the PipeWriter is still rented from the pool + context.Features.Set(new MemoryPoolFeature() { MemoryPool = memoryPool }); + return @delegate(context); + }; + }); + }); + }); + + var httpClientHandler = new HttpClientHandler(); + httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; + + using (var host = builder.Build()) + using (var client = new HttpClient(httpClientHandler)) + { + await host.StartAsync().DefaultTimeout(); + + var cts = new CancellationTokenSource(); + + var request = new HttpRequestMessage(HttpMethod.Post, $"https://127.0.0.1:{host.GetPort()}/"); + request.Version = GetProtocol(protocol); + request.VersionPolicy = HttpVersionPolicy.RequestVersionExact; + + // Act + var responseTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); + + Logger.LogInformation("Client waiting for headers."); + var response = await responseTask.DefaultTimeout(); + await writingTcs.Task; + + Logger.LogInformation("Client canceled request."); + response.Dispose(); + + // Assert + await host.StopAsync().DefaultTimeout(); + + await completionTcs.Task; + + memoryPool.Dispose(); + + await memoryPool.WhenAllBlocksReturnedAsync(TimeSpan.FromSeconds(15)); + } + } + // Verify HTTP/2 and HTTP/3 match behavior [ConditionalTheory] [MsQuicSupported] diff --git a/src/Shared/Buffers.MemoryPool/DiagnosticMemoryPool.cs b/src/Shared/Buffers.MemoryPool/DiagnosticMemoryPool.cs index 5c7f2cd686ae..32e3ab4b2189 100644 --- a/src/Shared/Buffers.MemoryPool/DiagnosticMemoryPool.cs +++ b/src/Shared/Buffers.MemoryPool/DiagnosticMemoryPool.cs @@ -162,4 +162,27 @@ public async Task WhenAllBlocksReturnedAsync(TimeSpan timeout) await task; } + + public bool ContainsMemory(Memory memory) + { + lock (_syncObj) + { + foreach (var block in _blocks) + { + unsafe + { + fixed (byte* inUseMemoryPtr = memory.Span) + fixed (byte* beginPooledMemoryPtr = block.Memory.Span) + { + byte* endPooledMemoryPtr = beginPooledMemoryPtr + block.Memory.Length; + if (inUseMemoryPtr >= beginPooledMemoryPtr && inUseMemoryPtr < endPooledMemoryPtr) + { + return true; + } + } + } + } + return false; + } + } }