From 768e2f8208f1061d2971b3178b4f70838af6133c Mon Sep 17 00:00:00 2001 From: Adrian Wright Date: Wed, 27 Mar 2019 21:51:22 +0000 Subject: [PATCH 01/19] Remove explicit footer height --- .../content/RazorPagesWeb-CSharp/wwwroot/css/site.css | 2 -- .../content/StarterWeb-CSharp/wwwroot/css/site.css | 2 -- .../content/StarterWeb-FSharp/wwwroot/css/site.css | 2 -- 3 files changed, 6 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/wwwroot/css/site.css b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/wwwroot/css/site.css index c486131d5a..19dc5bf077 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/wwwroot/css/site.css +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/wwwroot/css/site.css @@ -50,7 +50,5 @@ body { bottom: 0; width: 100%; white-space: nowrap; - /* Set the fixed height of the footer here */ - height: 60px; line-height: 60px; /* Vertically center the text there */ } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/wwwroot/css/site.css b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/wwwroot/css/site.css index c486131d5a..19dc5bf077 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/wwwroot/css/site.css +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/wwwroot/css/site.css @@ -50,7 +50,5 @@ body { bottom: 0; width: 100%; white-space: nowrap; - /* Set the fixed height of the footer here */ - height: 60px; line-height: 60px; /* Vertically center the text there */ } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/wwwroot/css/site.css b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/wwwroot/css/site.css index c486131d5a..19dc5bf077 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/wwwroot/css/site.css +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/wwwroot/css/site.css @@ -50,7 +50,5 @@ body { bottom: 0; width: 100%; white-space: nowrap; - /* Set the fixed height of the footer here */ - height: 60px; line-height: 60px; /* Vertically center the text there */ } From 8bfbc4a2ac8f32e61a9d6eee8c55901771478428 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 8 Apr 2019 12:11:07 -0700 Subject: [PATCH 02/19] [master] Update dependencies from 2 repositories (#9160) * Update dependencies from https://github.com/aspnet/AspNetCore-Tooling build 20190407.2 - Microsoft.NET.Sdk.Razor - 3.0.0-preview4.19207.2 - Microsoft.CodeAnalysis.Razor - 3.0.0-preview4.19207.2 - Microsoft.AspNetCore.Razor.Language - 3.0.0-preview4.19207.2 - Microsoft.AspNetCore.Mvc.Razor.Extensions - 3.0.0-preview4.19207.2 * Update dependencies from https://github.com/aspnet/EntityFrameworkCore build 20190407.2 - Microsoft.EntityFrameworkCore.Tools - 3.0.0-preview4.19207.2 - Microsoft.EntityFrameworkCore.SqlServer - 3.0.0-preview4.19207.2 - dotnet-ef - 3.0.0-preview4.19207.2 - Microsoft.EntityFrameworkCore - 3.0.0-preview4.19207.2 - Microsoft.EntityFrameworkCore.InMemory - 3.0.0-preview4.19207.2 - Microsoft.EntityFrameworkCore.Relational - 3.0.0-preview4.19207.2 - Microsoft.EntityFrameworkCore.Sqlite - 3.0.0-preview4.19207.2 Dependency coherency updates - Microsoft.AspNetCore.Analyzer.Testing - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.AspNetCore.BenchmarkRunner.Sources - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.ActivatorUtilities.Sources - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Caching.Abstractions - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Caching.Memory - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Caching.SqlServer - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Caching.StackExchangeRedis - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.CommandLineUtils.Sources - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.Abstractions - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.AzureKeyVault - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.Binder - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.CommandLine - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.EnvironmentVariables - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.FileExtensions - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.Ini - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.Json - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.KeyPerFile - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.UserSecrets - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.Xml - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.DependencyInjection.Abstractions - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.DependencyInjection - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.DiagnosticAdapter - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Diagnostics.HealthChecks - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.FileProviders.Abstractions - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.FileProviders.Composite - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.FileProviders.Embedded - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.FileProviders.Physical - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.FileSystemGlobbing - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.HashCodeCombiner.Sources - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Hosting.Abstractions - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Hosting - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.HostFactoryResolver.Sources - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Http - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Localization.Abstractions - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Localization - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.Abstractions - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.AzureAppServices - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.Configuration - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.Console - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.Debug - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.EventSource - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.TraceSource - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.Testing - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.ObjectPool - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Options.ConfigurationExtensions - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Options.DataAnnotations - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Options - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.ParameterDefaultValue.Sources - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Primitives - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.TypeNameHelper.Sources - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.ValueStopwatch.Sources - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.WebEncoders - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Internal.Extensions.Refs - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.JSInterop - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Mono.WebAssembly.Interop - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Bcl.Json.Sources - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.CSharp - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Win32.Registry - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.ComponentModel.Annotations - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Data.SqlClient - 4.7.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Diagnostics.EventLog - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.IO.Pipelines - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Net.Http.WinHttpHandler - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Net.WebSockets.WebSocketProtocol - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Reflection.Metadata - 1.7.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Runtime.CompilerServices.Unsafe - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Security.Cryptography.Cng - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Security.Cryptography.Pkcs - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Security.Cryptography.Xml - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Security.Permissions - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Security.Principal.Windows - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.ServiceProcess.ServiceController - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Text.Encodings.Web - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - System.Threading.Channels - 4.6.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.DependencyModel - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.NETCore.Platforms - 3.0.0-preview5.19205.9 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-01 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Internal.AspNetCore.Analyzers - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.AspNetCore.Testing - 3.0.0-preview4.19206.2 (parent: Microsoft.EntityFrameworkCore) * Rename option type temporarily until entire swap is done * nit * Rename adapter option type --- eng/Version.Details.xml | 372 +++++++++--------- eng/Versions.props | 186 ++++----- ...Microsoft.AspNetCore.Http.netcoreapp3.0.cs | 10 +- src/Http/Http/src/StreamPipeReader.cs | 4 +- src/Http/Http/src/StreamPipeReaderOptions.cs | 8 +- src/Http/Http/test/StreamPipeReaderTests.cs | 4 +- src/Http/Http/test/StreamPipeTest.cs | 2 +- .../Http/HttpProtocol.FeatureCollection.cs | 2 +- 8 files changed, 294 insertions(+), 294 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cf6155f54c..2417483a7e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -9,384 +9,384 @@ --> - + https://github.com/aspnet/AspNetCore-Tooling - cb6f5d0dc7de35046ca50df2c0cadd95e3a70707 + 3c92785f600a5aeb06f0c26264727270865b5a3d - + https://github.com/aspnet/AspNetCore-Tooling - cb6f5d0dc7de35046ca50df2c0cadd95e3a70707 + 3c92785f600a5aeb06f0c26264727270865b5a3d - + https://github.com/aspnet/AspNetCore-Tooling - cb6f5d0dc7de35046ca50df2c0cadd95e3a70707 + 3c92785f600a5aeb06f0c26264727270865b5a3d - + https://github.com/aspnet/AspNetCore-Tooling - cb6f5d0dc7de35046ca50df2c0cadd95e3a70707 + 3c92785f600a5aeb06f0c26264727270865b5a3d - + https://github.com/aspnet/EntityFrameworkCore - ed0cf26ad6fc200a47a803999e701ada1ce1101a + 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 - + https://github.com/aspnet/EntityFrameworkCore - ed0cf26ad6fc200a47a803999e701ada1ce1101a + 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 - + https://github.com/aspnet/EntityFrameworkCore - ed0cf26ad6fc200a47a803999e701ada1ce1101a + 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 - + https://github.com/aspnet/EntityFrameworkCore - ed0cf26ad6fc200a47a803999e701ada1ce1101a + 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 - + https://github.com/aspnet/EntityFrameworkCore - ed0cf26ad6fc200a47a803999e701ada1ce1101a + 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 - + https://github.com/aspnet/EntityFrameworkCore - ed0cf26ad6fc200a47a803999e701ada1ce1101a + 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 - + https://github.com/aspnet/EntityFrameworkCore - ed0cf26ad6fc200a47a803999e701ada1ce1101a + 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/dotnet/core-setup - 209213958004859a79ca586e7b278b5c7fe1f4b0 + ccdc90de5f757c56e13bf5c095ee5d2aa8ca1aa4 - + https://github.com/dotnet/core-setup - 209213958004859a79ca586e7b278b5c7fe1f4b0 + ccdc90de5f757c56e13bf5c095ee5d2aa8ca1aa4 - + https://github.com/dotnet/corefx - 871c5eae12ce339221ef0329009470c9945e34e5 + 35249a0072b41a89ce1542deacb2611c2393dec0 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 https://github.com/dotnet/arcade b1f9e12fe3ee71c48ea60b15968745850ac0a4a7 - + https://github.com/aspnet/Extensions - e797664b05db61037b493c4ab9cc632b6f9732d3 + 4b123acda735f7a7e20b62d9cfafabe5707290a0 diff --git a/eng/Versions.props b/eng/Versions.props index 7f78dc2868..a9cc55bc7e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -19,104 +19,104 @@ 1.0.0-beta.19207.1 - 3.0.0-preview4-27604-13 - 3.0.0-preview4-27604-13 + 3.0.0-preview5-27606-01 + 3.0.0-preview5-27606-01 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.7.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 1.7.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 - 4.6.0-preview4.19204.5 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.7.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 1.7.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 + 4.6.0-preview5.19205.9 - 3.0.0-preview4.19204.5 + 3.0.0-preview5.19205.9 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 - 3.0.0-preview4.19205.3 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 + 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.3 - 3.0.0-preview4.19206.3 - 3.0.0-preview4.19206.3 - 3.0.0-preview4.19206.3 - 3.0.0-preview4.19206.3 - 3.0.0-preview4.19206.3 - 3.0.0-preview4.19206.3 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 - 3.0.0-preview4.19206.3 - 3.0.0-preview4.19206.3 - 3.0.0-preview4.19206.3 - 3.0.0-preview4.19206.3 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 From 7a0b2142b207d769726a9bac2106c9106f02ec16 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Mon, 8 Apr 2019 11:57:02 -0700 Subject: [PATCH 05/19] Update branding for preview 5 --- version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.props b/version.props index 74142c4aa0..5d7bcf2f92 100644 --- a/version.props +++ b/version.props @@ -3,7 +3,7 @@ 3 0 0 - 4 + 5 preview$(PreReleasePreviewNumber) Preview $(PreReleasePreviewNumber) 0.3.$(AspNetCorePatchVersion) From 4d78c215750a8fcc728f7388cdd8260e5fa3fe6c Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Mon, 8 Apr 2019 21:01:55 -0700 Subject: [PATCH 06/19] Remove reference to Microsoft.AspNetCore.Components.Server (#9169) --- .../BlazorHosted-CSharp.Server/BlazorHosted-CSharp.Server.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Components/Blazor/Templates/src/content/BlazorHosted-CSharp/BlazorHosted-CSharp.Server/BlazorHosted-CSharp.Server.csproj b/src/Components/Blazor/Templates/src/content/BlazorHosted-CSharp/BlazorHosted-CSharp.Server/BlazorHosted-CSharp.Server.csproj index 622684bb25..05506ff5f1 100644 --- a/src/Components/Blazor/Templates/src/content/BlazorHosted-CSharp/BlazorHosted-CSharp.Server/BlazorHosted-CSharp.Server.csproj +++ b/src/Components/Blazor/Templates/src/content/BlazorHosted-CSharp/BlazorHosted-CSharp.Server/BlazorHosted-CSharp.Server.csproj @@ -11,7 +11,6 @@ - From e4fbd598b56c5582335b427dedfb68495d1b8489 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Tue, 9 Apr 2019 07:00:02 +0100 Subject: [PATCH 07/19] Reuse previous materialized strings (#8374) --- ...tCore.Server.Kestrel.Core.netcoreapp3.0.cs | 2 + .../Core/src/Internal/Http/Http1Connection.cs | 136 +- .../src/Internal/Http/Http1ParsingHandler.cs | 3 + .../Internal/Http/HttpHeaders.Generated.cs | 1334 +++++++---------- .../Core/src/Internal/Http/HttpHeaders.cs | 1 + .../Core/src/Internal/Http/HttpParser.cs | 1 + .../Core/src/Internal/Http/HttpProtocol.cs | 17 +- .../src/Internal/Http/HttpRequestHeaders.cs | 80 +- .../src/Internal/Http/IHttpHeadersHandler.cs | 1 + .../src/Internal/Http2/Http2Connection.cs | 3 + .../Infrastructure/StringUtilities.cs | 261 ++++ .../Kestrel/Core/src/KestrelServerOptions.cs | 9 + .../Kestrel/Core/test/AsciiDecoding.cs | 99 +- .../Kestrel/Core/test/HPackDecoderTests.cs | 2 + .../Kestrel/Core/test/HttpParserTests.cs | 2 + .../Core/test/HttpRequestHeadersTests.cs | 343 ++++- ...spNetCore.Server.Kestrel.Core.Tests.csproj | 1 + .../Kestrel/Core/test/StartLineTests.cs | 536 +++++++ .../Http1ConnectionBenchmark.cs | 3 + .../HttpParserBenchmark.cs | 7 + .../Kestrel.Performance/Mocks/NullParser.cs | 1 + .../BenchmarkApplication.HttpConnection.cs | 6 + .../CodeGenerator => shared}/KnownHeaders.cs | 560 +++++-- .../Http2/Http2TestBase.cs | 2 + .../tools/CodeGenerator/CodeGenerator.csproj | 4 + 25 files changed, 2461 insertions(+), 953 deletions(-) create mode 100644 src/Servers/Kestrel/Core/test/StartLineTests.cs rename src/Servers/Kestrel/{tools/CodeGenerator => shared}/KnownHeaders.cs (63%) diff --git a/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp3.0.cs b/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp3.0.cs index 494c58056d..62687bc800 100644 --- a/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp3.0.cs +++ b/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp3.0.cs @@ -121,6 +121,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core public Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingMode ApplicationSchedulingMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public System.IServiceProvider ApplicationServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader ConfigurationLoader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool DisableStringReuse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerLimits Limits { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader Configure() { throw null; } public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader Configure(Microsoft.Extensions.Configuration.IConfiguration config) { throw null; } @@ -251,6 +252,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public partial interface IHttpHeadersHandler { void OnHeader(System.Span name, System.Span value); + void OnHeadersComplete(); } public partial interface IHttpParser where TRequestHandler : Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpHeadersHandler, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpRequestLineHandler { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs index d2cdb57382..7b23196794 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs @@ -19,6 +19,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private const byte ByteAsterisk = (byte)'*'; private const byte ByteForwardSlash = (byte)'/'; private const string Asterisk = "*"; + private const string ForwardSlash = "/"; private readonly HttpConnectionContext _context; private readonly IHttpParser _parser; @@ -268,16 +269,68 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _requestTargetForm = HttpRequestTarget.OriginForm; + if (target.Length == 1) + { + // If target.Length == 1 it can only be a forward slash (e.g. home page) + // and we know RawTarget and Path are the same and QueryString is Empty + RawTarget = ForwardSlash; + Path = ForwardSlash; + QueryString = string.Empty; + // Clear parsedData as we won't check it if we come via this path again, + // an setting to null is fast as it doesn't need to use a GC write barrier. + _parsedRawTarget = _parsedPath = _parsedQueryString = null; + return; + } + // URIs are always encoded/escaped to ASCII https://tools.ietf.org/html/rfc3986#page-11 // Multibyte Internationalized Resource Identifiers (IRIs) are first converted to utf8; // then encoded/escaped to ASCII https://www.ietf.org/rfc/rfc3987.txt "Mapping of IRIs to URIs" try { + var disableStringReuse = ServerOptions.DisableStringReuse; // Read raw target before mutating memory. - RawTarget = target.GetAsciiStringNonNullCharacters(); - QueryString = query.GetAsciiStringNonNullCharacters(); - Path = PathNormalizer.DecodePath(path, pathEncoded, RawTarget, query.Length); + var previousValue = _parsedRawTarget; + if (disableStringReuse || + previousValue == null || previousValue.Length != target.Length || + !StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, target)) + { + // The previous string does not match what the bytes would convert to, + // so we will need to generate a new string. + RawTarget = _parsedRawTarget = target.GetAsciiStringNonNullCharacters(); + + previousValue = _parsedQueryString; + if (disableStringReuse || + previousValue == null || previousValue.Length != query.Length || + !StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, query)) + { + // The previous string does not match what the bytes would convert to, + // so we will need to generate a new string. + QueryString = _parsedQueryString = query.GetAsciiStringNonNullCharacters(); + } + else + { + // Same as previous + QueryString = _parsedQueryString; + } + + if (path.Length == 1) + { + // If path.Length == 1 it can only be a forward slash (e.g. home page) + Path = _parsedPath = ForwardSlash; + } + else + { + Path = _parsedPath = PathNormalizer.DecodePath(path, pathEncoded, RawTarget, query.Length); + } + } + else + { + // As RawTarget is the same we can reuse the previous parsed values. + RawTarget = _parsedRawTarget; + Path = _parsedPath; + QueryString = _parsedQueryString; + } } catch (InvalidOperationException) { @@ -312,9 +365,27 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http // // Allowed characters in the 'host + port' section of authority. // See https://tools.ietf.org/html/rfc3986#section-3.2 - RawTarget = target.GetAsciiStringNonNullCharacters(); + + var previousValue = _parsedRawTarget; + if (ServerOptions.DisableStringReuse || + previousValue == null || previousValue.Length != target.Length || + !StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, target)) + { + // The previous string does not match what the bytes would convert to, + // so we will need to generate a new string. + RawTarget = _parsedRawTarget = target.GetAsciiStringNonNullCharacters(); + } + else + { + // Reuse previous value + RawTarget = _parsedRawTarget; + } + Path = string.Empty; QueryString = string.Empty; + // Clear parsedData for path and queryString as we won't check it if we come via this path again, + // an setting to null is fast as it doesn't need to use a GC write barrier. + _parsedPath = _parsedQueryString = null; } private void OnAsteriskFormTarget(HttpMethod method) @@ -331,6 +402,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http RawTarget = Asterisk; Path = string.Empty; QueryString = string.Empty; + // Clear parsedData as we won't check it if we come via this path again, + // an setting to null is fast as it doesn't need to use a GC write barrier. + _parsedRawTarget = _parsedPath = _parsedQueryString = null; } private void OnAbsoluteFormTarget(Span target, Span query) @@ -346,21 +420,49 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http // a server MUST accept the absolute-form in requests, even though // HTTP/1.1 clients will only send them in requests to proxies. - RawTarget = target.GetAsciiStringNonNullCharacters(); - - // Validation of absolute URIs is slow, but clients - // should not be sending this form anyways, so perf optimization - // not high priority - - if (!Uri.TryCreate(RawTarget, UriKind.Absolute, out var uri)) + var disableStringReuse = ServerOptions.DisableStringReuse; + var previousValue = _parsedRawTarget; + if (disableStringReuse || + previousValue == null || previousValue.Length != target.Length || + !StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, target)) { - ThrowRequestTargetRejected(target); - } + // The previous string does not match what the bytes would convert to, + // so we will need to generate a new string. + RawTarget = _parsedRawTarget = target.GetAsciiStringNonNullCharacters(); - _absoluteRequestTarget = uri; - Path = uri.LocalPath; - // don't use uri.Query because we need the unescaped version - QueryString = query.GetAsciiStringNonNullCharacters(); + // Validation of absolute URIs is slow, but clients + // should not be sending this form anyways, so perf optimization + // not high priority + + if (!Uri.TryCreate(RawTarget, UriKind.Absolute, out var uri)) + { + ThrowRequestTargetRejected(target); + } + + _absoluteRequestTarget = uri; + Path = _parsedPath = uri.LocalPath; + // don't use uri.Query because we need the unescaped version + previousValue = _parsedQueryString; + if (disableStringReuse || + previousValue == null || previousValue.Length != query.Length || + !StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, query)) + { + // The previous string does not match what the bytes would convert to, + // so we will need to generate a new string. + QueryString = _parsedQueryString = query.GetAsciiStringNonNullCharacters(); + } + else + { + QueryString = _parsedQueryString; + } + } + else + { + // As RawTarget is the same we can reuse the previous values. + RawTarget = _parsedRawTarget; + Path = _parsedPath; + QueryString = _parsedQueryString; + } } internal void EnsureHostHeaderExists() diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ParsingHandler.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ParsingHandler.cs index a7d6fdddc7..bcc905cab9 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ParsingHandler.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ParsingHandler.cs @@ -17,6 +17,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public void OnHeader(Span name, Span value) => Connection.OnHeader(name, value); + public void OnHeadersComplete() + => Connection.OnHeadersComplete(); + public void OnStartLine(HttpMethod method, HttpVersion version, Span target, Span path, Span query, Span customMethod, bool pathEncoded) => Connection.OnStartLine(method, version, target, path, query, customMethod, pathEncoded); } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs index a69e738048..55882f905d 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs @@ -6,16 +6,16 @@ using System.Collections.Generic; using System.Buffers; using System.IO.Pipelines; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using Microsoft.Extensions.Primitives; using Microsoft.Net.Http.Headers; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { internal partial class HttpRequestHeaders { - - private long _bits = 0; private HeaderReferences _headers; public bool HasConnection => (_bits & 0x2L) != 0; @@ -703,12 +703,46 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _headers._UserAgent = value; } } - public StringValues HeaderOrigin + public StringValues HeaderDNT { get { StringValues value = default; if ((_bits & 0x10000000000L) != 0) + { + value = _headers._DNT; + } + return value; + } + set + { + _bits |= 0x10000000000L; + _headers._DNT = value; + } + } + public StringValues HeaderUpgradeInsecureRequests + { + get + { + StringValues value = default; + if ((_bits & 0x20000000000L) != 0) + { + value = _headers._UpgradeInsecureRequests; + } + return value; + } + set + { + _bits |= 0x20000000000L; + _headers._UpgradeInsecureRequests = value; + } + } + public StringValues HeaderOrigin + { + get + { + StringValues value = default; + if ((_bits & 0x40000000000L) != 0) { value = _headers._Origin; } @@ -716,7 +750,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x10000000000L; + _bits |= 0x40000000000L; _headers._Origin = value; } } @@ -725,7 +759,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x20000000000L) != 0) + if ((_bits & 0x80000000000L) != 0) { value = _headers._AccessControlRequestMethod; } @@ -733,7 +767,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x20000000000L; + _bits |= 0x80000000000L; _headers._AccessControlRequestMethod = value; } } @@ -742,7 +776,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x40000000000L) != 0) + if ((_bits & 0x100000000000L) != 0) { value = _headers._AccessControlRequestHeaders; } @@ -750,7 +784,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x40000000000L; + _bits |= 0x100000000000L; _headers._AccessControlRequestHeaders = value; } } @@ -932,7 +966,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if ("Origin".Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x10000000000L) != 0) + if ((_bits & 0x40000000000L) != 0) { value = _headers._Origin; return true; @@ -1023,6 +1057,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } return false; } + if ("DNT".Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x10000000000L) != 0) + { + value = _headers._DNT; + return true; + } + return false; + } } break; case 5: @@ -1227,11 +1270,24 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } } break; + case 25: + { + if ("Upgrade-Insecure-Requests".Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x20000000000L) != 0) + { + value = _headers._UpgradeInsecureRequests; + return true; + } + return false; + } + } + break; case 29: { if ("Access-Control-Request-Method".Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x20000000000L) != 0) + if ((_bits & 0x80000000000L) != 0) { value = _headers._AccessControlRequestMethod; return true; @@ -1244,7 +1300,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if ("Access-Control-Request-Headers".Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x40000000000L) != 0) + if ((_bits & 0x100000000000L) != 0) { value = _headers._AccessControlRequestHeaders; return true; @@ -1368,7 +1424,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if ("Origin".Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x10000000000L; + _bits |= 0x40000000000L; _headers._Origin = value; return; } @@ -1432,6 +1488,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _headers._Via = value; return; } + if ("DNT".Equals(key, StringComparison.OrdinalIgnoreCase)) + { + _bits |= 0x10000000000L; + _headers._DNT = value; + return; + } } break; case 5: @@ -1581,11 +1643,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } } break; + case 25: + { + if ("Upgrade-Insecure-Requests".Equals(key, StringComparison.OrdinalIgnoreCase)) + { + _bits |= 0x20000000000L; + _headers._UpgradeInsecureRequests = value; + return; + } + } + break; case 29: { if ("Access-Control-Request-Method".Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x20000000000L; + _bits |= 0x80000000000L; _headers._AccessControlRequestMethod = value; return; } @@ -1595,7 +1667,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if ("Access-Control-Request-Headers".Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x40000000000L; + _bits |= 0x100000000000L; _headers._AccessControlRequestHeaders = value; return; } @@ -1776,9 +1848,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if ("Origin".Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x10000000000L) == 0) + if ((_bits & 0x40000000000L) == 0) { - _bits |= 0x10000000000L; + _bits |= 0x40000000000L; _headers._Origin = value; return true; } @@ -1876,6 +1948,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } return false; } + if ("DNT".Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x10000000000L) == 0) + { + _bits |= 0x10000000000L; + _headers._DNT = value; + return true; + } + return false; + } } break; case 5: @@ -2097,13 +2179,27 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } } break; - case 29: + case 25: { - if ("Access-Control-Request-Method".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Upgrade-Insecure-Requests".Equals(key, StringComparison.OrdinalIgnoreCase)) { if ((_bits & 0x20000000000L) == 0) { _bits |= 0x20000000000L; + _headers._UpgradeInsecureRequests = value; + return true; + } + return false; + } + } + break; + case 29: + { + if ("Access-Control-Request-Method".Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x80000000000L) == 0) + { + _bits |= 0x80000000000L; _headers._AccessControlRequestMethod = value; return true; } @@ -2115,9 +2211,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if ("Access-Control-Request-Headers".Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x40000000000L) == 0) + if ((_bits & 0x100000000000L) == 0) { - _bits |= 0x40000000000L; + _bits |= 0x100000000000L; _headers._AccessControlRequestHeaders = value; return true; } @@ -2302,9 +2398,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if ("Origin".Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x10000000000L) != 0) + if ((_bits & 0x40000000000L) != 0) { - _bits &= ~0x10000000000L; + _bits &= ~0x40000000000L; _headers._Origin = default(StringValues); return true; } @@ -2402,6 +2498,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } return false; } + if ("DNT".Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x10000000000L) != 0) + { + _bits &= ~0x10000000000L; + _headers._DNT = default(StringValues); + return true; + } + return false; + } } break; case 5: @@ -2623,13 +2729,27 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } } break; - case 29: + case 25: { - if ("Access-Control-Request-Method".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Upgrade-Insecure-Requests".Equals(key, StringComparison.OrdinalIgnoreCase)) { if ((_bits & 0x20000000000L) != 0) { _bits &= ~0x20000000000L; + _headers._UpgradeInsecureRequests = default(StringValues); + return true; + } + return false; + } + } + break; + case 29: + { + if ("Access-Control-Request-Method".Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x80000000000L) != 0) + { + _bits &= ~0x80000000000L; _headers._AccessControlRequestMethod = default(StringValues); return true; } @@ -2641,9 +2761,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if ("Access-Control-Request-Headers".Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x40000000000L) != 0) + if ((_bits & 0x100000000000L) != 0) { - _bits &= ~0x40000000000L; + _bits &= ~0x100000000000L; _headers._AccessControlRequestHeaders = default(StringValues); return true; } @@ -2655,18 +2775,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return MaybeUnknown?.Remove(key) ?? false; } - - protected override void ClearFast() + private void Clear(long bitsToClear) { - MaybeUnknown?.Clear(); - _contentLength = null; - var tempBits = _bits; - _bits = 0; - if(HttpHeaders.BitCount(tempBits) > 12) - { - _headers = default(HeaderReferences); - return; - } + var tempBits = bitsToClear; if ((tempBits & 0x2L) != 0) { @@ -3070,7 +3181,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x10000000000L) != 0) { - _headers._Origin = default(StringValues); + _headers._DNT = default(StringValues); if((tempBits & ~0x10000000000L) == 0) { return; @@ -3080,7 +3191,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x20000000000L) != 0) { - _headers._AccessControlRequestMethod = default(StringValues); + _headers._UpgradeInsecureRequests = default(StringValues); if((tempBits & ~0x20000000000L) == 0) { return; @@ -3090,7 +3201,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x40000000000L) != 0) { - _headers._AccessControlRequestHeaders = default(StringValues); + _headers._Origin = default(StringValues); if((tempBits & ~0x40000000000L) == 0) { return; @@ -3098,6 +3209,26 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http tempBits &= ~0x40000000000L; } + if ((tempBits & 0x80000000000L) != 0) + { + _headers._AccessControlRequestMethod = default(StringValues); + if((tempBits & ~0x80000000000L) == 0) + { + return; + } + tempBits &= ~0x80000000000L; + } + + if ((tempBits & 0x100000000000L) != 0) + { + _headers._AccessControlRequestHeaders = default(StringValues); + if((tempBits & ~0x100000000000L) == 0) + { + return; + } + tempBits &= ~0x100000000000L; + } + } protected override bool CopyToFast(KeyValuePair[] array, int arrayIndex) @@ -3473,7 +3604,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair("Origin", _headers._Origin); + array[arrayIndex] = new KeyValuePair("DNT", _headers._DNT); ++arrayIndex; } if ((_bits & 0x20000000000L) != 0) @@ -3482,10 +3613,28 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair("Access-Control-Request-Method", _headers._AccessControlRequestMethod); + array[arrayIndex] = new KeyValuePair("Upgrade-Insecure-Requests", _headers._UpgradeInsecureRequests); ++arrayIndex; } if ((_bits & 0x40000000000L) != 0) + { + if (arrayIndex == array.Length) + { + return false; + } + array[arrayIndex] = new KeyValuePair("Origin", _headers._Origin); + ++arrayIndex; + } + if ((_bits & 0x80000000000L) != 0) + { + if (arrayIndex == array.Length) + { + return false; + } + array[arrayIndex] = new KeyValuePair("Access-Control-Request-Method", _headers._AccessControlRequestMethod); + ++arrayIndex; + } + if ((_bits & 0x100000000000L) != 0) { if (arrayIndex == array.Length) { @@ -3508,734 +3657,345 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return true; } - - public unsafe void Append(byte* pKeyBytes, int keyLength, string value) + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public unsafe void Append(Span name, Span value) { - var pUB = pKeyBytes; - var pUL = (ulong*)pUB; - var pUI = (uint*)pUB; - var pUS = (ushort*)pUB; - var stringValue = new StringValues(value); - switch (keyLength) + ref byte nameStart = ref MemoryMarshal.GetReference(name); + ref StringValues values = ref Unsafe.AsRef(null); + var flag = 0L; + + // Does the name matched any "known" headers + switch (name.Length) + { + case 2: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfu) == 0x4554u)) + { + flag = 0x2000000000L; + values = ref _headers._TE; + } + break; + case 3: + var firstTerm3 = (Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfu); + if ((firstTerm3 == 0x4e44u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)2) & 0xdfu) == 0x54u)) + { + flag = 0x10000000000L; + values = ref _headers._DNT; + } + else if ((firstTerm3 == 0x4956u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)2) & 0xdfu) == 0x41u)) + { + flag = 0x100L; + values = ref _headers._Via; + } + break; + case 4: + var firstTerm4 = (Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfu); + if ((firstTerm4 == 0x54534f48u)) + { + flag = 0x8000000L; + values = ref _headers._Host; + } + else if ((firstTerm4 == 0x45544144u)) + { + flag = 0x4L; + values = ref _headers._Date; + } + else if ((firstTerm4 == 0x4d4f5246u)) + { + flag = 0x4000000L; + values = ref _headers._From; + } + break; + case 5: + var firstTerm5 = (Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfu); + if ((firstTerm5 == 0x4f4c4c41u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)4) & 0xdfu) == 0x57u)) + { + flag = 0x400L; + values = ref _headers._Allow; + } + else if ((firstTerm5 == 0x474e4152u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)4) & 0xdfu) == 0x45u)) + { + flag = 0x1000000000L; + values = ref _headers._Range; + } + break; + case 6: + var firstTerm6 = (Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfu); + if ((firstTerm6 == 0x45434341u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ushort)))) & 0xdfdfu) == 0x5450u)) + { + flag = 0x80000L; + values = ref _headers._Accept; + } + else if ((firstTerm6 == 0x4b4f4f43u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ushort)))) & 0xdfdfu) == 0x4549u)) + { + flag = 0x1000000L; + values = ref _headers._Cookie; + } + else if ((firstTerm6 == 0x45505845u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ushort)))) & 0xdfdfu) == 0x5443u)) + { + flag = 0x2000000L; + values = ref _headers._Expect; + } + else if ((firstTerm6 == 0x4749524fu) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ushort)))) & 0xdfdfu) == 0x4e49u)) + { + flag = 0x40000000000L; + values = ref _headers._Origin; + } + else if ((firstTerm6 == 0x47415250u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ushort)))) & 0xdfdfu) == 0x414du)) + { + flag = 0x10L; + values = ref _headers._Pragma; + } + break; + case 7: + var firstTerm7 = (Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfu); + if ((firstTerm7 == 0x49505845u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ushort)))) & 0xdfdfu) == 0x4552u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)6) & 0xdfu) == 0x53u)) + { + flag = 0x20000L; + values = ref _headers._Expires; + } + else if ((firstTerm7 == 0x45464552u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ushort)))) & 0xdfdfu) == 0x4552u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)6) & 0xdfu) == 0x52u)) + { + flag = 0x800000000L; + values = ref _headers._Referer; + } + else if ((firstTerm7 == 0x49415254u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ushort)))) & 0xdfdfu) == 0x454cu) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)6) & 0xdfu) == 0x52u)) + { + flag = 0x20L; + values = ref _headers._Trailer; + } + else if ((firstTerm7 == 0x52475055u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ushort)))) & 0xdfdfu) == 0x4441u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)6) & 0xdfu) == 0x45u)) + { + flag = 0x80L; + values = ref _headers._Upgrade; + } + else if ((firstTerm7 == 0x4e524157u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ushort)))) & 0xdfdfu) == 0x4e49u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)6) & 0xdfu) == 0x47u)) + { + flag = 0x200L; + values = ref _headers._Warning; + } + break; + case 8: + var firstTerm8 = (Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfdfffdfdfuL); + if ((firstTerm8 == 0x484354414d2d4649uL)) + { + flag = 0x10000000L; + values = ref _headers._IfMatch; + } + else if ((firstTerm8 == 0x45474e41522d4649uL)) + { + flag = 0x80000000L; + values = ref _headers._IfRange; + } + break; + case 9: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfdfdfdfdfuL) == 0x54414c534e415254uL) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)8) & 0xdfu) == 0x45u)) + { + flag = 0x4000000000L; + values = ref _headers._Translate; + } + break; + case 10: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfdfdfdfdfuL) == 0x495443454e4e4f43uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(4 * sizeof(ushort)))) & 0xdfdfu) == 0x4e4fu)) + { + flag = 0x2L; + values = ref _headers._Connection; + } + else if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfffdfdfdfdfuL) == 0x4547412d52455355uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(4 * sizeof(ushort)))) & 0xdfdfu) == 0x544eu)) + { + flag = 0x8000000000L; + values = ref _headers._UserAgent; + } + else if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfffdfdfdfdfuL) == 0x494c412d5045454buL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(4 * sizeof(ushort)))) & 0xdfdfu) == 0x4556u)) + { + flag = 0x8L; + values = ref _headers._KeepAlive; + } + break; + case 11: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xffdfdfdfdfdfdfdfuL) == 0x2d544e45544e4f43uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(4 * sizeof(ushort)))) & 0xdfdfu) == 0x444du) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)10) & 0xffu) == 0x35u)) + { + flag = 0x8000L; + values = ref _headers._ContentMD5; + } + break; + case 12: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xffdfdfdfdfdfdfdfuL) == 0x2d544e45544e4f43uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x45505954u)) + { + flag = 0x800L; + values = ref _headers._ContentType; + } + else if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfffdfdfdfuL) == 0x57524f462d58414duL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x53445241u)) + { + flag = 0x200000000L; + values = ref _headers._MaxForwards; + } + break; + case 13: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfdfdfdfdfuL) == 0x5a49524f48545541uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x4f495441u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)12) & 0xdfu) == 0x4eu)) + { + flag = 0x800000L; + values = ref _headers._Authorization; + } + else if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfffdfdfdfdfdfuL) == 0x4f432d4548434143uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x4f52544eu) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)12) & 0xdfu) == 0x4cu)) + { + flag = 0x1L; + values = ref _headers._CacheControl; + } + else if (((Unsafe.ReadUnaligned(ref nameStart) & 0xffdfdfdfdfdfdfdfuL) == 0x2d544e45544e4f43uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x474e4152u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)12) & 0xdfu) == 0x45u)) + { + flag = 0x10000L; + values = ref _headers._ContentRange; + } + else if (((Unsafe.ReadUnaligned(ref nameStart) & 0xffdfdfdfdfffdfdfuL) == 0x2d454e4f4e2d4649uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x4354414du) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)12) & 0xdfu) == 0x48u)) + { + flag = 0x40000000L; + values = ref _headers._IfNoneMatch; + } + else if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfffdfdfdfdfuL) == 0x444f4d2d5453414cuL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x45494649u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)12) & 0xdfu) == 0x44u)) + { + flag = 0x40000L; + values = ref _headers._LastModified; + } + break; + case 14: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfffdfdfdfdfdfdfuL) == 0x432d545045434341uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x53524148u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(6 * sizeof(ushort)))) & 0xdfdfu) == 0x5445u)) + { + flag = 0x100000L; + values = ref _headers._AcceptCharset; + } + else if (((Unsafe.ReadUnaligned(ref nameStart) & 0xffdfdfdfdfdfdfdfuL) == 0x2d544e45544e4f43uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x474e454cu) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(6 * sizeof(ushort)))) & 0xdfdfu) == 0x4854u)) + { + AppendContentLength(value); + return; + } + break; + case 15: + var firstTerm15 = (Unsafe.ReadUnaligned(ref nameStart) & 0xdfffdfdfdfdfdfdfuL); + if ((firstTerm15 == 0x452d545045434341uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x444f434eu) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(6 * sizeof(ushort)))) & 0xdfdfu) == 0x4e49u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)14) & 0xdfu) == 0x47u)) + { + flag = 0x200000L; + values = ref _headers._AcceptEncoding; + } + else if ((firstTerm15 == 0x4c2d545045434341uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x55474e41u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(6 * sizeof(ushort)))) & 0xdfdfu) == 0x4741u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)14) & 0xdfu) == 0x45u)) + { + flag = 0x400000L; + values = ref _headers._AcceptLanguage; + } + break; + case 16: + var firstTerm16 = (Unsafe.ReadUnaligned(ref nameStart) & 0xffdfdfdfdfdfdfdfuL); + if ((firstTerm16 == 0x2d544e45544e4f43uL)) + { + if (((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof(ulong))) & 0xdfdfdfdfdfdfdfdfuL) == 0x474e49444f434e45uL)) + { + flag = 0x1000L; + values = ref _headers._ContentEncoding; + } + else if (((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof(ulong))) & 0xdfdfdfdfdfdfdfdfuL) == 0x45474155474e414cuL)) + { + flag = 0x2000L; + values = ref _headers._ContentLanguage; + } + else if (((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof(ulong))) & 0xdfdfdfdfdfdfdfdfuL) == 0x4e4f495441434f4cuL)) + { + flag = 0x4000L; + values = ref _headers._ContentLocation; + } + } + break; + case 17: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfdfffdfdfuL) == 0x4649444f4d2d4649uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof(ulong))) & 0xdfdfdfdfffdfdfdfuL) == 0x434e49532d444549uL) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)16) & 0xdfu) == 0x45u)) + { + flag = 0x20000000L; + values = ref _headers._IfModifiedSince; + } + else if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfdfdfdfdfuL) == 0x524546534e415254uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof(ulong))) & 0xdfdfdfdfdfdfdfffuL) == 0x4e49444f434e452duL) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)16) & 0xdfu) == 0x47u)) + { + flag = 0x40L; + values = ref _headers._TransferEncoding; + } + break; + case 19: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfdfdfdfffdfdfuL) == 0x444f4d4e552d4649uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof(ulong))) & 0xdfdfffdfdfdfdfdfuL) == 0x49532d4445494649uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(8 * sizeof(ushort)))) & 0xdfdfu) == 0x434eu) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)18) & 0xdfu) == 0x45u)) + { + flag = 0x100000000L; + values = ref _headers._IfUnmodifiedSince; + } + else if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfdfffdfdfdfdfdfuL) == 0x55412d59584f5250uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof(ulong))) & 0xdfdfdfdfdfdfdfdfuL) == 0x54415a49524f4854uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(8 * sizeof(ushort)))) & 0xdfdfu) == 0x4f49u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)18) & 0xdfu) == 0x4eu)) + { + flag = 0x400000000L; + values = ref _headers._ProxyAuthorization; + } + break; + case 25: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xffdfdfdfdfdfdfdfuL) == 0x2d45444152475055uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof(ulong))) & 0xdfdfdfdfdfdfdfdfuL) == 0x4552554345534e49uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ulong)))) & 0xdfdfdfdfdfdfdfffuL) == 0x545345555145522duL) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)24) & 0xdfu) == 0x53u)) + { + flag = 0x20000000000L; + values = ref _headers._UpgradeInsecureRequests; + } + break; + case 29: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfffdfdfdfdfdfdfuL) == 0x432d535345434341uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof(ulong))) & 0xdfffdfdfdfdfdfdfuL) == 0x522d4c4f52544e4fuL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ulong)))) & 0xdfffdfdfdfdfdfdfuL) == 0x4d2d545345555145uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(6 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x4f485445u) && ((Unsafe.AddByteOffset(ref nameStart, (IntPtr)28) & 0xdfu) == 0x44u)) + { + flag = 0x80000000000L; + values = ref _headers._AccessControlRequestMethod; + } + break; + case 30: + if (((Unsafe.ReadUnaligned(ref nameStart) & 0xdfffdfdfdfdfdfdfuL) == 0x432d535345434341uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof(ulong))) & 0xdfffdfdfdfdfdfdfuL) == 0x522d4c4f52544e4fuL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(2 * sizeof(ulong)))) & 0xdfffdfdfdfdfdfdfuL) == 0x482d545345555145uL) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(6 * sizeof(uint)))) & 0xdfdfdfdfu) == 0x45444145u) && ((Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)(14 * sizeof(ushort)))) & 0xdfdfu) == 0x5352u)) + { + flag = 0x100000000000L; + values = ref _headers._AccessControlRequestHeaders; + } + break; + } + + if (flag != 0) + { + // Matched a known header + if ((_previousBits & flag) != 0) { - case 10: + // Had a previous string for this header, mark it as used so we don't clear it OnHeadersComplete or consider it if we get a second header + _previousBits ^= flag; + + // We will only reuse this header if there was only one previous header + if (values.Count == 1) + { + var previousValue = values.ToString(); + // Check lengths are the same, then if the bytes were converted to an ascii string if they would be the same. + // We do not consider Utf8 headers for reuse. + if (previousValue.Length == value.Length && + StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, value)) { - if ((((pUL[0] & 16131858542891098079uL) == 5283922227757993795uL) && ((pUS[4] & 57311u) == 20047u))) - { - if ((_bits & 0x2L) != 0) - { - _headers._Connection = AppendValue(_headers._Connection, value); - } - else - { - _bits |= 0x2L; - _headers._Connection = stringValue; - } - return; - } - - if ((((pUL[0] & 16131858680330051551uL) == 4992030374873092949uL) && ((pUS[4] & 57311u) == 21582u))) - { - if ((_bits & 0x8000000000L) != 0) - { - _headers._UserAgent = AppendValue(_headers._UserAgent, value); - } - else - { - _bits |= 0x8000000000L; - _headers._UserAgent = stringValue; - } - return; - } + // The previous string matches what the bytes would convert to, so we will just use that one. + _bits |= flag; + return; } - break; - - case 6: - { - if ((((pUI[0] & 3755991007u) == 1162036033u) && ((pUS[2] & 57311u) == 21584u))) - { - if ((_bits & 0x80000L) != 0) - { - _headers._Accept = AppendValue(_headers._Accept, value); - } - else - { - _bits |= 0x80000L; - _headers._Accept = stringValue; - } - return; - } - } - break; - - case 4: - { - if ((((pUI[0] & 3755991007u) == 1414745928u))) - { - if ((_bits & 0x8000000L) != 0) - { - _headers._Host = AppendValue(_headers._Host, value); - } - else - { - _bits |= 0x8000000L; - _headers._Host = stringValue; - } - return; - } - } - break; + } } - AppendNonPrimaryHeaders(pKeyBytes, keyLength, value); - } - - private unsafe void AppendNonPrimaryHeaders(byte* pKeyBytes, int keyLength, string value) - { - var pUB = pKeyBytes; - var pUL = (ulong*)pUB; - var pUI = (uint*)pUB; - var pUS = (ushort*)pUB; - var stringValue = new StringValues(value); - switch (keyLength) + // We didn't have a previous matching header value, or have already added a header, so get the string for this value. + var valueStr = value.GetAsciiOrUTF8StringNonNullCharacters(); + if ((_bits & flag) == 0) { - case 13: - { - if ((((pUL[0] & 16131893727263186911uL) == 5711458528024281411uL) && ((pUI[2] & 3755991007u) == 1330795598u) && ((pUB[12] & 223u) == 76u))) - { - if ((_bits & 0x1L) != 0) - { - _headers._CacheControl = AppendValue(_headers._CacheControl, value); - } - else - { - _bits |= 0x1L; - _headers._CacheControl = stringValue; - } - return; - } - - if ((((pUL[0] & 18437701552104792031uL) == 3266321689424580419uL) && ((pUI[2] & 3755991007u) == 1196310866u) && ((pUB[12] & 223u) == 69u))) - { - if ((_bits & 0x10000L) != 0) - { - _headers._ContentRange = AppendValue(_headers._ContentRange, value); - } - else - { - _bits |= 0x10000L; - _headers._ContentRange = stringValue; - } - return; - } - - if ((((pUL[0] & 16131858680330051551uL) == 4922237774822850892uL) && ((pUI[2] & 3755991007u) == 1162430025u) && ((pUB[12] & 223u) == 68u))) - { - if ((_bits & 0x40000L) != 0) - { - _headers._LastModified = AppendValue(_headers._LastModified, value); - } - else - { - _bits |= 0x40000L; - _headers._LastModified = stringValue; - } - return; - } - - if ((((pUL[0] & 16131858542891098079uL) == 6505821637182772545uL) && ((pUI[2] & 3755991007u) == 1330205761u) && ((pUB[12] & 223u) == 78u))) - { - if ((_bits & 0x800000L) != 0) - { - _headers._Authorization = AppendValue(_headers._Authorization, value); - } - else - { - _bits |= 0x800000L; - _headers._Authorization = stringValue; - } - return; - } - - if ((((pUL[0] & 18437701552106889183uL) == 3262099607620765257uL) && ((pUI[2] & 3755991007u) == 1129595213u) && ((pUB[12] & 223u) == 72u))) - { - if ((_bits & 0x40000000L) != 0) - { - _headers._IfNoneMatch = AppendValue(_headers._IfNoneMatch, value); - } - else - { - _bits |= 0x40000000L; - _headers._IfNoneMatch = stringValue; - } - return; - } - } - break; - - case 4: - { - if ((((pUI[0] & 3755991007u) == 1163149636u))) - { - if ((_bits & 0x4L) != 0) - { - _headers._Date = AppendValue(_headers._Date, value); - } - else - { - _bits |= 0x4L; - _headers._Date = stringValue; - } - return; - } - - if ((((pUI[0] & 3755991007u) == 1297044038u))) - { - if ((_bits & 0x4000000L) != 0) - { - _headers._From = AppendValue(_headers._From, value); - } - else - { - _bits |= 0x4000000L; - _headers._From = stringValue; - } - return; - } - } - break; - - case 10: - { - if ((((pUL[0] & 16131858680330051551uL) == 5281668125874799947uL) && ((pUS[4] & 57311u) == 17750u))) - { - if ((_bits & 0x8L) != 0) - { - _headers._KeepAlive = AppendValue(_headers._KeepAlive, value); - } - else - { - _bits |= 0x8L; - _headers._KeepAlive = stringValue; - } - return; - } - } - break; - - case 6: - { - if ((((pUI[0] & 3755991007u) == 1195463248u) && ((pUS[2] & 57311u) == 16717u))) - { - if ((_bits & 0x10L) != 0) - { - _headers._Pragma = AppendValue(_headers._Pragma, value); - } - else - { - _bits |= 0x10L; - _headers._Pragma = stringValue; - } - return; - } - - if ((((pUI[0] & 3755991007u) == 1263488835u) && ((pUS[2] & 57311u) == 17737u))) - { - if ((_bits & 0x1000000L) != 0) - { - _headers._Cookie = AppendValue(_headers._Cookie, value); - } - else - { - _bits |= 0x1000000L; - _headers._Cookie = stringValue; - } - return; - } - - if ((((pUI[0] & 3755991007u) == 1162893381u) && ((pUS[2] & 57311u) == 21571u))) - { - if ((_bits & 0x2000000L) != 0) - { - _headers._Expect = AppendValue(_headers._Expect, value); - } - else - { - _bits |= 0x2000000L; - _headers._Expect = stringValue; - } - return; - } - - if ((((pUI[0] & 3755991007u) == 1195987535u) && ((pUS[2] & 57311u) == 20041u))) - { - if ((_bits & 0x10000000000L) != 0) - { - _headers._Origin = AppendValue(_headers._Origin, value); - } - else - { - _bits |= 0x10000000000L; - _headers._Origin = stringValue; - } - return; - } - } - break; - - case 7: - { - if ((((pUI[0] & 3755991007u) == 1229017684u) && ((pUS[2] & 57311u) == 17740u) && ((pUB[6] & 223u) == 82u))) - { - if ((_bits & 0x20L) != 0) - { - _headers._Trailer = AppendValue(_headers._Trailer, value); - } - else - { - _bits |= 0x20L; - _headers._Trailer = stringValue; - } - return; - } - - if ((((pUI[0] & 3755991007u) == 1380405333u) && ((pUS[2] & 57311u) == 17473u) && ((pUB[6] & 223u) == 69u))) - { - if ((_bits & 0x80L) != 0) - { - _headers._Upgrade = AppendValue(_headers._Upgrade, value); - } - else - { - _bits |= 0x80L; - _headers._Upgrade = stringValue; - } - return; - } - - if ((((pUI[0] & 3755991007u) == 1314013527u) && ((pUS[2] & 57311u) == 20041u) && ((pUB[6] & 223u) == 71u))) - { - if ((_bits & 0x200L) != 0) - { - _headers._Warning = AppendValue(_headers._Warning, value); - } - else - { - _bits |= 0x200L; - _headers._Warning = stringValue; - } - return; - } - - if ((((pUI[0] & 3755991007u) == 1230002245u) && ((pUS[2] & 57311u) == 17746u) && ((pUB[6] & 223u) == 83u))) - { - if ((_bits & 0x20000L) != 0) - { - _headers._Expires = AppendValue(_headers._Expires, value); - } - else - { - _bits |= 0x20000L; - _headers._Expires = stringValue; - } - return; - } - - if ((((pUI[0] & 3755991007u) == 1162233170u) && ((pUS[2] & 57311u) == 17746u) && ((pUB[6] & 223u) == 82u))) - { - if ((_bits & 0x800000000L) != 0) - { - _headers._Referer = AppendValue(_headers._Referer, value); - } - else - { - _bits |= 0x800000000L; - _headers._Referer = stringValue; - } - return; - } - } - break; - - case 17: - { - if ((((pUL[0] & 16131858542891098079uL) == 5928221808112259668uL) && ((pUL[1] & 16131858542891098111uL) == 5641115115480565037uL) && ((pUB[16] & 223u) == 71u))) - { - if ((_bits & 0x40L) != 0) - { - _headers._TransferEncoding = AppendValue(_headers._TransferEncoding, value); - } - else - { - _bits |= 0x40L; - _headers._TransferEncoding = stringValue; - } - return; - } - - if ((((pUL[0] & 16131858542893195231uL) == 5064654363342751305uL) && ((pUL[1] & 16131858543427968991uL) == 4849894470315165001uL) && ((pUB[16] & 223u) == 69u))) - { - if ((_bits & 0x20000000L) != 0) - { - _headers._IfModifiedSince = AppendValue(_headers._IfModifiedSince, value); - } - else - { - _bits |= 0x20000000L; - _headers._IfModifiedSince = stringValue; - } - return; - } - } - break; - - case 3: - { - if ((((pUS[0] & 57311u) == 18774u) && ((pUB[2] & 223u) == 65u))) - { - if ((_bits & 0x100L) != 0) - { - _headers._Via = AppendValue(_headers._Via, value); - } - else - { - _bits |= 0x100L; - _headers._Via = stringValue; - } - return; - } - } - break; - - case 5: - { - if ((((pUI[0] & 3755991007u) == 1330400321u) && ((pUB[4] & 223u) == 87u))) - { - if ((_bits & 0x400L) != 0) - { - _headers._Allow = AppendValue(_headers._Allow, value); - } - else - { - _bits |= 0x400L; - _headers._Allow = stringValue; - } - return; - } - - if ((((pUI[0] & 3755991007u) == 1196310866u) && ((pUB[4] & 223u) == 69u))) - { - if ((_bits & 0x1000000000L) != 0) - { - _headers._Range = AppendValue(_headers._Range, value); - } - else - { - _bits |= 0x1000000000L; - _headers._Range = stringValue; - } - return; - } - } - break; - - case 12: - { - if ((((pUL[0] & 18437701552104792031uL) == 3266321689424580419uL) && ((pUI[2] & 3755991007u) == 1162893652u))) - { - if ((_bits & 0x800L) != 0) - { - _headers._ContentType = AppendValue(_headers._ContentType, value); - } - else - { - _bits |= 0x800L; - _headers._ContentType = stringValue; - } - return; - } - - if ((((pUL[0] & 16131858543427968991uL) == 6292178792217067853uL) && ((pUI[2] & 3755991007u) == 1396986433u))) - { - if ((_bits & 0x200000000L) != 0) - { - _headers._MaxForwards = AppendValue(_headers._MaxForwards, value); - } - else - { - _bits |= 0x200000000L; - _headers._MaxForwards = stringValue; - } - return; - } - } - break; - - case 16: - { - if ((((pUL[0] & 18437701552104792031uL) == 3266321689424580419uL) && ((pUL[1] & 16131858542891098079uL) == 5138124782612729413uL))) - { - if ((_bits & 0x1000L) != 0) - { - _headers._ContentEncoding = AppendValue(_headers._ContentEncoding, value); - } - else - { - _bits |= 0x1000L; - _headers._ContentEncoding = stringValue; - } - return; - } - - if ((((pUL[0] & 18437701552104792031uL) == 3266321689424580419uL) && ((pUL[1] & 16131858542891098079uL) == 4992030546487820620uL))) - { - if ((_bits & 0x2000L) != 0) - { - _headers._ContentLanguage = AppendValue(_headers._ContentLanguage, value); - } - else - { - _bits |= 0x2000L; - _headers._ContentLanguage = stringValue; - } - return; - } - - if ((((pUL[0] & 18437701552104792031uL) == 3266321689424580419uL) && ((pUL[1] & 16131858542891098079uL) == 5642809484339531596uL))) - { - if ((_bits & 0x4000L) != 0) - { - _headers._ContentLocation = AppendValue(_headers._ContentLocation, value); - } - else - { - _bits |= 0x4000L; - _headers._ContentLocation = stringValue; - } - return; - } - } - break; - - case 11: - { - if ((((pUL[0] & 18437701552104792031uL) == 3266321689424580419uL) && ((pUS[4] & 57311u) == 17485u) && ((pUB[10] & 255u) == 53u))) - { - if ((_bits & 0x8000L) != 0) - { - _headers._ContentMD5 = AppendValue(_headers._ContentMD5, value); - } - else - { - _bits |= 0x8000L; - _headers._ContentMD5 = stringValue; - } - return; - } - } - break; - - case 14: - { - if ((((pUL[0] & 16140865742145839071uL) == 4840617878229304129uL) && ((pUI[2] & 3755991007u) == 1397899592u) && ((pUS[6] & 57311u) == 21573u))) - { - if ((_bits & 0x100000L) != 0) - { - _headers._AcceptCharset = AppendValue(_headers._AcceptCharset, value); - } - else - { - _bits |= 0x100000L; - _headers._AcceptCharset = stringValue; - } - return; - } - - if ((((pUL[0] & 18437701552104792031uL) == 3266321689424580419uL) && ((pUI[2] & 3755991007u) == 1196311884u) && ((pUS[6] & 57311u) == 18516u))) - { - if (_contentLength.HasValue) - { - BadHttpRequestException.Throw(RequestRejectionReason.MultipleContentLengths); - } - else - { - _contentLength = ParseContentLength(value); - } - return; - } - } - break; - - case 15: - { - if ((((pUL[0] & 16140865742145839071uL) == 4984733066305160001uL) && ((pUI[2] & 3755991007u) == 1146045262u) && ((pUS[6] & 57311u) == 20041u) && ((pUB[14] & 223u) == 71u))) - { - if ((_bits & 0x200000L) != 0) - { - _headers._AcceptEncoding = AppendValue(_headers._AcceptEncoding, value); - } - else - { - _bits |= 0x200000L; - _headers._AcceptEncoding = stringValue; - } - return; - } - - if ((((pUL[0] & 16140865742145839071uL) == 5489136224570655553uL) && ((pUI[2] & 3755991007u) == 1430736449u) && ((pUS[6] & 57311u) == 18241u) && ((pUB[14] & 223u) == 69u))) - { - if ((_bits & 0x400000L) != 0) - { - _headers._AcceptLanguage = AppendValue(_headers._AcceptLanguage, value); - } - else - { - _bits |= 0x400000L; - _headers._AcceptLanguage = stringValue; - } - return; - } - } - break; - - case 8: - { - if ((((pUL[0] & 16131858542893195231uL) == 5207098233614845513uL))) - { - if ((_bits & 0x10000000L) != 0) - { - _headers._IfMatch = AppendValue(_headers._IfMatch, value); - } - else - { - _bits |= 0x10000000L; - _headers._IfMatch = stringValue; - } - return; - } - - if ((((pUL[0] & 16131858542893195231uL) == 4992044754422023753uL))) - { - if ((_bits & 0x80000000L) != 0) - { - _headers._IfRange = AppendValue(_headers._IfRange, value); - } - else - { - _bits |= 0x80000000L; - _headers._IfRange = stringValue; - } - return; - } - } - break; - - case 19: - { - if ((((pUL[0] & 16131858542893195231uL) == 4922237916571059785uL) && ((pUL[1] & 16131893727263186911uL) == 5283616559079179849uL) && ((pUS[8] & 57311u) == 17230u) && ((pUB[18] & 223u) == 69u))) - { - if ((_bits & 0x100000000L) != 0) - { - _headers._IfUnmodifiedSince = AppendValue(_headers._IfUnmodifiedSince, value); - } - else - { - _bits |= 0x100000000L; - _headers._IfUnmodifiedSince = stringValue; - } - return; - } - - if ((((pUL[0] & 16131893727263186911uL) == 6143241228466999888uL) && ((pUL[1] & 16131858542891098079uL) == 6071233043632179284uL) && ((pUS[8] & 57311u) == 20297u) && ((pUB[18] & 223u) == 78u))) - { - if ((_bits & 0x400000000L) != 0) - { - _headers._ProxyAuthorization = AppendValue(_headers._ProxyAuthorization, value); - } - else - { - _bits |= 0x400000000L; - _headers._ProxyAuthorization = stringValue; - } - return; - } - } - break; - - case 2: - { - if ((((pUS[0] & 57311u) == 17748u))) - { - if ((_bits & 0x2000000000L) != 0) - { - _headers._TE = AppendValue(_headers._TE, value); - } - else - { - _bits |= 0x2000000000L; - _headers._TE = stringValue; - } - return; - } - } - break; - - case 9: - { - if ((((pUL[0] & 16131858542891098079uL) == 6071217693351039572uL) && ((pUB[8] & 223u) == 69u))) - { - if ((_bits & 0x4000000000L) != 0) - { - _headers._Translate = AppendValue(_headers._Translate, value); - } - else - { - _bits |= 0x4000000000L; - _headers._Translate = stringValue; - } - return; - } - } - break; - - case 29: - { - if ((((pUL[0] & 16140865742145839071uL) == 4840616791602578241uL) && ((pUL[1] & 16140865742145839071uL) == 5921472988629454415uL) && ((pUL[2] & 16140865742145839071uL) == 5561193831494668613uL) && ((pUI[6] & 3755991007u) == 1330140229u) && ((pUB[28] & 223u) == 68u))) - { - if ((_bits & 0x20000000000L) != 0) - { - _headers._AccessControlRequestMethod = AppendValue(_headers._AccessControlRequestMethod, value); - } - else - { - _bits |= 0x20000000000L; - _headers._AccessControlRequestMethod = stringValue; - } - return; - } - } - break; - - case 30: - { - if ((((pUL[0] & 16140865742145839071uL) == 4840616791602578241uL) && ((pUL[1] & 16140865742145839071uL) == 5921472988629454415uL) && ((pUL[2] & 16140865742145839071uL) == 5200905861305028933uL) && ((pUI[6] & 3755991007u) == 1162101061u) && ((pUS[14] & 57311u) == 21330u))) - { - if ((_bits & 0x40000000000L) != 0) - { - _headers._AccessControlRequestHeaders = AppendValue(_headers._AccessControlRequestHeaders, value); - } - else - { - _bits |= 0x40000000000L; - _headers._AccessControlRequestHeaders = stringValue; - } - return; - } - } - break; + // We didn't already have a header set, so add a new one. + _bits |= flag; + values = new StringValues(valueStr); } - - AppendUnknownHeaders(pKeyBytes, keyLength, value); + else + { + // We already had a header set, so concatenate the new one. + values = AppendValue(values, valueStr); + } + } + else + { + // The header was not one of the "known" headers. + // Convert value to string first, because passing two spans causes 8 bytes stack zeroing in + // this method with rep stosd, which is slower than necessary. + var valueStr = value.GetAsciiOrUTF8StringNonNullCharacters(); + AppendUnknownHeaders(name, valueStr); + } } private struct HeaderReferences @@ -4280,6 +4040,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public StringValues _TE; public StringValues _Translate; public StringValues _UserAgent; + public StringValues _DNT; + public StringValues _UpgradeInsecureRequests; public StringValues _Origin; public StringValues _AccessControlRequestMethod; public StringValues _AccessControlRequestHeaders; @@ -4374,12 +4136,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http case 39: goto HeaderUserAgent; case 40: - goto HeaderOrigin; + goto HeaderDNT; case 41: - goto HeaderAccessControlRequestMethod; + goto HeaderUpgradeInsecureRequests; case 42: - goto HeaderAccessControlRequestHeaders; + goto HeaderOrigin; case 43: + goto HeaderAccessControlRequestMethod; + case 44: + goto HeaderAccessControlRequestHeaders; + case 45: goto HeaderContentLength; default: goto ExtraHeaders; @@ -4665,32 +4431,46 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _next = 40; return true; } - HeaderOrigin: // case 40 + HeaderDNT: // case 40 if ((_bits & 0x10000000000L) != 0) { - _current = new KeyValuePair("Origin", _collection._headers._Origin); + _current = new KeyValuePair("DNT", _collection._headers._DNT); _next = 41; return true; } - HeaderAccessControlRequestMethod: // case 41 + HeaderUpgradeInsecureRequests: // case 41 if ((_bits & 0x20000000000L) != 0) { - _current = new KeyValuePair("Access-Control-Request-Method", _collection._headers._AccessControlRequestMethod); + _current = new KeyValuePair("Upgrade-Insecure-Requests", _collection._headers._UpgradeInsecureRequests); _next = 42; return true; } - HeaderAccessControlRequestHeaders: // case 42 + HeaderOrigin: // case 42 if ((_bits & 0x40000000000L) != 0) { - _current = new KeyValuePair("Access-Control-Request-Headers", _collection._headers._AccessControlRequestHeaders); + _current = new KeyValuePair("Origin", _collection._headers._Origin); _next = 43; return true; } - HeaderContentLength: // case 43 + HeaderAccessControlRequestMethod: // case 43 + if ((_bits & 0x80000000000L) != 0) + { + _current = new KeyValuePair("Access-Control-Request-Method", _collection._headers._AccessControlRequestMethod); + _next = 44; + return true; + } + HeaderAccessControlRequestHeaders: // case 44 + if ((_bits & 0x100000000000L) != 0) + { + _current = new KeyValuePair("Access-Control-Request-Headers", _collection._headers._AccessControlRequestHeaders); + _next = 45; + return true; + } + HeaderContentLength: // case 45 if (_collection._contentLength.HasValue) { _current = new KeyValuePair("Content-Length", HeaderUtilities.FormatNonNegativeInt64(_collection._contentLength.Value)); - _next = 44; + _next = 46; return true; } ExtraHeaders: @@ -4711,8 +4491,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { 13,10,67,97,99,104,101,45,67,111,110,116,114,111,108,58,32,13,10,67,111,110,110,101,99,116,105,111,110,58,32,13,10,68,97,116,101,58,32,13,10,75,101,101,112,45,65,108,105,118,101,58,32,13,10,80,114,97,103,109,97,58,32,13,10,84,114,97,105,108,101,114,58,32,13,10,84,114,97,110,115,102,101,114,45,69,110,99,111,100,105,110,103,58,32,13,10,85,112,103,114,97,100,101,58,32,13,10,86,105,97,58,32,13,10,87,97,114,110,105,110,103,58,32,13,10,65,108,108,111,119,58,32,13,10,67,111,110,116,101,110,116,45,84,121,112,101,58,32,13,10,67,111,110,116,101,110,116,45,69,110,99,111,100,105,110,103,58,32,13,10,67,111,110,116,101,110,116,45,76,97,110,103,117,97,103,101,58,32,13,10,67,111,110,116,101,110,116,45,76,111,99,97,116,105,111,110,58,32,13,10,67,111,110,116,101,110,116,45,77,68,53,58,32,13,10,67,111,110,116,101,110,116,45,82,97,110,103,101,58,32,13,10,69,120,112,105,114,101,115,58,32,13,10,76,97,115,116,45,77,111,100,105,102,105,101,100,58,32,13,10,65,99,99,101,112,116,45,82,97,110,103,101,115,58,32,13,10,65,103,101,58,32,13,10,69,84,97,103,58,32,13,10,76,111,99,97,116,105,111,110,58,32,13,10,80,114,111,120,121,45,65,117,116,104,101,110,116,105,99,97,116,101,58,32,13,10,82,101,116,114,121,45,65,102,116,101,114,58,32,13,10,83,101,114,118,101,114,58,32,13,10,83,101,116,45,67,111,111,107,105,101,58,32,13,10,86,97,114,121,58,32,13,10,87,87,87,45,65,117,116,104,101,110,116,105,99,97,116,101,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,67,114,101,100,101,110,116,105,97,108,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,72,101,97,100,101,114,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,77,101,116,104,111,100,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,79,114,105,103,105,110,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,69,120,112,111,115,101,45,72,101,97,100,101,114,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,77,97,120,45,65,103,101,58,32,13,10,67,111,110,116,101,110,116,45,76,101,110,103,116,104,58,32, }; - - private long _bits = 0; private HeaderReferences _headers; public bool HasConnection => (_bits & 0x2L) != 0; @@ -6980,7 +6758,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return MaybeUnknown?.Remove(key) ?? false; } - protected override void ClearFast() { MaybeUnknown?.Clear(); @@ -8138,7 +7915,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } } while (tempBits != 0); } - private struct HeaderReferences { @@ -8537,8 +8313,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { 13,10,69,84,97,103,58,32, }; - - private long _bits = 0; private HeaderReferences _headers; @@ -8657,7 +8431,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return MaybeUnknown?.Remove(key) ?? false; } - protected override void ClearFast() { MaybeUnknown?.Clear(); @@ -8712,7 +8485,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return true; } - private struct HeaderReferences { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs index f907c81d88..b6944d8021 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs @@ -16,6 +16,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { internal abstract class HttpHeaders : IHeaderDictionary { + protected long _bits = 0; protected long? _contentLength; protected bool _isReadOnly; protected Dictionary MaybeUnknown; diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs index 3010aecc61..d55706d827 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs @@ -241,6 +241,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } done = true; + handler.OnHeadersComplete(); return true; } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs index 8fec2adc03..0503c54930 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs @@ -74,6 +74,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _context = context; ServerOptions = ServiceContext.ServerOptions; + HttpRequestHeaders = new HttpRequestHeaders(reuseHeaderValues: !ServerOptions.DisableStringReuse); HttpResponseControl = this; } @@ -124,8 +125,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public string Scheme { get; set; } public HttpMethod Method { get; set; } public string PathBase { get; set; } + + protected string _parsedPath = null; public string Path { get; set; } + + protected string _parsedQueryString = null; public string QueryString { get; set; } + + protected string _parsedRawTarget = null; public string RawTarget { get; set; } public string HttpVersion @@ -275,7 +282,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public bool HasFlushedHeaders => _requestProcessingStatus == RequestProcessingStatus.HeadersFlushed; - protected HttpRequestHeaders HttpRequestHeaders { get; } = new HttpRequestHeaders(); + protected HttpRequestHeaders HttpRequestHeaders { get; } protected HttpResponseHeaders HttpResponseHeaders { get; } = new HttpResponseHeaders(); @@ -492,9 +499,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { BadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders); } - var valueString = value.GetAsciiOrUTF8StringNonNullCharacters(); - HttpRequestHeaders.Append(name, valueString); + HttpRequestHeaders.Append(name, value); + } + + public void OnHeadersComplete() + { + HttpRequestHeaders.OnHeadersComplete(); } public async Task ProcessRequestsAsync(IHttpApplication application) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs index 823cf6d126..586987ebdf 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Buffers.Text; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -13,6 +14,50 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { internal sealed partial class HttpRequestHeaders : HttpHeaders { + private readonly bool _reuseHeaderValues; + private long _previousBits = 0; + + public HttpRequestHeaders(bool reuseHeaderValues = true) + { + _reuseHeaderValues = reuseHeaderValues; + } + + public void OnHeadersComplete() + { + var bitsToClear = _previousBits & ~_bits; + _previousBits = 0; + + if (bitsToClear != 0) + { + // Some previous headers were not reused or overwritten. + + // While they cannot be accessed by the current request (as they were not supplied by it) + // there is no point in holding on to them, so clear them now, + // to allow them to get collected by the GC. + Clear(bitsToClear); + } + } + + protected override void ClearFast() + { + if (!_reuseHeaderValues) + { + // If we aren't reusing headers clear them all + Clear(_bits); + } + else + { + // If we are reusing headers, store the currently set headers for comparison later + _previousBits = _bits; + } + + // Mark no headers as currently in use + _bits = 0; + // Clear ContentLength and any unknown headers as we will never reuse them + _contentLength = null; + MaybeUnknown?.Clear(); + } + private static long ParseContentLength(string value) { if (!HeaderUtilities.TryParseNonNegativeInt64(value, out var parsed)) @@ -23,34 +68,45 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return parsed; } + [MethodImpl(MethodImplOptions.NoInlining)] + private void AppendContentLength(Span value) + { + if (_contentLength.HasValue) + { + BadHttpRequestException.Throw(RequestRejectionReason.MultipleContentLengths); + } + + if (!Utf8Parser.TryParse(value, out long parsed, out var consumed) || + parsed < 0 || + consumed != value.Length) + { + BadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value.GetAsciiOrUTF8StringNonNullCharacters()); + } + + _contentLength = parsed; + } + [MethodImpl(MethodImplOptions.NoInlining)] private void SetValueUnknown(string key, StringValues value) { Unknown[key] = value; } - public unsafe void Append(Span name, string value) - { - fixed (byte* namePtr = name) - { - Append(namePtr, name.Length, value); - } - } - [MethodImpl(MethodImplOptions.NoInlining)] - private unsafe void AppendUnknownHeaders(byte* pKeyBytes, int keyLength, string value) + private unsafe void AppendUnknownHeaders(Span name, string valueString) { - string key = new string('\0', keyLength); + string key = new string('\0', name.Length); + fixed (byte* pKeyBytes = name) fixed (char* keyBuffer = key) { - if (!StringUtilities.TryGetAsciiString(pKeyBytes, keyBuffer, keyLength)) + if (!StringUtilities.TryGetAsciiString(pKeyBytes, keyBuffer, name.Length)) { BadHttpRequestException.Throw(RequestRejectionReason.InvalidCharactersInHeaderName); } } Unknown.TryGetValue(key, out var existing); - Unknown[key] = AppendValue(existing, value); + Unknown[key] = AppendValue(existing, valueString); } public Enumerator GetEnumerator() diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/IHttpHeadersHandler.cs b/src/Servers/Kestrel/Core/src/Internal/Http/IHttpHeadersHandler.cs index 9a322f0da9..0ed16148b8 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/IHttpHeadersHandler.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/IHttpHeadersHandler.cs @@ -8,5 +8,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public interface IHttpHeadersHandler { void OnHeader(Span name, Span value); + void OnHeadersComplete(); } } \ No newline at end of file diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index 9f42f5545f..fed15bdf83 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -1092,6 +1092,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 } } + public void OnHeadersComplete() + => _currentHeadersStream.OnHeadersComplete(); + private void ValidateHeader(Span name, Span value) { // http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.1 diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/StringUtilities.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/StringUtilities.cs index edc3a8eeed..aea8290b66 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/StringUtilities.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/StringUtilities.cs @@ -2,13 +2,19 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Buffers.Binary; +using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Text; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure { internal class StringUtilities { + [MethodImpl(MethodImplOptions.AggressiveOptimization)] public static unsafe bool TryGetAsciiString(byte* input, char* output, int count) { // Calculate end position @@ -109,6 +115,261 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure return isValid; } + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public unsafe static bool BytesOrdinalEqualsStringAndAscii(string previousValue, Span newValue) + { + // previousValue is a previously materialized string which *must* have already passed validation. + Debug.Assert(IsValidHeaderString(previousValue)); + + // Ascii bytes => Utf-16 chars will be the same length. + // The caller should have already compared lengths before calling this method. + // However; let's double check, and early exit if they are not the same length. + if (previousValue.Length != newValue.Length) + { + // Lengths don't match, so there cannot be an exact ascii conversion between the two. + goto NotEqual; + } + + // Use IntPtr values rather than int, to avoid unnecessary 32 -> 64 movs on 64-bit. + // Unfortunately this means we also need to cast to byte* for comparisons as IntPtr doesn't + // support operator comparisons (e.g. <=, >, etc). + // + // Note: Pointer comparison is unsigned, so we use the compare pattern (offset + length <= count) + // rather than (offset <= count - length) which we'd do with signed comparison to avoid overflow. + // This isn't problematic as we know the maximum length is max string length (from test above) + // which is a signed value so half the size of the unsigned pointer value so we can safely add + // a Vector.Count to it without overflowing. + var count = (IntPtr)newValue.Length; + var offset = (IntPtr)0; + + // Get references to the first byte in the span, and the first char in the string. + ref var bytes = ref MemoryMarshal.GetReference(newValue); + ref var str = ref MemoryMarshal.GetReference(previousValue.AsSpan()); + + do + { + // If Vector not-accelerated or remaining less than vector size + if (!Vector.IsHardwareAccelerated || (byte*)(offset + Vector.Count) > (byte*)count) + { + if (IntPtr.Size == 8) // Use Intrinsic switch for branch elimination + { + // 64-bit: Loop longs by default + while ((byte*)(offset + sizeof(long)) <= (byte*)count) + { + if (!WidenFourAsciiBytesToUtf16AndCompareToChars( + ref Unsafe.Add(ref str, offset), + Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, offset))) || + !WidenFourAsciiBytesToUtf16AndCompareToChars( + ref Unsafe.Add(ref str, offset + 4), + Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, offset + 4)))) + { + goto NotEqual; + } + + offset += sizeof(long); + } + if ((byte*)(offset + sizeof(int)) <= (byte*)count) + { + if (!WidenFourAsciiBytesToUtf16AndCompareToChars( + ref Unsafe.Add(ref str, offset), + Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, offset)))) + { + goto NotEqual; + } + + offset += sizeof(int); + } + } + else + { + // 32-bit: Loop ints by default + while ((byte*)(offset + sizeof(int)) <= (byte*)count) + { + if (!WidenFourAsciiBytesToUtf16AndCompareToChars( + ref Unsafe.Add(ref str, offset), + Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, offset)))) + { + goto NotEqual; + } + + offset += sizeof(int); + } + } + if ((byte*)(offset + sizeof(short)) <= (byte*)count) + { + if (!WidenTwoAsciiBytesToUtf16AndCompareToChars( + ref Unsafe.Add(ref str, offset), + Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, offset)))) + { + goto NotEqual; + } + + offset += sizeof(short); + } + if ((byte*)offset < (byte*)count) + { + var ch = (char)Unsafe.Add(ref bytes, offset); + if (((ch & 0x80) != 0) || Unsafe.Add(ref str, offset) != ch) + { + goto NotEqual; + } + } + + // End of input reached, there are no inequalities via widening; so the input bytes are both ascii + // and a match to the string if it was converted via Encoding.ASCII.GetString(...) + return true; + } + + // Create a comparision vector for all bits being equal + var AllTrue = new Vector(-1); + // do/while as entry condition already checked, remaining length must be Vector.Count or larger. + do + { + // Read a Vector length from the input as bytes + var vector = Unsafe.ReadUnaligned>(ref Unsafe.Add(ref bytes, offset)); + if (!CheckBytesInAsciiRange(vector)) + { + goto NotEqual; + } + // Widen the bytes directly to chars (ushort) as if they were ascii. + // As widening doubles the size we get two vectors back. + Vector.Widen(vector, out var vector0, out var vector1); + // Read two char vectors from the string to perform the match. + var compare0 = Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref str, offset))); + var compare1 = Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref str, offset + Vector.Count))); + + // If the string is not ascii, then the widened bytes cannot match + // as each widened byte element as chars will be in the range 0-255 + // so cannot match any higher unicode values. + + // Compare to our all bits true comparision vector + if (!AllTrue.Equals( + // BitwiseAnd the two equals together + Vector.BitwiseAnd( + // Check equality for the two widened vectors + Vector.Equals(compare0, vector0), + Vector.Equals(compare1, vector1)))) + { + goto NotEqual; + } + + offset += Vector.Count; + } while ((byte*)(offset + Vector.Count) <= (byte*)count); + + // Vector path done, loop back to do non-Vector + // If is a exact multiple of vector size, bail now + } while ((byte*)offset < (byte*)count); + + // If we get here (input is exactly a multiple of Vector length) then there are no inequalities via widening; + // so the input bytes are both ascii and a match to the string if it was converted via Encoding.ASCII.GetString(...) + return true; + NotEqual: + return false; + } + + /// + /// Given a DWORD which represents a buffer of 4 bytes, widens the buffer into 4 WORDs and + /// compares them to the WORD buffer with machine endianness. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + private static bool WidenFourAsciiBytesToUtf16AndCompareToChars(ref char charStart, uint value) + { + if (!AllBytesInUInt32AreAscii(value)) + { + return false; + } + + if (Bmi2.X64.IsSupported) + { + // BMI2 will work regardless of the processor's endianness. + return Unsafe.ReadUnaligned(ref Unsafe.As(ref charStart)) == + Bmi2.X64.ParallelBitDeposit(value, 0x00FF00FF_00FF00FFul); + } + else + { + if (BitConverter.IsLittleEndian) + { + return charStart == (char)(byte)value && + Unsafe.Add(ref charStart, 1) == (char)(byte)(value >> 8) && + Unsafe.Add(ref charStart, 2) == (char)(byte)(value >> 16) && + Unsafe.Add(ref charStart, 3) == (char)(value >> 24); + } + else + { + return Unsafe.Add(ref charStart, 3) == (char)(byte)value && + Unsafe.Add(ref charStart, 2) == (char)(byte)(value >> 8) && + Unsafe.Add(ref charStart, 1) == (char)(byte)(value >> 16) && + charStart == (char)(value >> 24); + } + } + } + + /// + /// Given a WORD which represents a buffer of 2 bytes, widens the buffer into 2 WORDs and + /// compares them to the WORD buffer with machine endianness. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + private static bool WidenTwoAsciiBytesToUtf16AndCompareToChars(ref char charStart, ushort value) + { + if (!AllBytesInUInt16AreAscii(value)) + { + return false; + } + + if (Bmi2.IsSupported) + { + // BMI2 will work regardless of the processor's endianness. + return Unsafe.ReadUnaligned(ref Unsafe.As(ref charStart)) == + Bmi2.ParallelBitDeposit(value, 0x00FF00FFu); + } + else + { + if (BitConverter.IsLittleEndian) + { + return charStart == (char)(byte)value && + Unsafe.Add(ref charStart, 1) == (char)(byte)(value >> 8); + } + else + { + return Unsafe.Add(ref charStart, 1) == (char)(byte)value && + charStart == (char)(byte)(value >> 8); + } + } + } + + /// + /// Returns iff all bytes in are ASCII. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool AllBytesInUInt32AreAscii(uint value) + { + return ((value & 0x80808080u) == 0); + } + + /// + /// Returns iff all bytes in are ASCII. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool AllBytesInUInt16AreAscii(ushort value) + { + return ((value & 0x8080u) == 0); + } + + private unsafe static bool IsValidHeaderString(string value) + { + // Method for Debug.Assert to ensure BytesOrdinalEqualsStringAndAscii + // is not called with an unvalidated string comparitor. + try + { + if (value is null) return false; + new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true).GetByteCount(value); + return !value.Contains('\0'); + } + catch (DecoderFallbackException) { + return false; + } + } + private static readonly char[] s_encode16Chars = "0123456789ABCDEF".ToCharArray(); /// diff --git a/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs b/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs index 3b29d1ee1a..bbe5d30b9a 100644 --- a/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs +++ b/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs @@ -54,6 +54,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core /// public bool AllowSynchronousIO { get; set; } = false; + /// + /// Gets or sets a value that controls whether the string values materialized + /// will be reused across requests; if they match, or if the strings will always be reallocated. + /// + /// + /// Defaults to false. + /// + public bool DisableStringReuse { get; set; } = false; + /// /// Enables the Listen options callback to resolve and use services registered by the application during startup. /// Typically initialized by UseKestrel()"/>. diff --git a/src/Servers/Kestrel/Core/test/AsciiDecoding.cs b/src/Servers/Kestrel/Core/test/AsciiDecoding.cs index 7fa45513d2..128b79fdd0 100644 --- a/src/Servers/Kestrel/Core/test/AsciiDecoding.cs +++ b/src/Servers/Kestrel/Core/test/AsciiDecoding.cs @@ -24,16 +24,28 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests .Concat(byteRange) .ToArray(); - var s = new Span(byteArray).GetAsciiStringNonNullCharacters(); + var span = new Span(byteArray); - Assert.Equal(s.Length, byteArray.Length); - - for (var i = 1; i < byteArray.Length; i++) + for (var i = 0; i <= byteArray.Length; i++) { - var sb = (byte)s[i]; - var b = byteArray[i]; + // Test all the lengths to hit all the different length paths e.g. Vector, long, short, char + Test(span.Slice(i)); + } - Assert.Equal(sb, b); + static void Test(Span asciiBytes) + { + var s = asciiBytes.GetAsciiStringNonNullCharacters(); + + Assert.True(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, asciiBytes)); + Assert.Equal(s.Length, asciiBytes.Length); + + for (var i = 0; i < asciiBytes.Length; i++) + { + var sb = (byte)s[i]; + var b = asciiBytes[i]; + + Assert.Equal(sb, b); + } } } @@ -59,8 +71,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { var byteRange = Enumerable.Range(0, 16384 + 64).Select(x => (byte)((x & 0x7f) | 0x01)).ToArray(); var expectedByteRange = byteRange.Concat(byteRange).ToArray(); - - var s = new Span(expectedByteRange).GetAsciiStringNonNullCharacters(); + + var span = new Span(expectedByteRange); + var s = span.GetAsciiStringNonNullCharacters(); Assert.Equal(expectedByteRange.Length, s.Length); @@ -68,8 +81,74 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { var sb = (byte)((s[i] & 0x7f) | 0x01); var b = expectedByteRange[i]; + } - Assert.Equal(sb, b); + Assert.True(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, span)); + } + + [Fact] + private void DifferentLengthsAreNotEqual() + { + var byteRange = Enumerable.Range(0, 4096).Select(x => (byte)((x & 0x7f) | 0x01)).ToArray(); + var expectedByteRange = byteRange.Concat(byteRange).ToArray(); + + for (var i = 1; i < byteRange.Length; i++) + { + var span = new Span(expectedByteRange); + var s = span.GetAsciiStringNonNullCharacters(); + + Assert.True(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, span)); + + // One off end + Assert.False(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, span.Slice(0, span.Length - 1))); + Assert.False(StringUtilities.BytesOrdinalEqualsStringAndAscii(s.Substring(0, s.Length - 1), span)); + + // One off start + Assert.False(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, span.Slice(1, span.Length - 1))); + Assert.False(StringUtilities.BytesOrdinalEqualsStringAndAscii(s.Substring(1, s.Length - 1), span)); + } + } + + [Fact] + private void AsciiBytesEqualAsciiStrings() + { + var byteRange = Enumerable.Range(1, 127).Select(x => (byte)x); + + var byteArray = byteRange + .Concat(byteRange) + .Concat(byteRange) + .Concat(byteRange) + .Concat(byteRange) + .Concat(byteRange) + .ToArray(); + + var span = new Span(byteArray); + + for (var i = 0; i <= byteArray.Length; i++) + { + // Test all the lengths to hit all the different length paths e.g. Vector, long, short, char + Test(span.Slice(i)); + } + + static void Test(Span asciiBytes) + { + var s = asciiBytes.GetAsciiStringNonNullCharacters(); + + // Should start as equal + Assert.True(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, asciiBytes)); + + for (var i = 0; i < asciiBytes.Length; i++) + { + var b = asciiBytes[i]; + + // Change one byte, ensure is not equal + asciiBytes[i] = (byte)(b + 1); + Assert.False(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, asciiBytes)); + + // Change byte back for next iteration, ensure is equal again + asciiBytes[i] = b; + Assert.True(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, asciiBytes)); + } } } } diff --git a/src/Servers/Kestrel/Core/test/HPackDecoderTests.cs b/src/Servers/Kestrel/Core/test/HPackDecoderTests.cs index 598a7a6ed5..d9318e01e9 100644 --- a/src/Servers/Kestrel/Core/test/HPackDecoderTests.cs +++ b/src/Servers/Kestrel/Core/test/HPackDecoderTests.cs @@ -103,6 +103,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _decodedHeaders[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiStringNonNullCharacters(); } + void IHttpHeadersHandler.OnHeadersComplete() { } + [Fact] public void DecodesIndexedHeaderField_StaticTable() { diff --git a/src/Servers/Kestrel/Core/test/HttpParserTests.cs b/src/Servers/Kestrel/Core/test/HttpParserTests.cs index 825ee085de..0c7abe1b60 100644 --- a/src/Servers/Kestrel/Core/test/HttpParserTests.cs +++ b/src/Servers/Kestrel/Core/test/HttpParserTests.cs @@ -483,6 +483,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Headers[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiStringNonNullCharacters(); } + void IHttpHeadersHandler.OnHeadersComplete() { } + public void OnStartLine(HttpMethod method, HttpVersion version, Span target, Span path, Span query, Span customMethod, bool pathEncoded) { Method = method != HttpMethod.Custom ? HttpUtilities.MethodToString(method) : customMethod.GetAsciiStringNonNullCharacters(); diff --git a/src/Servers/Kestrel/Core/test/HttpRequestHeadersTests.cs b/src/Servers/Kestrel/Core/test/HttpRequestHeadersTests.cs index 1eef7c792c..a7603b9190 100644 --- a/src/Servers/Kestrel/Core/test/HttpRequestHeadersTests.cs +++ b/src/Servers/Kestrel/Core/test/HttpRequestHeadersTests.cs @@ -3,11 +3,13 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.Extensions.Primitives; using Xunit; +using static CodeGenerator.KnownHeaders; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { @@ -307,8 +309,347 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var encoding = Encoding.GetEncoding("iso-8859-1"); var exception = Assert.Throws( - () => headers.Append(encoding.GetBytes(key), "value")); + () => headers.Append(encoding.GetBytes(key), Encoding.ASCII.GetBytes("value"))); Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode); } + + [Theory] + [MemberData(nameof(KnownRequestHeaders))] + public void ValueReuseOnlyWhenAllowed(bool reuseValue, KnownHeader header) + { + const string HeaderValue = "Hello"; + var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue); + + for (var i = 0; i < 6; i++) + { + var prevName = ChangeNameCase(header.Name, variant: i); + var nextName = ChangeNameCase(header.Name, variant: i + 1); + + var values = GetHeaderValues(headers, prevName, nextName, HeaderValue, HeaderValue); + + Assert.Equal(HeaderValue, values.PrevHeaderValue); + Assert.NotSame(HeaderValue, values.PrevHeaderValue); + + Assert.Equal(HeaderValue, values.NextHeaderValue); + Assert.NotSame(HeaderValue, values.NextHeaderValue); + + Assert.Equal(values.PrevHeaderValue, values.NextHeaderValue); + if (reuseValue) + { + // When materalized string is reused previous and new should be the same object + Assert.Same(values.PrevHeaderValue, values.NextHeaderValue); + } + else + { + // When materalized string is not reused previous and new should be the different objects + Assert.NotSame(values.PrevHeaderValue, values.NextHeaderValue); + } + } + } + + [Theory] + [MemberData(nameof(KnownRequestHeaders))] + public void ValueReuseChangedValuesOverwrite(bool reuseValue, KnownHeader header) + { + const string HeaderValue1 = "Hello1"; + const string HeaderValue2 = "Hello2"; + var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue); + + for (var i = 0; i < 6; i++) + { + var prevName = ChangeNameCase(header.Name, variant: i); + var nextName = ChangeNameCase(header.Name, variant: i + 1); + + var values = GetHeaderValues(headers, prevName, nextName, HeaderValue1, HeaderValue2); + + Assert.Equal(HeaderValue1, values.PrevHeaderValue); + Assert.NotSame(HeaderValue1, values.PrevHeaderValue); + + Assert.Equal(HeaderValue2, values.NextHeaderValue); + Assert.NotSame(HeaderValue2, values.NextHeaderValue); + + Assert.NotEqual(values.PrevHeaderValue, values.NextHeaderValue); + } + } + + [Theory] + [MemberData(nameof(KnownRequestHeaders))] + public void ValueReuseMissingValuesClear(bool reuseValue, KnownHeader header) + { + const string HeaderValue1 = "Hello1"; + var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue); + + for (var i = 0; i < 6; i++) + { + var prevName = ChangeNameCase(header.Name, variant: i); + var nextName = ChangeNameCase(header.Name, variant: i + 1); + + var values = GetHeaderValues(headers, prevName, nextName, HeaderValue1, nextValue: null); + + Assert.Equal(HeaderValue1, values.PrevHeaderValue); + Assert.NotSame(HeaderValue1, values.PrevHeaderValue); + + Assert.Equal(string.Empty, values.NextHeaderValue); + + Assert.NotEqual(values.PrevHeaderValue, values.NextHeaderValue); + } + } + + [Theory] + [MemberData(nameof(KnownRequestHeaders))] + public void ValueReuseNeverWhenNotAscii(bool reuseValue, KnownHeader header) + { + const string HeaderValue = "Hello \u03a0"; + + var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue); + + for (var i = 0; i < 6; i++) + { + var prevName = ChangeNameCase(header.Name, variant: i); + var nextName = ChangeNameCase(header.Name, variant: i + 1); + + var values = GetHeaderValues(headers, prevName, nextName, HeaderValue, HeaderValue); + + Assert.Equal(HeaderValue, values.PrevHeaderValue); + Assert.NotSame(HeaderValue, values.PrevHeaderValue); + + Assert.Equal(HeaderValue, values.NextHeaderValue); + Assert.NotSame(HeaderValue, values.NextHeaderValue); + + Assert.Equal(values.PrevHeaderValue, values.NextHeaderValue); + + Assert.NotSame(values.PrevHeaderValue, values.NextHeaderValue); + } + } + + [Theory] + [MemberData(nameof(KnownRequestHeaders))] + public void ValueReuseLatin1NotConfusedForUtf16AndStillRejected(bool reuseValue, KnownHeader header) + { + var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue); + + var headerValue = new char[127]; // 64 + 32 + 16 + 8 + 4 + 2 + 1 + for (var i = 0; i < headerValue.Length; i++) + { + headerValue[i] = 'a'; + } + + for (var i = 0; i < headerValue.Length; i++) + { + // Set non-ascii Latin char that is valid Utf16 when widened; but not a valid utf8 -> utf16 conversion. + headerValue[i] = '\u00a3'; + + for (var mode = 0; mode <= 1; mode++) + { + string headerValueUtf16Latin1CrossOver; + if (mode == 0) + { + // Full length + headerValueUtf16Latin1CrossOver = new string(headerValue); + } + else + { + // Truncated length (to ensure different paths from changing lengths in matching) + headerValueUtf16Latin1CrossOver = new string(headerValue.AsSpan().Slice(0, i + 1)); + } + + headers.Reset(); + + var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan(); + var prevSpan = Encoding.UTF8.GetBytes(headerValueUtf16Latin1CrossOver).AsSpan(); + + headers.Append(headerName, prevSpan); + headers.OnHeadersComplete(); + var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString(); + + Assert.Equal(headerValueUtf16Latin1CrossOver, prevHeaderValue); + Assert.NotSame(headerValueUtf16Latin1CrossOver, prevHeaderValue); + + headers.Reset(); + + Assert.Throws(() => + { + var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan(); + var nextSpan = Encoding.GetEncoding("iso-8859-1").GetBytes(headerValueUtf16Latin1CrossOver).AsSpan(); + + Assert.False(nextSpan.SequenceEqual(Encoding.ASCII.GetBytes(headerValueUtf16Latin1CrossOver))); + + headers.Append(headerName, nextSpan); + }); + } + + // Reset back to Ascii + headerValue[i] = 'a'; + } + } + + [Fact] + public void ValueReuseNeverWhenUnknownHeader() + { + const string HeaderName = "An-Unknown-Header"; + const string HeaderValue = "Hello"; + + var headers = new HttpRequestHeaders(reuseHeaderValues: true); + + for (var i = 0; i < 6; i++) + { + var prevName = ChangeNameCase(HeaderName, variant: i); + var nextName = ChangeNameCase(HeaderName, variant: i + 1); + + var values = GetHeaderValues(headers, prevName, nextName, HeaderValue, HeaderValue); + + Assert.Equal(HeaderValue, values.PrevHeaderValue); + Assert.NotSame(HeaderValue, values.PrevHeaderValue); + + Assert.Equal(HeaderValue, values.NextHeaderValue); + Assert.NotSame(HeaderValue, values.NextHeaderValue); + + Assert.Equal(values.PrevHeaderValue, values.NextHeaderValue); + + Assert.NotSame(values.PrevHeaderValue, values.NextHeaderValue); + } + } + + [Theory] + [MemberData(nameof(KnownRequestHeaders))] + public void ValueReuseEmptyAfterReset(bool reuseValue, KnownHeader header) + { + const string HeaderValue = "Hello"; + + var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue); + var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan(); + var prevSpan = Encoding.UTF8.GetBytes(HeaderValue).AsSpan(); + + headers.Append(headerName, prevSpan); + headers.OnHeadersComplete(); + var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString(); + + Assert.NotNull(prevHeaderValue); + Assert.NotEqual(string.Empty, prevHeaderValue); + Assert.Equal(HeaderValue, prevHeaderValue); + Assert.NotSame(HeaderValue, prevHeaderValue); + Assert.Single(headers); + var count = headers.Count; + Assert.Equal(1, count); + + headers.Reset(); + + // Empty after reset + var nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString(); + + Assert.NotNull(nextHeaderValue); + Assert.Equal(string.Empty, nextHeaderValue); + Assert.NotEqual(HeaderValue, nextHeaderValue); + Assert.Empty(headers); + count = headers.Count; + Assert.Equal(0, count); + + headers.OnHeadersComplete(); + + // Still empty after complete + nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString(); + + Assert.NotNull(nextHeaderValue); + Assert.Equal(string.Empty, nextHeaderValue); + Assert.NotEqual(HeaderValue, nextHeaderValue); + Assert.Empty(headers); + count = headers.Count; + Assert.Equal(0, count); + } + + [Theory] + [MemberData(nameof(KnownRequestHeaders))] + public void MultiValueReuseEmptyAfterReset(bool reuseValue, KnownHeader header) + { + const string HeaderValue1 = "Hello1"; + const string HeaderValue2 = "Hello2"; + + var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue); + var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan(); + var prevSpan1 = Encoding.UTF8.GetBytes(HeaderValue1).AsSpan(); + var prevSpan2 = Encoding.UTF8.GetBytes(HeaderValue2).AsSpan(); + + headers.Append(headerName, prevSpan1); + headers.Append(headerName, prevSpan2); + headers.OnHeadersComplete(); + var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name]; + + Assert.Equal(2, prevHeaderValue.Count); + + Assert.NotEqual(string.Empty, prevHeaderValue.ToString()); + Assert.Single(headers); + var count = headers.Count; + Assert.Equal(1, count); + + headers.Reset(); + + // Empty after reset + var nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString(); + + Assert.NotNull(nextHeaderValue); + Assert.Equal(string.Empty, nextHeaderValue); + Assert.Empty(headers); + count = headers.Count; + Assert.Equal(0, count); + + headers.OnHeadersComplete(); + + // Still empty after complete + nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString(); + + Assert.NotNull(nextHeaderValue); + Assert.Equal(string.Empty, nextHeaderValue); + Assert.Empty(headers); + count = headers.Count; + Assert.Equal(0, count); + } + + private static (string PrevHeaderValue, string NextHeaderValue) GetHeaderValues(HttpRequestHeaders headers, string prevName, string nextName, string prevValue, string nextValue) + { + headers.Reset(); + var headerName = Encoding.ASCII.GetBytes(prevName).AsSpan(); + var prevSpan = Encoding.UTF8.GetBytes(prevValue).AsSpan(); + + headers.Append(headerName, prevSpan); + headers.OnHeadersComplete(); + var prevHeaderValue = ((IHeaderDictionary)headers)[prevName].ToString(); + + headers.Reset(); + + if (nextValue != null) + { + headerName = Encoding.ASCII.GetBytes(prevName).AsSpan(); + var nextSpan = Encoding.UTF8.GetBytes(nextValue).AsSpan(); + headers.Append(headerName, nextSpan); + } + + headers.OnHeadersComplete(); + + var newHeaderValue = ((IHeaderDictionary)headers)[nextName].ToString(); + + return (prevHeaderValue, newHeaderValue); + } + + private static string ChangeNameCase(string name, int variant) + { + switch ((variant / 2) % 3) + { + case 0: + return name; + case 1: + return name.ToLowerInvariant(); + case 2: + return name.ToUpperInvariant(); + } + + // Never reached + Assert.False(true); + return name; + } + + // Content-Length is numeric not a string, so we exclude it from the string reuse tests + public static IEnumerable KnownRequestHeaders => + RequestHeaders.Where(h => h.Name != "Content-Length").Select(h => new object[] { true, h }).Concat( + RequestHeaders.Where(h => h.Name != "Content-Length").Select(h => new object[] { false, h })); } } diff --git a/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj b/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj index 797278050b..b334a87ed9 100644 --- a/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj +++ b/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj @@ -10,6 +10,7 @@ + diff --git a/src/Servers/Kestrel/Core/test/StartLineTests.cs b/src/Servers/Kestrel/Core/test/StartLineTests.cs new file mode 100644 index 0000000000..9b9656fbba --- /dev/null +++ b/src/Servers/Kestrel/Core/test/StartLineTests.cs @@ -0,0 +1,536 @@ +// 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.Buffers; +using System.IO.Pipelines; +using System.Text; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; +using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal; +using Moq; +using Xunit; + +namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests +{ + public class StartLineTests : IDisposable + { + private readonly static IKestrelTrace _trace = Mock.Of(); + + private IDuplexPipe Transport { get; } + private MemoryPool MemoryPool { get; } + private Http1Connection Http1Connection { get; } + private Http1ParsingHandler ParsingHandler {get;} + private IHttpParser Parser { get; } + + [Fact] + public void InOriginForm() + { + var rawTarget = "/path%20with%20spaces?q=123&w=xyzw1"; + var path = "/path with spaces"; + var query = "?q=123&w=xyzw1"; + Http1Connection.Reset(); + // RawTarget, Path, QueryString are null after reset + Assert.Null(Http1Connection.RawTarget); + Assert.Null(Http1Connection.Path); + Assert.Null(Http1Connection.QueryString); + + var ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"POST {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // But not the same as the inputs. + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + Assert.NotSame(path, Http1Connection.Path); + Assert.NotSame(query, Http1Connection.QueryString); + } + + [Fact] + public void InAuthorityForm() + { + var rawTarget = "example.com:1234"; + var path = string.Empty; + var query = string.Empty; + Http1Connection.Reset(); + // RawTarget, Path, QueryString are null after reset + Assert.Null(Http1Connection.RawTarget); + Assert.Null(Http1Connection.Path); + Assert.Null(Http1Connection.QueryString); + + var ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"CONNECT {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // But not the same as the inputs. + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + // Empty strings, so interned and the same. + Assert.Same(path, Http1Connection.Path); + Assert.Same(query, Http1Connection.QueryString); + } + + [Fact] + public void InAbsoluteForm() + { + var rawTarget = "http://localhost/path1?q=123&w=xyzw"; + var path = "/path1"; + var query = "?q=123&w=xyzw"; + Http1Connection.Reset(); + // RawTarget, Path, QueryString are null after reset + Assert.Null(Http1Connection.RawTarget); + Assert.Null(Http1Connection.Path); + Assert.Null(Http1Connection.QueryString); + + var ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"CONNECT {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // But not the same as the inputs. + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + Assert.NotSame(path, Http1Connection.Path); + Assert.NotSame(query, Http1Connection.QueryString); + } + + [Fact] + public void InAsteriskForm() + { + var rawTarget = "*"; + var path = string.Empty; + var query = string.Empty; + Http1Connection.Reset(); + // RawTarget, Path, QueryString are null after reset + Assert.Null(Http1Connection.RawTarget); + Assert.Null(Http1Connection.Path); + Assert.Null(Http1Connection.QueryString); + + var ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"OPTIONS {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // Asterisk is interned string, so the same. + Assert.Same(rawTarget, Http1Connection.RawTarget); + // Empty strings, so interned and the same. + Assert.Same(path, Http1Connection.Path); + Assert.Same(query, Http1Connection.QueryString); + } + + [Fact] + public void DifferentFormsWorkTogether() + { + // InOriginForm + var rawTarget = "/a%20path%20with%20spaces?q=123&w=xyzw12"; + var path = "/a path with spaces"; + var query = "?q=123&w=xyzw12"; + Http1Connection.Reset(); + var ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"POST {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // But not the same as the inputs. + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + Assert.NotSame(path, Http1Connection.Path); + Assert.NotSame(query, Http1Connection.QueryString); + + InAuthorityForm(); + + InOriginForm(); + InAbsoluteForm(); + + InOriginForm(); + InAsteriskForm(); + + InAuthorityForm(); + InAsteriskForm(); + + InAbsoluteForm(); + InAuthorityForm(); + + InAbsoluteForm(); + InAsteriskForm(); + + InAbsoluteForm(); + InAuthorityForm(); + } + + [Theory] + [InlineData("/abs/path", "/abs/path", "")] + [InlineData("/", "/", "")] + [InlineData("/path", "/path", "")] + [InlineData("/?q=123&w=xyz", "/", "?q=123&w=xyz")] + [InlineData("/path?q=123&w=xyz", "/path", "?q=123&w=xyz")] + [InlineData("/path%20with%20space?q=abc%20123", "/path with space", "?q=abc%20123")] + public void OriginForms(string rawTarget, string path, string query) + { + Http1Connection.Reset(); + var ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + var prevRequestUrl = Http1Connection.RawTarget; + var prevPath = Http1Connection.Path; + var prevQuery = Http1Connection.QueryString; + + // Identical requests keep same materialized string values + for (var i = 0; i < 5; i++) + { + Http1Connection.Reset(); + // RawTarget, Path, QueryString are null after reset + Assert.Null(Http1Connection.RawTarget); + Assert.Null(Http1Connection.Path); + Assert.Null(Http1Connection.QueryString); + + // Parser decodes % encoding in place, so we need to recreate the ROS + ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // But not the same as the inputs. + + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + Assert.NotSame(path, Http1Connection.Path); + // string.Empty is used for empty strings, so should be the same. + Assert.True(query.Length == 0 || !ReferenceEquals(query, Http1Connection.QueryString)); + + // However, materalized strings are reused if generated for previous requests. + + Assert.Same(prevRequestUrl, Http1Connection.RawTarget); + Assert.Same(prevPath, Http1Connection.Path); + Assert.Same(prevQuery, Http1Connection.QueryString); + + prevRequestUrl = Http1Connection.RawTarget; + prevPath = Http1Connection.Path; + prevQuery = Http1Connection.QueryString; + } + + // Different OriginForm request changes values + + rawTarget = "/path1?q=123&w=xyzw"; + path = "/path1"; + query = "?q=123&w=xyzw"; + + Http1Connection.Reset(); + ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n")); + Parser.ParseRequestLine(ParsingHandler, ros, out _, out _); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // But not the same as the inputs. + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + Assert.NotSame(path, Http1Connection.Path); + Assert.NotSame(query, Http1Connection.QueryString); + + // Not equal previous request. + Assert.NotEqual(prevRequestUrl, Http1Connection.RawTarget); + Assert.NotEqual(prevPath, Http1Connection.Path); + Assert.NotEqual(prevQuery, Http1Connection.QueryString); + + DifferentFormsWorkTogether(); + } + + [Theory] + [InlineData("http://localhost/abs/path", "/abs/path", "")] + [InlineData("https://localhost/abs/path", "/abs/path", "")] // handles mismatch scheme + [InlineData("https://localhost:22/abs/path", "/abs/path", "")] // handles mismatched ports + [InlineData("https://differenthost/abs/path", "/abs/path", "")] // handles mismatched hostname + [InlineData("http://localhost/", "/", "")] + [InlineData("http://root@contoso.com/path", "/path", "")] + [InlineData("http://root:password@contoso.com/path", "/path", "")] + [InlineData("https://localhost/", "/", "")] + [InlineData("http://localhost", "/", "")] + [InlineData("http://127.0.0.1/", "/", "")] + [InlineData("http://[::1]/", "/", "")] + [InlineData("http://[::1]:8080/", "/", "")] + [InlineData("http://localhost?q=123&w=xyz", "/", "?q=123&w=xyz")] + [InlineData("http://localhost/?q=123&w=xyz", "/", "?q=123&w=xyz")] + [InlineData("http://localhost/path?q=123&w=xyz", "/path", "?q=123&w=xyz")] + [InlineData("http://localhost/path%20with%20space?q=abc%20123", "/path with space", "?q=abc%20123")] + public void AbsoluteForms(string rawTarget, string path, string query) + { + Http1Connection.Reset(); + var ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + var prevRequestUrl = Http1Connection.RawTarget; + var prevPath = Http1Connection.Path; + var prevQuery = Http1Connection.QueryString; + + // Identical requests keep same materialized string values + for (var i = 0; i < 5; i++) + { + Http1Connection.Reset(); + // RawTarget, Path, QueryString are null after reset + Assert.Null(Http1Connection.RawTarget); + Assert.Null(Http1Connection.Path); + Assert.Null(Http1Connection.QueryString); + + ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // But not the same as the inputs. + + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + Assert.NotSame(path, Http1Connection.Path); + // string.Empty is used for empty strings, so should be the same. + Assert.True(query.Length == 0 || !ReferenceEquals(query, Http1Connection.QueryString)); + + // However, materalized strings are reused if generated for previous requests. + + Assert.Same(prevRequestUrl, Http1Connection.RawTarget); + Assert.Same(prevPath, Http1Connection.Path); + Assert.Same(prevQuery, Http1Connection.QueryString); + + prevRequestUrl = Http1Connection.RawTarget; + prevPath = Http1Connection.Path; + prevQuery = Http1Connection.QueryString; + } + + // Different Absolute Form request changes values + + rawTarget = "http://localhost/path1?q=123&w=xyzw"; + path = "/path1"; + query = "?q=123&w=xyzw"; + + Http1Connection.Reset(); + ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n")); + Parser.ParseRequestLine(ParsingHandler, ros, out _, out _); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // But not the same as the inputs. + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + Assert.NotSame(path, Http1Connection.Path); + Assert.NotSame(query, Http1Connection.QueryString); + + // Not equal previous request. + Assert.NotEqual(prevRequestUrl, Http1Connection.RawTarget); + Assert.NotEqual(prevPath, Http1Connection.Path); + Assert.NotEqual(prevQuery, Http1Connection.QueryString); + + DifferentFormsWorkTogether(); + } + + [Fact] + public void AsteriskForms() + { + var rawTarget = "*"; + var path = string.Empty; + var query = string.Empty; + + Http1Connection.Reset(); + var ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"OPTIONS {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + var prevRequestUrl = Http1Connection.RawTarget; + var prevPath = Http1Connection.Path; + var prevQuery = Http1Connection.QueryString; + + // Identical requests keep same materialized string values + for (var i = 0; i < 5; i++) + { + Http1Connection.Reset(); + // RawTarget, Path, QueryString are null after reset + Assert.Null(Http1Connection.RawTarget); + Assert.Null(Http1Connection.Path); + Assert.Null(Http1Connection.QueryString); + + ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"OPTIONS {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // Also same as the inputs (interned strings). + + Assert.Same(rawTarget, Http1Connection.RawTarget); + Assert.Same(path, Http1Connection.Path); + Assert.Same(query, Http1Connection.QueryString); + + // Materalized strings are reused if generated for previous requests. + + Assert.Same(prevRequestUrl, Http1Connection.RawTarget); + Assert.Same(prevPath, Http1Connection.Path); + Assert.Same(prevQuery, Http1Connection.QueryString); + + prevRequestUrl = Http1Connection.RawTarget; + prevPath = Http1Connection.Path; + prevQuery = Http1Connection.QueryString; + } + + // Different request changes values (can't be Astrisk Form as all the same) + rawTarget = "http://localhost/path1?q=123&w=xyzw"; + path = "/path1"; + query = "?q=123&w=xyzw"; + + Http1Connection.Reset(); + ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n")); + Parser.ParseRequestLine(ParsingHandler, ros, out _, out _); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // But not the same as the inputs. + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + Assert.NotSame(path, Http1Connection.Path); + Assert.NotSame(query, Http1Connection.QueryString); + + // Not equal previous request. + Assert.NotEqual(prevRequestUrl, Http1Connection.RawTarget); + Assert.NotEqual(prevPath, Http1Connection.Path); + Assert.NotEqual(prevQuery, Http1Connection.QueryString); + + DifferentFormsWorkTogether(); + } + + [Theory] + [InlineData("localhost", "", "")] + [InlineData("localhost:22", "", "")] // handles mismatched ports + [InlineData("differenthost", "", "")] // handles mismatched hostname + [InlineData("127.0.0.1", "", "")] + [InlineData("[::1]", "", "")] + [InlineData("[::1]:8080", "", "")] + public void AuthorityForms(string rawTarget, string path, string query) + { + Http1Connection.Reset(); + var ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"CONNECT {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + var prevRequestUrl = Http1Connection.RawTarget; + var prevPath = Http1Connection.Path; + var prevQuery = Http1Connection.QueryString; + + // Identical requests keep same materialized string values + for (var i = 0; i < 5; i++) + { + Http1Connection.Reset(); + // RawTarget, Path, QueryString are null after reset + Assert.Null(Http1Connection.RawTarget); + Assert.Null(Http1Connection.Path); + Assert.Null(Http1Connection.QueryString); + + ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"CONNECT {rawTarget} HTTP/1.1\r\n")); + Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _)); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // RawTarget not the same as the input. + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + // Others same as the inputs, empty strings. + Assert.Same(path, Http1Connection.Path); + Assert.Same(query, Http1Connection.QueryString); + + // However, materalized strings are reused if generated for previous requests. + + Assert.Same(prevRequestUrl, Http1Connection.RawTarget); + Assert.Same(prevPath, Http1Connection.Path); + Assert.Same(prevQuery, Http1Connection.QueryString); + + prevRequestUrl = Http1Connection.RawTarget; + prevPath = Http1Connection.Path; + prevQuery = Http1Connection.QueryString; + } + + // Different Authority Form request changes values + rawTarget = "example.org:2345"; + path = ""; + query = ""; + + Http1Connection.Reset(); + ros = new ReadOnlySequence(Encoding.ASCII.GetBytes($"CONNECT {rawTarget} HTTP/1.1\r\n")); + Parser.ParseRequestLine(ParsingHandler, ros, out _, out _); + + // Equal the inputs. + Assert.Equal(rawTarget, Http1Connection.RawTarget); + Assert.Equal(path, Http1Connection.Path); + Assert.Equal(query, Http1Connection.QueryString); + + // But not the same as the inputs. + Assert.NotSame(rawTarget, Http1Connection.RawTarget); + // Empty interned strings + Assert.Same(path, Http1Connection.Path); + Assert.Same(query, Http1Connection.QueryString); + + // Not equal previous request. + Assert.NotEqual(prevRequestUrl, Http1Connection.RawTarget); + + DifferentFormsWorkTogether(); + } + + public StartLineTests() + { + MemoryPool = KestrelMemoryPool.Create(); + var options = new PipeOptions(MemoryPool, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false); + var pair = DuplexPipe.CreateConnectionPair(options, options); + Transport = pair.Transport; + + var serviceContext = new ServiceContext + { + ServerOptions = new KestrelServerOptions(), + Log = _trace, + HttpParser = new HttpParser() + }; + + Http1Connection = new Http1Connection(context: new HttpConnectionContext + { + ServiceContext = serviceContext, + ConnectionFeatures = new FeatureCollection(), + MemoryPool = MemoryPool, + Transport = Transport, + TimeoutControl = new TimeoutControl(timeoutHandler: null) + }); + + Parser = new HttpParser(showErrorDetails: true); + ParsingHandler = new Http1ParsingHandler(Http1Connection); + } + + public void Dispose() + { + Transport.Input.Complete(); + Transport.Output.Complete(); + + MemoryPool.Dispose(); + } + } +} diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Http1ConnectionBenchmark.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Http1ConnectionBenchmark.cs index 27023e0af5..c404a16c27 100644 --- a/src/Servers/Kestrel/perf/Kestrel.Performance/Http1ConnectionBenchmark.cs +++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Http1ConnectionBenchmark.cs @@ -107,6 +107,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance public void OnHeader(Span name, Span value) => RequestHandler.Connection.OnHeader(name, value); + public void OnHeadersComplete() + => RequestHandler.Connection.OnHeadersComplete(); + public void OnStartLine(HttpMethod method, HttpVersion version, Span target, Span path, Span query, Span customMethod, bool pathEncoded) => RequestHandler.Connection.OnStartLine(method, version, target, path, query, customMethod, pathEncoded); } diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/HttpParserBenchmark.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/HttpParserBenchmark.cs index 1fab96121b..a542f905b5 100644 --- a/src/Servers/Kestrel/perf/Kestrel.Performance/HttpParserBenchmark.cs +++ b/src/Servers/Kestrel/perf/Kestrel.Performance/HttpParserBenchmark.cs @@ -72,6 +72,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance { } + public void OnHeadersComplete() + { + } + private struct Adapter : IHttpRequestLineHandler, IHttpHeadersHandler { public HttpParserBenchmark RequestHandler; @@ -84,6 +88,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance public void OnHeader(Span name, Span value) => RequestHandler.OnHeader(name, value); + public void OnHeadersComplete() + => RequestHandler.OnHeadersComplete(); + public void OnStartLine(HttpMethod method, HttpVersion version, Span target, Span path, Span query, Span customMethod, bool pathEncoded) => RequestHandler.OnStartLine(method, version, target, path, query, customMethod, pathEncoded); } diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullParser.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullParser.cs index fc190bbafb..2a3069823a 100644 --- a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullParser.cs +++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullParser.cs @@ -26,6 +26,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance handler.OnHeader(new Span(_hostHeaderName), new Span(_hostHeaderValue)); handler.OnHeader(new Span(_acceptHeaderName), new Span(_acceptHeaderValue)); handler.OnHeader(new Span(_connectionHeaderName), new Span(_connectionHeaderValue)); + handler.OnHeadersComplete(); consumedBytes = 0; consumed = buffer.Start; diff --git a/src/Servers/Kestrel/perf/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs b/src/Servers/Kestrel/perf/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs index 0714143289..898b4c9af8 100644 --- a/src/Servers/Kestrel/perf/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs +++ b/src/Servers/Kestrel/perf/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs @@ -125,6 +125,12 @@ namespace PlatformBenchmarks { } +#if NETCOREAPP3_0 + public void OnHeadersComplete() + { + } +#endif + public async ValueTask OnReadCompletedAsync() { await Writer.FlushAsync(); diff --git a/src/Servers/Kestrel/tools/CodeGenerator/KnownHeaders.cs b/src/Servers/Kestrel/shared/KnownHeaders.cs similarity index 63% rename from src/Servers/Kestrel/tools/CodeGenerator/KnownHeaders.cs rename to src/Servers/Kestrel/shared/KnownHeaders.cs index 7dd1500cca..0899143bc5 100644 --- a/src/Servers/Kestrel/tools/CodeGenerator/KnownHeaders.cs +++ b/src/Servers/Kestrel/shared/KnownHeaders.cs @@ -11,114 +11,11 @@ namespace CodeGenerator { public class KnownHeaders { - static string Each(IEnumerable values, Func formatter) - { - return values.Any() ? values.Select(formatter).Aggregate((a, b) => a + b) : ""; - } + public readonly static KnownHeader[] RequestHeaders; + public readonly static KnownHeader[] ResponseHeaders; + public readonly static KnownHeader[] ResponseTrailers; - static string AppendSwitch(IEnumerable> values, string className) => - $@"var pUL = (ulong*)pUB; - var pUI = (uint*)pUB; - var pUS = (ushort*)pUB; - var stringValue = new StringValues(value); - switch (keyLength) - {{{Each(values, byLength => $@" - case {byLength.Key}: - {{{Each(byLength, header => $@" - if ({header.EqualIgnoreCaseBytes()}) - {{{(header.Identifier == "ContentLength" ? $@" - if (_contentLength.HasValue) - {{ - BadHttpRequestException.Throw(RequestRejectionReason.MultipleContentLengths); - }} - else - {{ - _contentLength = ParseContentLength(value); - }} - return;" : $@" - if ({header.TestBit()}) - {{ - _headers._{header.Identifier} = AppendValue(_headers._{header.Identifier}, value); - }} - else - {{ - {header.SetBit()}; - _headers._{header.Identifier} = stringValue;{(header.EnhancedSetter == false ? "" : $@" - _headers._raw{header.Identifier} = null;")} - }} - return;")} - }} - ")}}} - break; - ")}}}"; - - class KnownHeader - { - public string Name { get; set; } - public int Index { get; set; } - public string Identifier => Name.Replace("-", ""); - - public byte[] Bytes => Encoding.ASCII.GetBytes($"\r\n{Name}: "); - public int BytesOffset { get; set; } - public int BytesCount { get; set; } - public bool ExistenceCheck { get; set; } - public bool FastCount { get; set; } - public bool EnhancedSetter { get; set; } - public bool PrimaryHeader { get; set; } - public string TestBit() => $"(_bits & {"0x" + (1L << Index).ToString("x")}L) != 0"; - public string TestTempBit() => $"(tempBits & {"0x" + (1L << Index).ToString("x")}L) != 0"; - public string TestNotTempBit() => $"(tempBits & ~{"0x" + (1L << Index).ToString("x")}L) == 0"; - public string TestNotBit() => $"(_bits & {"0x" + (1L << Index).ToString("x")}L) == 0"; - public string SetBit() => $"_bits |= {"0x" + (1L << Index).ToString("x")}L"; - public string ClearBit() => $"_bits &= ~{"0x" + (1L << Index).ToString("x")}L"; - - public string EqualIgnoreCaseBytes() - { - var result = ""; - var delim = ""; - var index = 0; - while (index != Name.Length) - { - if (Name.Length - index >= 8) - { - result += delim + Term(Name, index, 8, "pUL", "uL"); - index += 8; - } - else if (Name.Length - index >= 4) - { - result += delim + Term(Name, index, 4, "pUI", "u"); - index += 4; - } - else if (Name.Length - index >= 2) - { - result += delim + Term(Name, index, 2, "pUS", "u"); - index += 2; - } - else - { - result += delim + Term(Name, index, 1, "pUB", "u"); - index += 1; - } - delim = " && "; - } - return $"({result})"; - } - protected string Term(string name, int offset, int count, string array, string suffix) - { - ulong mask = 0; - ulong comp = 0; - for (var scan = 0; scan < count; scan++) - { - var ch = (byte)name[offset + count - scan - 1]; - var isAlpha = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); - comp = (comp << 8) + (ch & (isAlpha ? 0xdfu : 0xffu)); - mask = (mask << 8) + (isAlpha ? 0xdfu : 0xffu); - } - return $"(({array}[{offset / count}] & {mask}{suffix}) == {comp}{suffix})"; - } - } - - public static string GeneratedFile() + static KnownHeaders() { var requestPrimaryHeaders = new[] { @@ -173,7 +70,7 @@ namespace CodeGenerator { "Host" }; - var requestHeaders = commonHeaders.Concat(new[] + RequestHeaders = commonHeaders.Concat(new[] { "Accept", "Accept-Charset", @@ -196,6 +93,8 @@ namespace CodeGenerator "TE", "Translate", "User-Agent", + "DNT", + "Upgrade-Insecure-Requests" }) .Concat(corsRequestHeaders) .Select((header, index) => new KnownHeader @@ -213,8 +112,6 @@ namespace CodeGenerator PrimaryHeader = requestPrimaryHeaders.Contains("Content-Length") }}) .ToArray(); - Debug.Assert(requestHeaders.Length <= 64); - Debug.Assert(requestHeaders.Max(x => x.Index) <= 62); var responseHeadersExistence = new[] { @@ -240,7 +137,7 @@ namespace CodeGenerator "Access-Control-Expose-Headers", "Access-Control-Max-Age", }; - var responseHeaders = commonHeaders.Concat(new[] + ResponseHeaders = commonHeaders.Concat(new[] { "Accept-Ranges", "Age", @@ -271,7 +168,7 @@ namespace CodeGenerator }}) .ToArray(); - var responseTrailers = new[] + ResponseTrailers = new[] { "ETag", } @@ -284,11 +181,359 @@ namespace CodeGenerator PrimaryHeader = responsePrimaryHeaders.Contains(header) }) .ToArray(); + } + + static string Each(IEnumerable values, Func formatter) + { + return values.Any() ? values.Select(formatter).Aggregate((a, b) => a + b) : ""; + } + + static string Each(IEnumerable values, Func formatter) + { + return values.Any() ? values.Select(formatter).Aggregate((a, b) => a + b) : ""; + } + + static string AppendSwitch(IEnumerable> values) => + $@"switch (name.Length) + {{{Each(values, byLength => $@" + case {byLength.Key}:{AppendSwitchSection(byLength.Key, byLength.OrderBy(h => (h.PrimaryHeader ? "_" : "") + h.Name))} + break;")} + }}"; + + static string AppendSwitchSection(int length, IOrderedEnumerable values) + { + var useVarForFirstTerm = values.Count() > 1 && values.Select(h => h.FirstNameIgnoreCaseSegment()).Distinct().Count() == 1; + var firstTermVarExpression = values.Select(h => h.FirstNameIgnoreCaseSegment()).FirstOrDefault(); + var firstTermVar = $"firstTerm{length}"; + + var start = ""; + if (useVarForFirstTerm) + { + start = $@" + var {firstTermVar} = {firstTermVarExpression};"; + } + else + { + firstTermVar = ""; + } + + var groups = values.GroupBy(header => header.EqualIgnoreCaseBytesFirstTerm()); + return start + $@"{Each(groups, (byFirstTerm, i) => $@"{(byFirstTerm.Count() == 1 ? $@"{Each(byFirstTerm, header => $@" + {(i > 0 ? "else " : "")}if ({header.EqualIgnoreCaseBytes(firstTermVar)}) + {{{(header.Identifier == "ContentLength" ? $@" + AppendContentLength(value); + return;" : $@" + flag = {header.FlagBit()}; + values = ref _headers._{header.Identifier};")} + }}")}" : $@" + if ({byFirstTerm.Key.Replace(firstTermVarExpression, firstTermVar)}) + {{{Each(byFirstTerm, (header, i) => $@" + {(i > 0 ? "else " : "")}if ({header.EqualIgnoreCaseBytesSecondTermOnwards()}) + {{{(header.Identifier == "ContentLength" ? $@" + AppendContentLength(value); + return;" : $@" + flag = {header.FlagBit()}; + values = ref _headers._{header.Identifier};")} + }}")} + }}")}")}"; + } + + public class KnownHeader + { + public string Name { get; set; } + public int Index { get; set; } + public string Identifier => Name.Replace("-", ""); + + public byte[] Bytes => Encoding.ASCII.GetBytes($"\r\n{Name}: "); + public int BytesOffset { get; set; } + public int BytesCount { get; set; } + public bool ExistenceCheck { get; set; } + public bool FastCount { get; set; } + public bool EnhancedSetter { get; set; } + public bool PrimaryHeader { get; set; } + public string FlagBit() => $"{"0x" + (1L << Index).ToString("x")}L"; + public string TestBit() => $"(_bits & {"0x" + (1L << Index).ToString("x")}L) != 0"; + public string TestTempBit() => $"(tempBits & {"0x" + (1L << Index).ToString("x")}L) != 0"; + public string TestNotTempBit() => $"(tempBits & ~{"0x" + (1L << Index).ToString("x")}L) == 0"; + public string TestNotBit() => $"(_bits & {"0x" + (1L << Index).ToString("x")}L) == 0"; + public string SetBit() => $"_bits |= {"0x" + (1L << Index).ToString("x")}L"; + public string ClearBit() => $"_bits &= ~{"0x" + (1L << Index).ToString("x")}L"; + + private void GetMaskAndComp(string name, int offset, int count, out ulong mask, out ulong comp) + { + mask = 0; + comp = 0; + for (var scan = 0; scan < count; scan++) + { + var ch = (byte)name[offset + count - scan - 1]; + var isAlpha = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); + comp = (comp << 8) + (ch & (isAlpha ? 0xdfu : 0xffu)); + mask = (mask << 8) + (isAlpha ? 0xdfu : 0xffu); + } + } + + private string NameTerm(string name, int offset, int count, string type, string suffix) + { + GetMaskAndComp(name, offset, count, out var mask, out var comp); + + if (offset == 0) + { + if (type == "byte") + { + return $"(nameStart & 0x{mask:x}{suffix})"; + } + else + { + return $"(Unsafe.ReadUnaligned<{type}>(ref nameStart) & 0x{mask:x}{suffix})"; + } + } + else + { + if (type == "byte") + { + return $"(Unsafe.AddByteOffset(ref nameStart, (IntPtr){offset / count}) & 0x{mask:x}{suffix})"; + } + else if ((offset / count) == 1) + { + return $"(Unsafe.ReadUnaligned<{type}>(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof({type}))) & 0x{mask:x}{suffix})"; + } + else + { + return $"(Unsafe.ReadUnaligned<{type}>(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)({offset / count} * sizeof({type})))) & 0x{mask:x}{suffix})"; + } + } + + } + + private string EqualityTerm(string name, int offset, int count, string type, string suffix) + { + GetMaskAndComp(name, offset, count, out var mask, out var comp); + + return $"0x{comp:x}{suffix}"; + } + + private string Term(string name, int offset, int count, string type, string suffix) + { + GetMaskAndComp(name, offset, count, out var mask, out var comp); + + return $"({NameTerm(name, offset, count, type, suffix)} == {EqualityTerm(name, offset, count, type, suffix)})"; + } + + public string FirstNameIgnoreCaseSegment() + { + var result = ""; + if (Name.Length >= 8) + { + result = NameTerm(Name, 0, 8, "ulong", "uL"); + } + else if (Name.Length >= 4) + { + result = NameTerm(Name, 0, 4, "uint", "u"); + } + else if (Name.Length >= 2) + { + result = NameTerm(Name, 0, 2, "ushort", "u"); + } + else + { + result = NameTerm(Name, 0, 1, "byte", "u"); + } + + return result; + } + + public string EqualIgnoreCaseBytes(string firstTermVar = "") + { + if (!string.IsNullOrEmpty(firstTermVar)) + { + return EqualIgnoreCaseBytesWithVar(firstTermVar); + } + + var result = ""; + var delim = ""; + var index = 0; + while (index != Name.Length) + { + if (Name.Length - index >= 8) + { + result += delim + Term(Name, index, 8, "ulong", "uL"); + index += 8; + } + else if (Name.Length - index >= 4) + { + result += delim + Term(Name, index, 4, "uint", "u"); + index += 4; + } + else if (Name.Length - index >= 2) + { + result += delim + Term(Name, index, 2, "ushort", "u"); + index += 2; + } + else + { + result += delim + Term(Name, index, 1, "byte", "u"); + index += 1; + } + delim = " && "; + } + return result; + + string EqualIgnoreCaseBytesWithVar(string firstTermVar) + { + var result = ""; + var delim = " && "; + var index = 0; + var isFirst = true; + while (index != Name.Length) + { + if (Name.Length - index >= 8) + { + if (isFirst) + { + result = $"({firstTermVar} == {EqualityTerm(Name, index, 8, "ulong", "uL")})"; + } + else + { + result += delim + Term(Name, index, 8, "ulong", "uL"); + } + + index += 8; + } + else if (Name.Length - index >= 4) + { + if (isFirst) + { + result = $"({firstTermVar} == {EqualityTerm(Name, index, 4, "uint", "u")})"; + } + else + { + result += delim + Term(Name, index, 4, "uint", "u"); + } + index += 4; + } + else if (Name.Length - index >= 2) + { + if (isFirst) + { + result = $"({firstTermVar} == {EqualityTerm(Name, index, 2, "ushort", "u")})"; + } + else + { + result += delim + Term(Name, index, 2, "ushort", "u"); + } + index += 2; + } + else + { + if (isFirst) + { + result = $"({firstTermVar} == {EqualityTerm(Name, index, 1, "byte", "u")})"; + } + else + { + result += delim + Term(Name, index, 1, "byte", "u"); + } + index += 1; + } + + isFirst = false; + } + return result; + } + } + + public string EqualIgnoreCaseBytesFirstTerm() + { + var result = ""; + if (Name.Length >= 8) + { + result = Term(Name, 0, 8, "ulong", "uL"); + } + else if (Name.Length >= 4) + { + result = Term(Name, 0, 4, "uint", "u"); + } + else if (Name.Length >= 2) + { + result = Term(Name, 0, 2, "ushort", "u"); + } + else + { + result = Term(Name, 0, 1, "byte", "u"); + } + + return result; + } + + public string EqualIgnoreCaseBytesSecondTermOnwards() + { + var result = ""; + var delim = ""; + var index = 0; + var isFirst = true; + while (index != Name.Length) + { + if (Name.Length - index >= 8) + { + if (!isFirst) + { + result += delim + Term(Name, index, 8, "ulong", "uL"); + } + + index += 8; + } + else if (Name.Length - index >= 4) + { + if (!isFirst) + { + result += delim + Term(Name, index, 4, "uint", "u"); + } + index += 4; + } + else if (Name.Length - index >= 2) + { + if (!isFirst) + { + result += delim + Term(Name, index, 2, "ushort", "u"); + } + index += 2; + } + else + { + if (!isFirst) + { + result += delim + Term(Name, index, 1, "byte", "u"); + } + index += 1; + } + + if (isFirst) + { + isFirst = false; + } + else + { + delim = " && "; + } + } + return result; + } + } + + public static string GeneratedFile() + { + + var requestHeaders = RequestHeaders; + Debug.Assert(requestHeaders.Length <= 64); + Debug.Assert(requestHeaders.Max(x => x.Index) <= 62); // 63 for responseHeaders as it steals one bit for Content-Length in CopyTo(ref MemoryPoolIterator output) + var responseHeaders = ResponseHeaders; Debug.Assert(responseHeaders.Length <= 63); Debug.Assert(responseHeaders.Count(x => x.Index == 63) == 1); + var responseTrailers = ResponseTrailers; + var loops = new[] { new @@ -331,8 +576,10 @@ using System.Collections.Generic; using System.Buffers; using System.IO.Pipelines; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using Microsoft.Extensions.Primitives; using Microsoft.Net.Http.Headers; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http {{ @@ -345,8 +592,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http {Each(loop.Bytes, b => $"{b},")} }};" : "")} - - private long _bits = 0; private HeaderReferences _headers; {Each(loop.Headers.Where(header => header.ExistenceCheck), header => $@" public bool Has{header.Identifier} => {header.TestBit()};")} @@ -510,8 +755,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return MaybeUnknown?.Remove(key) ?? false; }} - - protected override void ClearFast() +{(loop.ClassName != "HttpRequestHeaders" ? + $@" protected override void ClearFast() {{ MaybeUnknown?.Clear(); _contentLength = null; @@ -534,7 +779,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http }} ")} }} - +" : +$@" private void Clear(long bitsToClear) + {{ + var tempBits = bitsToClear; + {Each(loop.Headers.Where(header => header.Identifier != "ContentLength").OrderBy(h => !h.PrimaryHeader), header => $@" + if ({header.TestTempBit()}) + {{ + _headers._{header.Identifier} = default(StringValues); + if({header.TestNotTempBit()}) + {{ + return; + }} + tempBits &= ~{"0x" + (1L << header.Index).ToString("x")}L; + }} + ")} + }} +")} protected override bool CopyToFast(KeyValuePair[] array, int arrayIndex) {{ if (arrayIndex < 0) @@ -625,22 +886,63 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http }} }} }} while (tempBits != 0); - }}" : "")} - {(loop.ClassName == "HttpRequestHeaders" ? $@" - public unsafe void Append(byte* pKeyBytes, int keyLength, string value) + }}" : "")}{(loop.ClassName == "HttpRequestHeaders" ? $@" + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public unsafe void Append(Span name, Span value) {{ - var pUB = pKeyBytes; - {AppendSwitch(loop.Headers.Where(h => h.PrimaryHeader).GroupBy(x => x.Name.Length), loop.ClassName)} + ref byte nameStart = ref MemoryMarshal.GetReference(name); + ref StringValues values = ref Unsafe.AsRef(null); + var flag = 0L; - AppendNonPrimaryHeaders(pKeyBytes, keyLength, value); - }} + // Does the name matched any ""known"" headers + {AppendSwitch(loop.Headers.GroupBy(x => x.Name.Length).OrderBy(x => x.Key))} - private unsafe void AppendNonPrimaryHeaders(byte* pKeyBytes, int keyLength, string value) - {{ - var pUB = pKeyBytes; - {AppendSwitch(loop.Headers.Where(h => !h.PrimaryHeader).GroupBy(x => x.Name.Length), loop.ClassName)} + if (flag != 0) + {{ + // Matched a known header + if ((_previousBits & flag) != 0) + {{ + // Had a previous string for this header, mark it as used so we don't clear it OnHeadersComplete or consider it if we get a second header + _previousBits ^= flag; - AppendUnknownHeaders(pKeyBytes, keyLength, value); + // We will only reuse this header if there was only one previous header + if (values.Count == 1) + {{ + var previousValue = values.ToString(); + // Check lengths are the same, then if the bytes were converted to an ascii string if they would be the same. + // We do not consider Utf8 headers for reuse. + if (previousValue.Length == value.Length && + StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, value)) + {{ + // The previous string matches what the bytes would convert to, so we will just use that one. + _bits |= flag; + return; + }} + }} + }} + + // We didn't have a previous matching header value, or have already added a header, so get the string for this value. + var valueStr = value.GetAsciiOrUTF8StringNonNullCharacters(); + if ((_bits & flag) == 0) + {{ + // We didn't already have a header set, so add a new one. + _bits |= flag; + values = new StringValues(valueStr); + }} + else + {{ + // We already had a header set, so concatenate the new one. + values = AppendValue(values, valueStr); + }} + }} + else + {{ + // The header was not one of the ""known"" headers. + // Convert value to string first, because passing two spans causes 8 bytes stack zeroing in + // this method with rep stosd, which is slower than necessary. + var valueStr = value.GetAsciiOrUTF8StringNonNullCharacters(); + AppendUnknownHeaders(name, valueStr); + }} }}" : "")} private struct HeaderReferences diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs index f1a3b215a0..6752e74e3b 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs @@ -406,6 +406,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _decodedHeaders[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiOrUTF8StringNonNullCharacters(); } + void IHttpHeadersHandler.OnHeadersComplete() { } + protected void CreateConnection() { var limits = _serviceContext.ServerOptions.Limits; diff --git a/src/Servers/Kestrel/tools/CodeGenerator/CodeGenerator.csproj b/src/Servers/Kestrel/tools/CodeGenerator/CodeGenerator.csproj index e0bd7e6ee8..afb106a5cf 100644 --- a/src/Servers/Kestrel/tools/CodeGenerator/CodeGenerator.csproj +++ b/src/Servers/Kestrel/tools/CodeGenerator/CodeGenerator.csproj @@ -7,6 +7,10 @@ true + + + + From 269c253769f261c0cd755394e5f08354c86fdf84 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 9 Apr 2019 08:21:01 -0700 Subject: [PATCH 08/19] Revert "Use new Fedora queue (#9178)" (#9186) --- eng/targets/Helix.Common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/targets/Helix.Common.props b/eng/targets/Helix.Common.props index 903acfb4f5..8c335657a0 100644 --- a/eng/targets/Helix.Common.props +++ b/eng/targets/Helix.Common.props @@ -20,7 +20,7 @@ - + From a7acbaf7bc86f4a06b8affc867de9d30ca2491f3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 9 Apr 2019 08:34:25 -0700 Subject: [PATCH 09/19] [master] Update dependencies from 2 repositories (#9199) * Update dependencies from https://github.com/aspnet/EntityFrameworkCore build 20190408.4 - Microsoft.EntityFrameworkCore.Tools - 3.0.0-preview5.19208.4 - Microsoft.EntityFrameworkCore.SqlServer - 3.0.0-preview5.19208.4 - dotnet-ef - 3.0.0-preview5.19208.4 - Microsoft.EntityFrameworkCore - 3.0.0-preview5.19208.4 - Microsoft.EntityFrameworkCore.InMemory - 3.0.0-preview5.19208.4 - Microsoft.EntityFrameworkCore.Relational - 3.0.0-preview5.19208.4 - Microsoft.EntityFrameworkCore.Sqlite - 3.0.0-preview5.19208.4 Dependency coherency updates - Microsoft.AspNetCore.Analyzer.Testing - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.AspNetCore.BenchmarkRunner.Sources - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.ActivatorUtilities.Sources - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Caching.Abstractions - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Caching.Memory - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Caching.SqlServer - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Caching.StackExchangeRedis - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.CommandLineUtils.Sources - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.Abstractions - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.AzureKeyVault - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.Binder - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.CommandLine - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.EnvironmentVariables - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.FileExtensions - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.Ini - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.Json - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.KeyPerFile - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.UserSecrets - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration.Xml - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Configuration - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.DependencyInjection.Abstractions - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.DependencyInjection - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.DiagnosticAdapter - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Diagnostics.HealthChecks - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.FileProviders.Abstractions - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.FileProviders.Composite - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.FileProviders.Embedded - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.FileProviders.Physical - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.FileSystemGlobbing - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.HashCodeCombiner.Sources - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Hosting.Abstractions - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Hosting - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.HostFactoryResolver.Sources - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Http - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Localization.Abstractions - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Localization - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.Abstractions - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.AzureAppServices - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.Configuration - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.Console - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.Debug - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.EventSource - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.TraceSource - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Logging.Testing - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.ObjectPool - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Options.ConfigurationExtensions - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Options.DataAnnotations - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Options - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.ParameterDefaultValue.Sources - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.Primitives - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.TypeNameHelper.Sources - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.ValueStopwatch.Sources - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.WebEncoders - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Internal.Extensions.Refs - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.JSInterop - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Mono.WebAssembly.Interop - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Bcl.Json.Sources - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.CSharp - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Win32.Registry - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.ComponentModel.Annotations - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Data.SqlClient - 4.7.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Diagnostics.EventLog - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.IO.Pipelines - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Net.Http.WinHttpHandler - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Net.WebSockets.WebSocketProtocol - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Reflection.Metadata - 1.7.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Runtime.CompilerServices.Unsafe - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Security.Cryptography.Cng - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Security.Cryptography.Pkcs - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Security.Cryptography.Xml - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Security.Permissions - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Security.Principal.Windows - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.ServiceProcess.ServiceController - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Text.Encodings.Web - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - System.Threading.Channels - 4.6.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.Extensions.DependencyModel - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.NETCore.Platforms - 3.0.0-preview5.19206.5 (parent: Microsoft.NETCore.App) - Microsoft.NETCore.App - 3.0.0-preview5-27606-09 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.Logging - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Internal.AspNetCore.Analyzers - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) - Microsoft.AspNetCore.Testing - 3.0.0-preview4.19207.2 (parent: Microsoft.EntityFrameworkCore) * Update dependencies from https://github.com/aspnet/AspNetCore-Tooling build 20190408.6 - Microsoft.NET.Sdk.Razor - 3.0.0-preview5.19208.6 - Microsoft.CodeAnalysis.Razor - 3.0.0-preview5.19208.6 - Microsoft.AspNetCore.Razor.Language - 3.0.0-preview5.19208.6 - Microsoft.AspNetCore.Mvc.Razor.Extensions - 3.0.0-preview5.19208.6 --- eng/Version.Details.xml | 372 ++++++++++++++++++++-------------------- eng/Versions.props | 186 ++++++++++---------- 2 files changed, 279 insertions(+), 279 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2417483a7e..21d971ca51 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -9,384 +9,384 @@ --> - + https://github.com/aspnet/AspNetCore-Tooling - 3c92785f600a5aeb06f0c26264727270865b5a3d + beebdf43f54ec82e06a48b99812d9740cb9f38cf - + https://github.com/aspnet/AspNetCore-Tooling - 3c92785f600a5aeb06f0c26264727270865b5a3d + beebdf43f54ec82e06a48b99812d9740cb9f38cf - + https://github.com/aspnet/AspNetCore-Tooling - 3c92785f600a5aeb06f0c26264727270865b5a3d + beebdf43f54ec82e06a48b99812d9740cb9f38cf - + https://github.com/aspnet/AspNetCore-Tooling - 3c92785f600a5aeb06f0c26264727270865b5a3d + beebdf43f54ec82e06a48b99812d9740cb9f38cf - + https://github.com/aspnet/EntityFrameworkCore - 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 + 243ea5080c4d7eefc96797134c9e10b2fa75f835 - + https://github.com/aspnet/EntityFrameworkCore - 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 + 243ea5080c4d7eefc96797134c9e10b2fa75f835 - + https://github.com/aspnet/EntityFrameworkCore - 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 + 243ea5080c4d7eefc96797134c9e10b2fa75f835 - + https://github.com/aspnet/EntityFrameworkCore - 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 + 243ea5080c4d7eefc96797134c9e10b2fa75f835 - + https://github.com/aspnet/EntityFrameworkCore - 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 + 243ea5080c4d7eefc96797134c9e10b2fa75f835 - + https://github.com/aspnet/EntityFrameworkCore - 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 + 243ea5080c4d7eefc96797134c9e10b2fa75f835 - + https://github.com/aspnet/EntityFrameworkCore - 5c3860f3a9f880b1d4767e6d19ec9ff909b1cda6 + 243ea5080c4d7eefc96797134c9e10b2fa75f835 - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/dotnet/core-setup - ccdc90de5f757c56e13bf5c095ee5d2aa8ca1aa4 + 42a6743d709c3d74f1cb7a2af8740e3183a022f4 - + https://github.com/dotnet/core-setup - ccdc90de5f757c56e13bf5c095ee5d2aa8ca1aa4 + 42a6743d709c3d74f1cb7a2af8740e3183a022f4 - + https://github.com/dotnet/corefx - 35249a0072b41a89ce1542deacb2611c2393dec0 + 81fe62442228cb26bd0d95ceec3e0a3b74bde0a2 - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b https://github.com/dotnet/arcade b1f9e12fe3ee71c48ea60b15968745850ac0a4a7 - + https://github.com/aspnet/Extensions - 4b123acda735f7a7e20b62d9cfafabe5707290a0 + 8749bf15c942cb1e4c9c01f3e7a9b2af84293d4b diff --git a/eng/Versions.props b/eng/Versions.props index a9cc55bc7e..b4a736e4b5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -19,104 +19,104 @@ 1.0.0-beta.19207.1 - 3.0.0-preview5-27606-01 - 3.0.0-preview5-27606-01 + 3.0.0-preview5-27606-09 + 3.0.0-preview5-27606-09 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.7.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 1.7.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 - 4.6.0-preview5.19205.9 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.7.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 1.7.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 + 4.6.0-preview5.19206.5 - 3.0.0-preview5.19205.9 + 3.0.0-preview5.19206.5 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 - 3.0.0-preview4.19206.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 + 3.0.0-preview4.19207.2 - 3.0.0-preview4.19207.2 - 3.0.0-preview4.19207.2 - 3.0.0-preview4.19207.2 - 3.0.0-preview4.19207.2 - 3.0.0-preview4.19207.2 - 3.0.0-preview4.19207.2 - 3.0.0-preview4.19207.2 + 3.0.0-preview5.19208.4 + 3.0.0-preview5.19208.4 + 3.0.0-preview5.19208.4 + 3.0.0-preview5.19208.4 + 3.0.0-preview5.19208.4 + 3.0.0-preview5.19208.4 + 3.0.0-preview5.19208.4 - 3.0.0-preview4.19207.2 - 3.0.0-preview4.19207.2 - 3.0.0-preview4.19207.2 - 3.0.0-preview4.19207.2 + 3.0.0-preview5.19208.6 + 3.0.0-preview5.19208.6 + 3.0.0-preview5.19208.6 + 3.0.0-preview5.19208.6 - 1.0.0-beta.19207.1 + 1.0.0-beta.19209.1 3.0.0-preview5-27606-09 3.0.0-preview5-27606-09 From 4134d02dab44717d049d1e55abb473ec04ddf47d Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Tue, 9 Apr 2019 18:52:04 +0100 Subject: [PATCH 11/19] Fix Platform benchmark (#9204) --- .../BenchmarkApplication.HttpConnection.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Servers/Kestrel/perf/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs b/src/Servers/Kestrel/perf/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs index 898b4c9af8..1d5cc6f55d 100644 --- a/src/Servers/Kestrel/perf/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs +++ b/src/Servers/Kestrel/perf/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs @@ -181,6 +181,11 @@ namespace PlatformBenchmarks public void OnStartLine(HttpMethod method, HttpVersion version, Span target, Span path, Span query, Span customMethod, bool pathEncoded) => RequestHandler.OnStartLine(method, version, target, path, query, customMethod, pathEncoded); + +#if NETCOREAPP3_0 + public void OnHeadersComplete() + => RequestHandler.OnHeadersComplete(); +#endif } } From cacf9aa9f144c598cda6991f92fed27565890f9e Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 9 Apr 2019 12:47:27 -0700 Subject: [PATCH 12/19] Fix folder version for global module to only have 3 numbers (#9211) --- .../ANCMIISExpressV2/ancm_iis_expressv2.wxs | 4 ++-- .../AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs | 4 ++-- .../Windows/AspNetCoreModule-Setup/Directory.Build.props | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs index a5ed751f14..49bae9932b 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs +++ b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs @@ -173,7 +173,7 @@ - + - + - + - + $(BUILD_MINOR) - 1$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(BUILD_MAJOR).0 + 1$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(BUILD_MAJOR) + $(ANCMFolderVersion).0 @@ -31,7 +32,7 @@ <_ServerIISBasePath>$(RepositoryRoot)\src\Servers\IIS\ BLDVERMAJOR=$(BLDVERMAJOR);BLDVERMINOR=$(BLDVERMINOR);BLDNUMMAJOR=$(BLDNUMMAJOR);BLDNUMMINOR=$(BLDNUMMINOR);$(DefineConstants) - ANCMMsiVersion=$(ANCMMsiVersion);ANCMOutOfProcessNugetPackageHandlerVersion=$(ANCMOutOfProcessNugetPackageHandlerVersion);$(DefineConstants) + ANCMMsiVersion=$(ANCMMsiVersion);ANCMFolderVersion=$(ANCMFolderVersion);ANCMOutOfProcessNugetPackageHandlerVersion=$(ANCMOutOfProcessNugetPackageHandlerVersion);$(DefineConstants) AspNetCoreSchemaPath=$(_ServerIISBasePath)AspNetCoreModuleV2\AspNetCore\aspnetcore_schema_v2.xml; AspNetCoreMofPath=$(_ServerIISBasePath)AspNetCoreModuleV2\AspNetCore\ancm.mof; From 454ac1544359aa51aa3dc1f1a5e92a59b7ca615e Mon Sep 17 00:00:00 2001 From: Mikael Mengistu Date: Tue, 9 Apr 2019 12:56:07 -0700 Subject: [PATCH 13/19] Expose Connection Id in SignalR TS Client (#9188) --- .../clients/ts/FunctionalTests/TestHub.cs | 5 ++ .../FunctionalTests/ts/HubConnectionTests.ts | 76 +++++++++++++++++++ .../clients/ts/signalr/src/HttpConnection.ts | 1 + .../clients/ts/signalr/src/HubConnection.ts | 7 ++ 4 files changed, 89 insertions(+) diff --git a/src/SignalR/clients/ts/FunctionalTests/TestHub.cs b/src/SignalR/clients/ts/FunctionalTests/TestHub.cs index 980a04653a..7853595e55 100644 --- a/src/SignalR/clients/ts/FunctionalTests/TestHub.cs +++ b/src/SignalR/clients/ts/FunctionalTests/TestHub.cs @@ -34,6 +34,11 @@ namespace FunctionalTests return message; } + public string GetCallerConnectionId() + { + return Context.ConnectionId; + } + public int GetNumRedirects() { return int.Parse(Context.GetHttpContext().Request.Query["numRedirects"]); diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts index 7bd557f4fe..84278f0f14 100644 --- a/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts +++ b/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts @@ -782,6 +782,9 @@ describe("hubConnection", () => { expect(newConnectionId).not.toBe(initialConnectionId); + const serverConnectionId = await hubConnection.invoke("GetCallerConnectionId"); + expect(newConnectionId).toBe(serverConnectionId); + const postReconnectRedirects = await hubConnection.invoke("GetNumRedirects"); expect(postReconnectRedirects).toBeGreaterThan(preReconnectRedirects); @@ -838,6 +841,79 @@ describe("hubConnection", () => { } }); + it("connection id matches server side connection id", async (done) => { + try { + const reconnectingPromise = new PromiseSource(); + const reconnectedPromise = new PromiseSource(); + const hubConnection = getConnectionBuilder(undefined, TESTHUB_REDIRECT_ENDPOINT_URL) + .withAutomaticReconnect() + .build(); + + hubConnection.onreconnecting(() => { + reconnectingPromise.resolve(); + }); + + hubConnection.onreconnected((connectionId?) => { + reconnectedPromise.resolve(connectionId); + }); + + expect(hubConnection.connectionId).toBeNull(); + + await hubConnection.start(); + + expect(hubConnection.connectionId).not.toBeNull(); + let serverConnectionId = await hubConnection.invoke("GetCallerConnectionId"); + expect(hubConnection.connectionId).toBe(serverConnectionId); + + const initialConnectionId = hubConnection.connectionId!; + + // Induce reconnect + (hubConnection as any).serverTimeout(); + + await reconnectingPromise; + const newConnectionId = await reconnectedPromise; + + expect(newConnectionId).not.toBe(initialConnectionId); + + serverConnectionId = await hubConnection.invoke("GetCallerConnectionId"); + expect(newConnectionId).toBe(serverConnectionId); + + await hubConnection.stop(); + expect(hubConnection.connectionId).toBeNull(); + + done(); + } catch (err) { + fail(err); + done(); + } + }); + + it("connection id is alwys null is negotiation is skipped", async (done) => { + try { + const hubConnection = getConnectionBuilder( + HttpTransportType.WebSockets, + undefined, + { skipNegotiation: true }, + ) + .build(); + + expect(hubConnection.connectionId).toBeNull(); + + await hubConnection.start(); + + expect(hubConnection.connectionId).toBeNull(); + + await hubConnection.stop(); + + expect(hubConnection.connectionId).toBeNull(); + + done(); + } catch (err) { + fail(err); + done(); + } + }); + if (typeof EventSource !== "undefined") { it("allows Server-Sent Events when negotiating for JSON protocol", async (done) => { const hubConnection = getConnectionBuilder(undefined, TESTHUB_NOWEBSOCKETS_ENDPOINT_URL) diff --git a/src/SignalR/clients/ts/signalr/src/HttpConnection.ts b/src/SignalR/clients/ts/signalr/src/HttpConnection.ts index cff6b0172f..729d01cc32 100644 --- a/src/SignalR/clients/ts/signalr/src/HttpConnection.ts +++ b/src/SignalR/clients/ts/signalr/src/HttpConnection.ts @@ -450,6 +450,7 @@ export class HttpConnection implements IConnection { this.logger.log(LogLevel.Information, "Connection disconnected."); } + this.connectionId = undefined; this.connectionState = ConnectionState.Disconnected; if (this.onclose && this.connectionStarted) { diff --git a/src/SignalR/clients/ts/signalr/src/HubConnection.ts b/src/SignalR/clients/ts/signalr/src/HubConnection.ts index baab33767d..b9421e025d 100644 --- a/src/SignalR/clients/ts/signalr/src/HubConnection.ts +++ b/src/SignalR/clients/ts/signalr/src/HubConnection.ts @@ -120,6 +120,13 @@ export class HubConnection { return this.connectionState; } + /** Represents the connection id of the {@link HubConnection} on the server. The connection id will be null when the connection is either + * in the disconnected state or if the negotiation step was skipped. + */ + get connectionId(): string | null { + return this.connection ? (this.connection.connectionId || null) : null; + } + /** Starts the connection. * * @returns {Promise} A Promise that resolves when the connection has been successfully established, or rejects with an error. From 212ba91a5c1eaf51c0205fc4422a92c027ffeaec Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 9 Apr 2019 13:11:03 -0700 Subject: [PATCH 14/19] Make IISExpress not depend on jscript. (#9212) --- .../ANCMIISExpressV2/ancm_iis_expressv2.wxs | 156 +++++------------- .../CustomAction/aspnetcoreCA.cpp | 134 +++++++++++++++ .../CustomAction/aspnetcoreCA.def | 2 + src/Installers/Windows/UpgradeLog.htm | Bin 0 -> 45142 bytes 4 files changed, 176 insertions(+), 116 deletions(-) create mode 100644 src/Installers/Windows/UpgradeLog.htm diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs index 49bae9932b..279bb8688a 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs +++ b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs @@ -366,66 +366,25 @@ Value=""[IISEXPRESS_INSTALL_PATH]appcmd.exe" set config -section:system.webServer/httpCompression /+"dynamicTypes.[\[]mimeType='text/event-stream',enabled='FALSE'[\]]" /apphostconfig:"[IISEXPRESS_APPHOST_CONFIG_TMP]""/> - - - - + Value="[IISEXPRESS_APPHOST_CONFIG]"/> + + + + - - - - + Property="CA_REMOVE_CONFIGSECTION" + Value="[IISEXPRESS_APPHOST_CONFIG]"/> + + + + - - - - - - + Property="CA_ADD_CONFIGSECTION32" + Value="[IISEXPRESS_APPHOST_CONFIG32]"/> + + + + - - - - + Value="[IISEXPRESS_APPHOST_CONFIG32]"/> + + + + @@ -600,7 +516,9 @@ - + + + @@ -610,6 +528,8 @@ + + @@ -640,7 +560,9 @@ - + + + @@ -650,6 +572,8 @@ + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.cpp index 48d826f720..7727eeed5c 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.cpp +++ b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.cpp @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. #include +#include +#include DECLARE_DEBUG_PRINT_OBJECT( "proxyCA.dll" ); @@ -40,6 +42,138 @@ struct COMPRESSION_MIME_TYPE COMPRESSION_MIME_TYPE gMimeTypes[] = { { L"text/event-stream", FALSE} }; +#define _HR_RET(hr) __pragma(warning(push)) \ + __pragma(warning(disable:26498)) /*disable constexpr warning */ \ + const HRESULT __hrRet = hr; \ + __pragma(warning(pop)) + +#define _GOTO_FINISHED() __pragma(warning(push)) \ + __pragma(warning(disable:26438)) /*disable avoid goto warning*/ \ + goto Finished \ + __pragma(warning(pop)) + +#define RETURN_IF_FAILED(hrr) do { _HR_RET(hrr); if (FAILED(__hrRet)) { hr = __hrRet; IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Exiting hr=0x%x", hr); return hr; }} while (0, 0) + +// Modifies the configSections to include the aspNetCore section +UINT +WINAPI +AddConfigSection( + IN MSIHANDLE handle +) +{ + HRESULT hr; + CComPtr pXMLDoc; + VARIANT_BOOL variantResult; + IXMLDOMNode* webServerNode; + IXMLDOMNode* aspNetCoreNode; + IXMLDOMNode* tempNode; + IXMLDOMElement* element; + STRU customActionData; + + CComBSTR selectLanguage = SysAllocString(L"SelectionLanguage"); + CComBSTR xPath = SysAllocString(L"XPath"); + CComBSTR webServerPath = SysAllocString(L"//configuration/configSections/sectionGroup[@name=\"system.webServer\"]"); + CComBSTR aspNetCorePath = SysAllocString(L"//configuration/configSections/sectionGroup[@name=\"system.webServer\"]/section[@name=\"aspNetCore\"]"); + CComBSTR section = SysAllocString(L"section"); + CComBSTR name = SysAllocString(L"name"); + CComBSTR aspNetCore = SysAllocString(L"aspNetCore"); + CComBSTR overrideMode = SysAllocString(L"overrideModeDefault"); + CComBSTR allow = SysAllocString(L"Allow"); + + RETURN_IF_FAILED(CoInitialize(NULL)); + + hr = MsiUtilGetProperty(handle, TEXT("CustomActionData"), &customActionData); + + RETURN_IF_FAILED(hr = pXMLDoc.CoCreateInstance(__uuidof(DOMDocument60))); + + RETURN_IF_FAILED(hr = pXMLDoc->put_async(false)); + + RETURN_IF_FAILED(hr = pXMLDoc->load(CComVariant(customActionData.QueryStr()), &variantResult)); + + if (variantResult == VARIANT_FALSE) + { + return ERROR_SUCCESS; + } + + RETURN_IF_FAILED(hr = pXMLDoc->setProperty(selectLanguage, CComVariant(xPath))); + + RETURN_IF_FAILED(hr = pXMLDoc->selectSingleNode(webServerPath, &webServerNode)); + + RETURN_IF_FAILED(hr = pXMLDoc->selectSingleNode(aspNetCorePath, &aspNetCoreNode)); + + if (aspNetCoreNode == NULL) + { + RETURN_IF_FAILED(hr = pXMLDoc->createElement(section, &element)); + + RETURN_IF_FAILED(hr = element->setAttribute(name, CComVariant(aspNetCore))); + + RETURN_IF_FAILED(hr = element->setAttribute(overrideMode, CComVariant(allow))); + + RETURN_IF_FAILED(hr = webServerNode->appendChild(element, &tempNode)); + + RETURN_IF_FAILED(hr = pXMLDoc->save(CComVariant(customActionData.QueryStr()))); + } + + return ERROR_SUCCESS; +} + +// Modifies the configSections to remove the aspNetCore section +UINT +WINAPI +RemoveConfigSection( + IN MSIHANDLE handle +) +{ + HRESULT hr; + CComPtr pXMLDoc; + VARIANT_BOOL variantResult; + IXMLDOMNode* webServerNode; + IXMLDOMNode* aspNetCoreNode; + IXMLDOMNode* tempNode; + IXMLDOMElement* element; + STRU customActionData; + + CComBSTR selectLanguage = SysAllocString(L"SelectionLanguage"); + CComBSTR xPath = SysAllocString(L"XPath"); + CComBSTR webServerPath = SysAllocString(L"//configuration/configSections/sectionGroup[@name=\"system.webServer\"]"); + CComBSTR aspNetCorePath = SysAllocString(L"//configuration/configSections/sectionGroup[@name=\"system.webServer\"]/section[@name=\"aspNetCore\"]"); + CComBSTR section = SysAllocString(L"section"); + CComBSTR name = SysAllocString(L"name"); + CComBSTR aspNetCore = SysAllocString(L"aspNetCore"); + CComBSTR overrideMode = SysAllocString(L"overrideModeDefault"); + CComBSTR allow = SysAllocString(L"Allow"); + + RETURN_IF_FAILED(CoInitialize(NULL)); + + hr = MsiUtilGetProperty(handle, TEXT("CustomActionData"), &customActionData); + + RETURN_IF_FAILED(hr = pXMLDoc.CoCreateInstance(__uuidof(DOMDocument60))); + + RETURN_IF_FAILED(hr = pXMLDoc->put_async(false)); + + RETURN_IF_FAILED(hr = pXMLDoc->load(CComVariant(customActionData.QueryStr()), &variantResult)); + + if (variantResult == VARIANT_FALSE) + { + return ERROR_SUCCESS; + } + + RETURN_IF_FAILED(hr = pXMLDoc->setProperty(selectLanguage, CComVariant(xPath))); + + RETURN_IF_FAILED(hr = pXMLDoc->selectSingleNode(webServerPath, &webServerNode)); + + RETURN_IF_FAILED(hr = pXMLDoc->selectSingleNode(aspNetCorePath, &aspNetCoreNode)); + + if (aspNetCoreNode != NULL) + { + RETURN_IF_FAILED(webServerNode->removeChild(aspNetCoreNode, &tempNode)); + + RETURN_IF_FAILED(hr = pXMLDoc->save(CComVariant(customActionData.QueryStr()))); + } + + return ERROR_SUCCESS; +} + UINT WINAPI RegisterANCMCompressionCA( diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.def b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.def index 3518cde35f..ed516a4392 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.def +++ b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.def @@ -18,6 +18,8 @@ EXPORTS ExecuteCleanUpWindowsHotfixCA ScheduleRebootIfRequiredCA + AddConfigSection + RemoveConfigSection RegisterANCMCompressionCA CheckForServicesRunningCA diff --git a/src/Installers/Windows/UpgradeLog.htm b/src/Installers/Windows/UpgradeLog.htm new file mode 100644 index 0000000000000000000000000000000000000000..f327ebd6ec8c9266607c164392462b8d434be9e7 GIT binary patch literal 45142 zcmeI5X>%J#l7{>1Zp8ivSe&uwm3d1%N9Cvx?M3I&QFIvn z9Q{}HpOH%R@F_%UY z#~imQb)nnRu&RK=)ii7;fwQtLd?hMj(2PK3ASZOKuxhB)8nN*hMvQHARphu_bXu2m-u!(aDB|4of?aNPoeB-KOuk*giohXVH` z1qHt1_CEOPYKy0vP+3x;`vqY2x2CoZUhkKo{6|vPFoZyC~WN2iDzKJ%mca_ffP2wRd?g4!lJQA4THS zGUfKTtMRStmyRdfj5@ns;rfg|YqZ%N=_F~49=>|EPg||^{}f1De59{-9hUtqLK608 zzz`($HZPoiIsWC5CX@eHP(XbU9R_GOISQoHyzUm4!*~$B!c}*IhR8b#_GmK?&aI7r zYAy{x-&6Fc=xoPu$Dg$(5kY>X5kEscadVJx7BvUW0Qp* zHyfXWv(1bJ*8@?ki?Ew(LFw2Rgct1SZFpkUxN8|bmc4oX+GIvC-g%zo5r-p z_$Jpj3s<<4e;f}!z&H-vh>xv-X!H(aE5K|YhrRUF(mT(-=$%3o&cBY7w?h(#ocv@< zVg;*X<94=<%b8|tJ(GQ2U_O!Log$GZ(Z^ef)HstBpcy~EOb$J$OtxQsf@~(`U2@av zT+%Mhc;B+!%$#?Qte7PyY-E|sa?CfDS{(yg&DrcL$vxzwm7lGiw6>LPbl@af_N?SL z%yRir#f<8UNDs<-d7%yYbv`lP+pvbg=aPqVC9O@gEKpfC{!lD3MKm)G7b^v7tk zu=ah-eXp71*EcVztRbtXd*)>;V8_e(fGN{*pmiMQ##Hc z<7c`=u$pY9&=|geGx8_u*@1(5!CW5J#ESl!6&zpN*$PQm!W&SdkpkL87#){iA0lU#SJ4L@#;>x#IvGIqM$=rc*x zZ@!WDyW`J)P^-C5wM84^G=sOc;sCx0AG@)$yzz%tx#35U*K=OW*(mTH48`fy5Bb|o z=gG1PQX~zkD@l|%su8*Ftl&^acG3<{#;{iZ&N08v>jFYD3J}Ngp-0U+`a+g!K27Ik z#^}=%qoHj15&Y;HhxsJ(uDnm`M&qy7aJurAwRGPVS2s=uJRjp6&Z_~tQW`MX_Cs^j zdX$f!tUsZ#gPIb}X6Qz=N_b7liY&str_dx)A_LUc61%r_?eIIm@0_dqXY z7Aadn5m>E3llSt;V0K%|U{cJ*$3&kyIeAz+Eh(S!6qwXoE>e)y`x*oHFOO!A&OvKg z$I|5!oLg*N7KX;6e5QJuv~rG|4m3Mt!<9Ngs(UFlMQQI<3F{N{j@Ue?Y#-%&Y2FoF zQBot)V&L+hYW?A7USCQ!Rh;JgZnjq5UcuFs-$YrB(kBI?7{XjQ*}1fbWsZ4x7U$e@ zIw)YQGU~BBEtYqaSHF3=HroEm7}4h)@DAzm3XtV{QZ|&RD$S;&@+|eFhkQ6|dzhTe zq`sT_(&OiKbZ8f~m7ygq(*+HxJ?uR^(=0B!iQkq7+I@@9I`_i!K1RE;s(x~iL=WNg zBaoLkmt|%CZ&9|3{L!DB$57T*SM(dOTczB6;k^&_$H~c9L@N5DY4X&R%T~Po%+ag2 zNMxDc-P?QPU!E4D1=g%ZvTc3&9rSh|cH!QaJ0-Y04rf+5&feZt6vJw~LB|(qbA^_# zpyS5v{c$9=4Cl+VumWyRsr?DddKrm%%eTbuB6&=&up$Srw03FtL-d+jRd^Jr3+5*SnnU0{E~0P97Cy1aGM7!wXSu*h>N6Fpv@6AmcXVTXrlBb<&L4+JQUH2ZJK+ZY4wtlbF`$G z@)p>t{5&|#Kqt}T8d``yMa~z%_ye@t;`c4^k2t^PzFO_4m6tqM?>~d#HQ!}g`9K@< z)W4?8E1s|L^b|@Ra_k4<7(JZ^#tkL6@UmEQi7|Ipd0HY~r^&SkiDN}+T@)ExT$1?ctfZqu?EQ8M$tq%kD zHEk%~-N%zX?krPhfL1jMcEE9iGRkqDrT52NKcnUZF!$iuM~>69`PxBwORGh$H4c{@ z--jt%g1U3`?iF_hX`Na}(4Y)eFM%n4q4EVZD$BIL3&vC6H^RMT%H2Sz9r&~h4x2nX zp)J{uhj8%(tY?Apk-i>7<iRcqc`)s{u)Ev@^pb9`IL87)sQ&4b}**Jh6$3+K;n;dseON@>T^kp)-JLc3o} zXB-Whwpc3YMzdH>(8~*G`bBi=2%7H-{rDLTeS%K>=w`=hwC@(0?ilU8#rJ|Ii|Ajy z$uvssS!Rj>?#l{!0<23)Rk*iKe-~(b94)=cbqV;ZXw;IMb)@YVfVqiIo&@GOXR@ys z(A2_Wow9RiWqE^S0UWqFWDI*@7C6J)lU=+GG_6JSCesWUyaDe`j`DR*a&}D*Cehp5 zu2&^y_G!MKm=|Ojj?%7XO<8K1U01lCr_LsA9x@lG%{h8HNG(P{(-E2Tqrq?E*zP(6W9eINNkJccJkjwPok*(AGz4jZ^0p@CV!zQS}q_ zoTCS`z)-fsI?pxdA41V-+E{Qi;uLeDt}FCOYr~gNb&TGOxw*QZHa`ISfYS1?_JQdr zr53rqqRxV&^dNVJz)TkQAoJ)7c*=78?C!ni*&NUg;aLf2AL!c?p2&sWpKHH8=t{KtD0%fbzif-IIoN>S#DF*xpq=@$-N!UZg?s#uRy(L;6CD{Y?}Kc z^lQOkRHB_do{N`5+&SQP9vZH?)+(;m33@s}Z)Evsr7G{liTn8ZTo&usozas%u=|nG0r!$X#y?MNd?rp_mp_xj$JMOVKMOQANdl%5EC5|dH ziT-`cv52l6=iUrYt~s8eyGNalUgy5v;?%migeG4??=Etb7h;5~B06`0`A4&awE8N~ zb>*ti!O7#u37jMA@qKU z&os~914Uzb!OgHwnIFsa;1k+^hT{b@)D^SH1bE%>`Aq+`3jD}3%}R4Xe?pxi_n!bo z@1AL8zXB$*Mk>(kfEh%-fq8Jc1kNyh(`x&aQo>X|mSM_h_1p(W2V4o>Fl{W+8+kvD zfpg({{EYS$50?coO6@+5tJIzbqVBz-hMve?SO&%uT9xG^JkRO*N8sGhpK~`8_H!-o zzSiqSdb14dC$yl|??9!z;{j=@MzCh2D%kSC$kQ$DYGzQQxfmT2i`$8nx4 zQsWs^Jp(6kQlA$OxZ(|wpZl2`1N@{O?5uMYL-(F{$#BP$?|tw-mKtQIGbet%IZ@u| z^xF0lT6Gzn`W9`dId2i&CLiGyx_h2k5}o~$7Ry}i zqoqIdIRv8t?$6K6WeoVO_Tp8m=QJV~D>xqrmf5oHEx;hHi> zU?M)h15d>W4rxvF>Zff*6=m~?YUh*?)sNuw2JkeOUonF!)BXeZSAi}$(6a&V%bWj- zvIjtthg(*G@E_oby!0Qy@Ql(Wt|sV%?1FP3YGry&|N8izQmW$Wy@YBX!EJ?hH@UOR zlM!gXMU6Sy9_J&f9MYcTP}uCl1I^o7{U5^}t;#28{UunA@bt5z-4wK5rnQfJrog=n zE?2)qAxxFbL@4x(fvL!<7;)TOIdAFO0N+J54 zZxS=724hE*4XW{?#B~E(>!}p*umTUizYa9puN7ru7v6A(H});~#Nu z)N7+VdJMOY>A7+JvE!S@L6E96RTbIK>Y>G->W#Q<+LCub7PqXxYFa3-Hc&y4Lg6E> zY{PT$F01wYbjfZ{6v{&#Wsz#99P4GfXmz(9r$?Hk;p_G~n}=DwHNB^}vsQ~5v6gRX zxkH-e<%!+ktI;j39WsY}KBzK;q@z?*qeQwd=rwuG<TL<>L1p7e8)V}xODL&- zqyasi%fPT)v|+U@$htmf#KpB=1^Ynr zyjCRv!^f06V>~pHY8(50zUYREFR*Hq5xmd$AAFOT>5U|fZ&{0bx8`x{woMxi35)qhEsJUH9vF1>qalF=+x3>%vTzGGLu zdf0p)eGfjhpZ0=-=2=-GZ`^$1v5h2J(@l4R4?!Ne+WHVKod(BSNHY)G;C7xgWj@zQZ*)(FCptfqfvW_b-TGq z`39Puv&Udu>)5&SoVA9O_eYkHViel9qIo#kx~CcKWo5FoR4rVCt(~oDv+>Jn)hte} zLzEHdt-`p~S<7PdK7#bBR_g;%+h#s{+eKyUy|j=C9#*GGD>dx2>sPOOo`rw4Zud3S zmm4QJ=FiBM=VmmwIONACcZ{mx~;d(OSj2R z7L9#N1-wXl3tHYZS!iMRVewtO(@w{;=ZCOr2|H3GVKj%W z*W;G=?`7QPl0GEEWBkXLvkJU4oPUVcu#MK}ufD(1qaJ*IMShh_-GgUujo&rw=ijj9 zyD3|%%x}CG@I&;AgYgTcYL)SD{z)m7{Lz(O<97|n-}AQNTJ$&GGFU^l{s*nKhJ>tP zPyGgDy>*}%akh2{{A-SGwI!-IHL|;%Mm@xrYPv%*@R;?F-Ywm8Wp}{%5x9TP@6YZi zKjb>+T2B-jVExcKO}?ApA=8^QvfP!CpGCDs`X{;a)M{~yzGp#fZv1=MPGc?o)0`El zHSiQ=JxsW`^NQ}w;-}5F#Bm1 zhpS~K?(vzW?_p1hupS9MpKf%jd^~>NO25j_=0RiHd*0TDUO+ddXS&)Y^UiyXF_T2Z zwNf*)TQ+|LF^flfp2xrS2$_uY%~p;j#)#r4wpafXVAiHsGd`z0*gUR@jq+bD`f)~7 zO7Epyp@|F3GT#nfidD+@(-^O8{$+DNi}Tf^a|sJp1kuk)S~kt#;*9h{&B^$wXT#`q3nL0+nzdk{~hHn|Ba&m!?AxuQQN{n{_RWdNmt9p zSB6`NZTtVT(Z2C%Jm0to@R^e>d3Kh8VgIk9TIr`ohrya{rgxgLRu$W|IF#^|{Mm8O z9rb@Mc4kqrG+;JWWbA;Y78@( zr=A5jU9vIkAh-6hP<}Y zYl_e5I=y=BV$ClIN5IxQvSp%Dvf)g3t&lk-d1zEdJ<+;X$8?M8nc-r`A|+0V+{tHI z0yDKW>&Cx!Kig(3YDWUgiCLrNIhT1?4?C5}#=qD3TdY@FQyA3)Mrj&*?^X#cY|IP8 zEk}n|=ochalpJvFds@XQlNXPl@zccVeiv9tk4Bg4Yi;OXUry69sp~i$?nnOAN{}^O zJ(OIjt&R*yPuyMCX;rA~3XSJUju!pbTdjJFLE|&KL>@WIhP2k8rTdnyZ0tJn_7L(m z&RRjM5zTsyWiMX3eR3Fw+DInjWxuX`#xd#0>O;t?q97YhNU4=;pL`m;Mv`fzzOGCf z4jpN1k2J0#Z_$?7y`_?Rv)QtFq_SCUq}@`r52qASSa*6UTs^E5g?5ANgnJ#C`L<+c2_2-pCjA^DJtS|k?ZMwT?vbv) zbX(Kbxk=cPLl4<}$etFBe0fvoNtLmT+im9G3Vu25&U@^9f`5&w{FL}xaz8n(QroW`^q$UqY{+7s5Bn(^KYdhQ;N34 z<7??UAyd;^IJPf!#Yu>|`-W zF0o<~`tQo5#`5%dLAfDHYrjnGQ!+@rbQE1Q%AFqeW*8-|G3M?K0QDJX+9_g`-y!@a z+8t|x=M#LYXI(F|^|f|A9jF*pkp85;(=)Y|N4KfYUqz1@?My?rTW1OOx2K(jK;6Z+7%f+&ajPUZyoscIjqyQ#O=;cWss3`*z!0*{$8DM$2xwQ5-7m-SiQ7dTWqvX+wR;NAs&|v+wHKFH0d)KbnGn=*f^|YV0-$?ISsgB0$XuLcc zuh|TqwAO33UbC97S$O~M+OJtUwA%`7w%z;Gg3aR4dj4ByZQNNKXW4&>?$pk$OWJ(( z$~CL)>ec_VYPUw#m~ti*E6d7$Ouvg(FJf6871n=@B_qC-+dWLBCF{{zyC2zJs}|wY z|B0I-@BmKh^qo-en;8H~c5?l4usSeR};qN^!Z7 zR!+CktR$xE#o_*WGmnz9m-QpwGx;Z!Rh902<5fUAXI{_H2spWT*GOlUZ2lJ|-ckbam!o-o3tB%{Z)Q3wR0?c-LN8NY!+xwk&GF(kSqG zsMVP Date: Tue, 9 Apr 2019 14:23:07 -0700 Subject: [PATCH 15/19] Updating SDK to 3.0.100-preview4-011136 --- build/sources.props | 1 + build/tasks/RepoTasks.csproj | 2 +- global.json | 2 +- korebuild-lock.txt | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build/sources.props b/build/sources.props index 717242fc60..29a3b61a6d 100644 --- a/build/sources.props +++ b/build/sources.props @@ -20,6 +20,7 @@ https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; https://dotnet.myget.org/F/blazor-dev/api/v3/index.json; https://dotnet.myget.org/F/dotnet-core/api/v3/index.json; + https://dotnet.myget.org/F/nuget-build/api/v3/index.json; https://dotnet.myget.org/F/roslyn-tools/api/v3/index.json; https://dotnet.myget.org/F/roslyn/api/v3/index.json; https://vside.myget.org/F/devcore/api/v3/index.json; diff --git a/build/tasks/RepoTasks.csproj b/build/tasks/RepoTasks.csproj index 8615952bb7..cee6fea25f 100644 --- a/build/tasks/RepoTasks.csproj +++ b/build/tasks/RepoTasks.csproj @@ -12,7 +12,7 @@ - + diff --git a/global.json b/global.json index dd1a93e0d5..339c8c9e4c 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "3.0.100-preview4-010309" + "version": "3.0.100-preview4-011136" }, "msbuild-sdks": { "Yarn.MSBuild": "1.13.0" diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 638dfb3b2a..bf0fe32bb6 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-build-20190322.1 -commithash:c38761a564c72b5bc96356ec99c89de5f281a358 +version:3.0.0-build-20190408.1 +commithash:8b533cbfa5357e5785f4c4231231c1234cfc2c5f From 3e056db750d562826473f476e4f9b02ad76ffdd3 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 9 Apr 2019 14:37:06 -0700 Subject: [PATCH 16/19] Marking a good number of tests as flaky. (#9101) --- .../IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs | 2 ++ .../Kestrel/test/BindTests/AddressRegistrationTests.cs | 2 ++ src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs | 1 + .../InMemory.FunctionalTests/Http2/Http2TimeoutTests.cs | 2 +- .../InMemory.FunctionalTests/HttpsConnectionAdapterTests.cs | 2 +- .../LoggingConnectionAdapterTests.cs | 2 ++ .../Kestrel/test/InMemory.FunctionalTests/RequestTests.cs | 6 ++++-- src/Servers/Kestrel/xunit.runner.json | 3 ++- 8 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs index 9ea84650d7..68ff8d44ac 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing.xunit; using Xunit; @@ -170,6 +171,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests } [ConditionalTheory] + [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2200", FlakyOn.All)] [MemberData(nameof(TestVariants))] public async Task CheckUTF8File(TestVariant variant) { diff --git a/src/Servers/Kestrel/test/BindTests/AddressRegistrationTests.cs b/src/Servers/Kestrel/test/BindTests/AddressRegistrationTests.cs index 50fbbfb73d..654b7b6fea 100644 --- a/src/Servers/Kestrel/test/BindTests/AddressRegistrationTests.cs +++ b/src/Servers/Kestrel/test/BindTests/AddressRegistrationTests.cs @@ -154,6 +154,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests } [ConditionalTheory] + [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2179", FlakyOn.Helix.All)] [MemberData(nameof(AddressRegistrationDataIPv6ScopeId))] [IPv6SupportedCondition] [IPv6ScopeIdPresentCondition] @@ -589,6 +590,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests } [Fact] + [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2178", FlakyOn.All)] public async Task DoesNotOverrideDirectConfigurationWithIServerAddressesFeature_IfPreferHostingUrlsFalse() { var useUrlsAddress = $"http://127.0.0.1:0"; diff --git a/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs b/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs index 7f1114a4c7..30bc96a50d 100644 --- a/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs +++ b/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs @@ -542,6 +542,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests } [Theory] + [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2181", FlakyOn.Helix.All)] [MemberData(nameof(ConnectionAdapterData))] public async Task ConnectionClosedTokenFiresOnServerFIN(ListenOptions listenOptions) { diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TimeoutTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TimeoutTests.cs index 92d175b17a..029e8b5e15 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TimeoutTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TimeoutTests.cs @@ -492,7 +492,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _mockConnectionContext.VerifyNoOtherCalls(); } - [Fact] + [Fact(Skip = "https://github.com/aspnet/AspNetCore-Internal/issues/2197")] public async Task DATA_Sent_TooSlowlyDueToOutputFlowControlOnMultipleStreams_AbortsConnectionAfterAdditiveRateTimeout() { var mockSystemClock = _serviceContext.MockSystemClock; diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionAdapterTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionAdapterTests.cs index fe46fba80f..1334d1809b 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionAdapterTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionAdapterTests.cs @@ -484,7 +484,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests } } - [Theory] + [ConditionalTheory] [SkipOnHelix] [InlineData(ClientCertificateMode.AllowCertificate)] [InlineData(ClientCertificateMode.RequireCertificate)] diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/LoggingConnectionAdapterTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/LoggingConnectionAdapterTests.cs index bb70e492bf..cd0d470eec 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/LoggingConnectionAdapterTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/LoggingConnectionAdapterTests.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport; using Microsoft.AspNetCore.Testing; +using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.Logging.Testing; using Xunit; @@ -14,6 +15,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests public class LoggingConnectionAdapterTests : LoggedTest { [Fact] + [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/1753", FlakyOn.Helix.All)] public async Task LoggingConnectionAdapterCanBeAddedBeforeAndAfterHttpsAdapter() { await using (var server = new TestServer(context => diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs index 8ed69dc763..7aa6ccd275 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs @@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport; using Microsoft.AspNetCore.Testing; +using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.Logging.Testing; using Xunit; @@ -781,6 +782,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests } [Fact] + [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2176", FlakyOn.All)] public async Task ContentLengthReadAsyncSingleBytesAtATime() { var testContext = new TestServiceContext(LoggerFactory); @@ -811,10 +813,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests "Content-Length: 5", "", "fun"); - await tcs.Task; + await tcs.Task.DefaultTimeout(); await connection.Send( "n"); - await tcs2.Task; + await tcs2.Task.DefaultTimeout(); await connection.Send( "y"); await connection.ReceiveEnd( diff --git a/src/Servers/Kestrel/xunit.runner.json b/src/Servers/Kestrel/xunit.runner.json index e3984f4384..18711b4b2e 100644 --- a/src/Servers/Kestrel/xunit.runner.json +++ b/src/Servers/Kestrel/xunit.runner.json @@ -3,5 +3,6 @@ "appDomain": "denied", "methodDisplay": "method", "longRunningTestSeconds": 60, - "maxParallelThreads": -1 + "maxParallelThreads": -1, + "diagnosticMessages": true } From 3b32f43453eba8edf03bebb9d893af59ada0e431 Mon Sep 17 00:00:00 2001 From: Stafford Williams Date: Wed, 10 Apr 2019 17:36:18 +1000 Subject: [PATCH 17/19] Crankier: Log connection exceptions (#9045) --- .../perf/benchmarkapps/Crankier/Client.cs | 19 +++++++++++++++++-- .../perf/benchmarkapps/Crankier/Worker.cs | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Client.cs b/src/SignalR/perf/benchmarkapps/Crankier/Client.cs index f78c509b77..6ef5946037 100644 --- a/src/SignalR/perf/benchmarkapps/Crankier/Client.cs +++ b/src/SignalR/perf/benchmarkapps/Crankier/Client.cs @@ -12,12 +12,27 @@ namespace Microsoft.AspNetCore.SignalR.Crankier { public class Client { + private readonly int _processId; + private readonly IAgent _agent; private HubConnection _connection; private CancellationTokenSource _sendCts; private bool _sendInProgress; private volatile ConnectionState _connectionState = ConnectionState.Connecting; public ConnectionState State => _connectionState; + public Client(int processId, IAgent agent) + { + _processId = processId; + _agent = agent; + } + + private void LogFault(string description, Exception exception) + { + var message = $"{description}: {exception.GetType()}: {exception.Message}"; + Trace.WriteLine(message); + _agent.LogAsync(_processId, message); + } + public async Task CreateAndStartConnectionAsync(string url, HttpTransportType transportType) { _connection = new HubConnectionBuilder() @@ -33,7 +48,7 @@ namespace Microsoft.AspNetCore.SignalR.Crankier } else { - Trace.WriteLine($"Connection terminated with error: {ex.GetType()}: {ex.Message}"); + LogFault("Connection terminated with error", ex); _connectionState = ConnectionState.Faulted; } @@ -57,7 +72,7 @@ namespace Microsoft.AspNetCore.SignalR.Crankier } catch (Exception ex) { - Trace.WriteLine($"Connection.Start Failed: {ex.GetType()}: {ex.Message}"); + LogFault("Connection.Start Failed", ex); if (connectCount == 3) { diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Worker.cs b/src/SignalR/perf/benchmarkapps/Crankier/Worker.cs index 6a39616574..06409418d6 100644 --- a/src/SignalR/perf/benchmarkapps/Crankier/Worker.cs +++ b/src/SignalR/perf/benchmarkapps/Crankier/Worker.cs @@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.SignalR.Crankier _targetConnectionCount += numberOfConnections; for (var count = 0; count < numberOfConnections; count++) { - var client = new Client(); + var client = new Client(_processId, _agent); _clients.Add(client); await client.CreateAndStartConnectionAsync(targetAddress, transportType); From 6f13e7b77a262a95cf7f360d4da2b73024deadaf Mon Sep 17 00:00:00 2001 From: Javier Calvarro Nelson Date: Wed, 10 Apr 2019 17:19:52 +0200 Subject: [PATCH 18/19] E2E infrastructure cleanup (#9163) --- src/Shared/E2ETesting/BrowserFixture.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Shared/E2ETesting/BrowserFixture.cs b/src/Shared/E2ETesting/BrowserFixture.cs index b1f954ce12..c93e618590 100644 --- a/src/Shared/E2ETesting/BrowserFixture.cs +++ b/src/Shared/E2ETesting/BrowserFixture.cs @@ -3,21 +3,20 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Remote; +using Xunit; using Xunit.Abstractions; namespace Microsoft.AspNetCore.E2ETesting { - public class BrowserFixture : IDisposable + public class BrowserFixture : IAsyncLifetime { private ConcurrentDictionary> _browsers = new ConcurrentDictionary>(); - private List _browsersToDispose = new List(); public BrowserFixture(IMessageSink diagnosticsMessageSink) { @@ -52,9 +51,10 @@ namespace Microsoft.AspNetCore.E2ETesting } } - public void Dispose() + public async Task DisposeAsync() { - foreach (var browser in _browsersToDispose) + var browsers = await Task.WhenAll(_browsers.Values); + foreach (var (browser, log) in browsers) { browser.Dispose(); } @@ -71,6 +71,8 @@ namespace Microsoft.AspNetCore.E2ETesting return _browsers.GetOrAdd(isolationContext, CreateBrowserAsync, output); } + public Task InitializeAsync() => Task.CompletedTask; + private async Task<(IWebDriver browser, ILogs log)> CreateBrowserAsync(string context, ITestOutputHelper output) { var opts = new ChromeOptions(); @@ -115,7 +117,6 @@ namespace Microsoft.AspNetCore.E2ETesting driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1); var logs = new RemoteLogs(driver); - _browsersToDispose.Add(driver); return (driver, logs); } catch From a3a53413c46bdf79e11c3cec40d8c2d0be9979e7 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 10 Apr 2019 08:55:35 -0700 Subject: [PATCH 19/19] Update CODEOWNERS (#9229) --- .github/CODEOWNERS | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c4e6085b10..719f153297 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,18 +1,18 @@ # Users referenced in this file will automatically be requested as reviewers for PRs that modify the given paths. # See https://help.github.com/articles/about-code-owners/ -/.azure/ @dougbu -/.config/ @dougbu -/build/ @dougbu -/eng/ @dougbu -/src/Components/ @SteveSandersonMS -/src/DefaultBuilder/ @tratcher @anurse -/src/Hosting/ @tratcher @anurse -/src/Http/ @tratcher @jkotalik @anurse -/src/Middleware/ @tratcher @anurse -/src/ProjectTemplates/ @ryanbrandenburg -/src/Security/ @tratcher @anurse -/src/Servers/ @tratcher @jkotalik @anurse -/src/Middleware/Rewrite @jkotalik @anurse -/src/Middleware/HttpsPolicy @jkotalik @anurse -/src/SignalR/ @mikaelm12 @BrennanConroy @halter73 @anurse +/.azure/ @aspnet/build +/.config/ @aspnet/build +/build/ @aspnet/build +/eng/ @aspnet/build +/src/Components/ @SteveSandersonMS +/src/DefaultBuilder/ @tratcher @anurse +/src/Hosting/ @tratcher @anurse +/src/Http/ @tratcher @jkotalik @anurse +/src/Middleware/ @tratcher @anurse +/src/ProjectTemplates/ @ryanbrandenburg +/src/Security/ @tratcher @anurse +/src/Servers/ @tratcher @jkotalik @anurse +/src/Middleware/Rewrite @jkotalik @anurse +/src/Middleware/HttpsPolicy @jkotalik @anurse +/src/SignalR/ @mikaelm12 @BrennanConroy @halter73 @anurse