From d7fc06af5e04a11a5ba90e9039f018f12c9f4a9d Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 10 Jun 2019 21:16:36 -0700 Subject: [PATCH] Move IServerVariablesFeature to Http.Features (#11007) --- ...spNetCore.Http.Extensions.netcoreapp3.0.cs | 4 +++ .../HttpContextServerVariableExtensions.cs | 31 ++++++++++++++++++ ...AspNetCore.Http.Features.netstandard2.0.cs | 4 +++ .../src/IServerVariablesFeature.cs} | 6 ---- .../ref/Microsoft.AspNetCore.Rewrite.csproj | 1 - .../IISServerVariableSegment.cs | 4 +-- .../src/Microsoft.AspNetCore.Rewrite.csproj | 3 +- .../Microsoft.AspNetCore.Server.IIS.csproj | 2 ++ ...oft.AspNetCore.Server.IIS.netcoreapp3.0.cs | 8 +---- .../IIS/samples/NativeIISSample/Startup.cs | 2 +- src/Servers/IIS/IIS/src/AssemblyInfo.cs | 2 ++ .../IIS/IIS/src/HttpContextExtensions.cs | 20 +++--------- .../Microsoft.AspNetCore.Server.IIS.csproj | 4 ++- .../InProcessNewShimWebSite.csproj | 32 ++++++++++++++----- .../InProcessWebSite/Startup.WebSockets.cs | 5 ++- .../testassets/InProcessWebSite/Startup.cs | 22 +++++++++++-- 16 files changed, 104 insertions(+), 46 deletions(-) create mode 100644 src/Http/Http.Extensions/src/HttpContextServerVariableExtensions.cs rename src/{Servers/IIS/IIS/src/IServerVariableFeature.cs => Http/Http.Features/src/IServerVariablesFeature.cs} (72%) diff --git a/src/Http/Http.Extensions/ref/Microsoft.AspNetCore.Http.Extensions.netcoreapp3.0.cs b/src/Http/Http.Extensions/ref/Microsoft.AspNetCore.Http.Extensions.netcoreapp3.0.cs index 77740aa3f0..4f7e2f5642 100644 --- a/src/Http/Http.Extensions/ref/Microsoft.AspNetCore.Http.Extensions.netcoreapp3.0.cs +++ b/src/Http/Http.Extensions/ref/Microsoft.AspNetCore.Http.Extensions.netcoreapp3.0.cs @@ -9,6 +9,10 @@ namespace Microsoft.AspNetCore.Http public static Microsoft.AspNetCore.Http.Headers.RequestHeaders GetTypedHeaders(this Microsoft.AspNetCore.Http.HttpRequest request) { throw null; } public static Microsoft.AspNetCore.Http.Headers.ResponseHeaders GetTypedHeaders(this Microsoft.AspNetCore.Http.HttpResponse response) { throw null; } } + public static partial class HttpContextServerVariableExtensions + { + public static string GetServerVariable(this Microsoft.AspNetCore.Http.HttpContext context, string variableName) { throw null; } + } public static partial class ResponseExtensions { public static void Clear(this Microsoft.AspNetCore.Http.HttpResponse response) { } diff --git a/src/Http/Http.Extensions/src/HttpContextServerVariableExtensions.cs b/src/Http/Http.Extensions/src/HttpContextServerVariableExtensions.cs new file mode 100644 index 0000000000..1b41d8e305 --- /dev/null +++ b/src/Http/Http.Extensions/src/HttpContextServerVariableExtensions.cs @@ -0,0 +1,31 @@ +// 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 Microsoft.AspNetCore.Http.Features; + +namespace Microsoft.AspNetCore.Http +{ + public static class HttpContextServerVariableExtensions + { + /// + /// Gets the value of a server variable for the current request. + /// + /// The http context for the request. + /// The name of the variable. + /// + /// null if the server does not support the feature. + /// May return null or empty if the variable does not exist or is not set. + /// + public static string GetServerVariable(this HttpContext context, string variableName) + { + var feature = context.Features.Get(); + + if (feature == null) + { + return null; + } + + return feature[variableName]; + } + } +} diff --git a/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netstandard2.0.cs b/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netstandard2.0.cs index c97e11f219..30f567851c 100644 --- a/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netstandard2.0.cs +++ b/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netstandard2.0.cs @@ -260,6 +260,10 @@ namespace Microsoft.AspNetCore.Http.Features { Microsoft.AspNetCore.Http.IResponseCookies Cookies { get; } } + public partial interface IServerVariablesFeature + { + string this[string variableName] { get; set; } + } public partial interface IServiceProvidersFeature { System.IServiceProvider RequestServices { get; set; } diff --git a/src/Servers/IIS/IIS/src/IServerVariableFeature.cs b/src/Http/Http.Features/src/IServerVariablesFeature.cs similarity index 72% rename from src/Servers/IIS/IIS/src/IServerVariableFeature.cs rename to src/Http/Http.Features/src/IServerVariablesFeature.cs index 44f667cb41..2ff18f77c5 100644 --- a/src/Servers/IIS/IIS/src/IServerVariableFeature.cs +++ b/src/Http/Http.Features/src/IServerVariablesFeature.cs @@ -5,13 +5,7 @@ namespace Microsoft.AspNetCore.Http.Features { /// /// This feature provides access to request server variables set. - /// - /// This feature is only available when hosting ASP.NET Core in-process with IIS or IIS Express. - /// /// - /// - /// For a list of common server variables available in IIS, see http://go.microsoft.com/fwlink/?LinkId=52471. - /// public interface IServerVariablesFeature { /// diff --git a/src/Middleware/Rewrite/ref/Microsoft.AspNetCore.Rewrite.csproj b/src/Middleware/Rewrite/ref/Microsoft.AspNetCore.Rewrite.csproj index 587668329e..a4014b3f94 100644 --- a/src/Middleware/Rewrite/ref/Microsoft.AspNetCore.Rewrite.csproj +++ b/src/Middleware/Rewrite/ref/Microsoft.AspNetCore.Rewrite.csproj @@ -7,7 +7,6 @@ - diff --git a/src/Middleware/Rewrite/src/Internal/PatternSegments/IISServerVariableSegment.cs b/src/Middleware/Rewrite/src/Internal/PatternSegments/IISServerVariableSegment.cs index 30504d54a4..8bc3f96cf8 100644 --- a/src/Middleware/Rewrite/src/Internal/PatternSegments/IISServerVariableSegment.cs +++ b/src/Middleware/Rewrite/src/Internal/PatternSegments/IISServerVariableSegment.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNetCore.Server.IIS; +using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Rewrite.Internal.PatternSegments { @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.PatternSegments public override string Evaluate(RewriteContext context, BackReferenceCollection ruleBackReferences, BackReferenceCollection conditionBackReferences) { - return context.HttpContext.GetIISServerVariable(_variableName) ?? _fallbackThunk().Evaluate(context, ruleBackReferences, conditionBackReferences); + return context.HttpContext.GetServerVariable(_variableName) ?? _fallbackThunk().Evaluate(context, ruleBackReferences, conditionBackReferences); } } } diff --git a/src/Middleware/Rewrite/src/Microsoft.AspNetCore.Rewrite.csproj b/src/Middleware/Rewrite/src/Microsoft.AspNetCore.Rewrite.csproj index be6f19ceb7..b7f9f44efa 100644 --- a/src/Middleware/Rewrite/src/Microsoft.AspNetCore.Rewrite.csproj +++ b/src/Middleware/Rewrite/src/Microsoft.AspNetCore.Rewrite.csproj @@ -1,4 +1,4 @@ - + ASP.NET Core basic middleware for rewriting URLs. Includes: @@ -15,7 +15,6 @@ - diff --git a/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.csproj b/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.csproj index ed6753b780..72d9c85999 100644 --- a/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.csproj +++ b/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.csproj @@ -8,6 +8,8 @@ + + diff --git a/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.netcoreapp3.0.cs b/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.netcoreapp3.0.cs index 7294851a43..635097115d 100644 --- a/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.netcoreapp3.0.cs +++ b/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.netcoreapp3.0.cs @@ -19,13 +19,6 @@ namespace Microsoft.AspNetCore.Hosting public static Microsoft.AspNetCore.Hosting.IWebHostBuilder UseIIS(this Microsoft.AspNetCore.Hosting.IWebHostBuilder hostBuilder) { throw null; } } } -namespace Microsoft.AspNetCore.Http.Features -{ - public partial interface IServerVariablesFeature - { - string this[string variableName] { get; set; } - } -} namespace Microsoft.AspNetCore.Server.IIS { public sealed partial class BadHttpRequestException : System.IO.IOException @@ -35,6 +28,7 @@ namespace Microsoft.AspNetCore.Server.IIS } public static partial class HttpContextExtensions { + [System.ObsoleteAttribute("This is obsolete and will be removed in a future version. Use GetServerVariable instead.")] public static string GetIISServerVariable(this Microsoft.AspNetCore.Http.HttpContext context, string variableName) { throw null; } } public partial class IISServerDefaults diff --git a/src/Servers/IIS/IIS/samples/NativeIISSample/Startup.cs b/src/Servers/IIS/IIS/samples/NativeIISSample/Startup.cs index 216dcea3b8..96c77e15cb 100644 --- a/src/Servers/IIS/IIS/samples/NativeIISSample/Startup.cs +++ b/src/Servers/IIS/IIS/samples/NativeIISSample/Startup.cs @@ -80,7 +80,7 @@ namespace NativeIISSample foreach (var varName in IISServerVarNames) { - await context.Response.WriteAsync(varName + ": " + context.GetIISServerVariable(varName) + Environment.NewLine); + await context.Response.WriteAsync(varName + ": " + context.GetServerVariable(varName) + Environment.NewLine); } await context.Response.WriteAsync(Environment.NewLine); diff --git a/src/Servers/IIS/IIS/src/AssemblyInfo.cs b/src/Servers/IIS/IIS/src/AssemblyInfo.cs index 5f58cf6c8e..6f83e91b28 100644 --- a/src/Servers/IIS/IIS/src/AssemblyInfo.cs +++ b/src/Servers/IIS/IIS/src/AssemblyInfo.cs @@ -2,7 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Runtime.CompilerServices; +using Microsoft.AspNetCore.Http.Features; [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Server.IISIntegration.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("IIS.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] +[assembly: TypeForwardedTo(typeof(IServerVariablesFeature))] diff --git a/src/Servers/IIS/IIS/src/HttpContextExtensions.cs b/src/Servers/IIS/IIS/src/HttpContextExtensions.cs index 9c0092d3fe..de1d53a5aa 100644 --- a/src/Servers/IIS/IIS/src/HttpContextExtensions.cs +++ b/src/Servers/IIS/IIS/src/HttpContextExtensions.cs @@ -1,6 +1,7 @@ // 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 Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; @@ -17,22 +18,11 @@ namespace Microsoft.AspNetCore.Server.IIS /// The http context for the request. /// The name of the variable. /// - /// null if the feature does not support the feature. + /// null if the server does not support the feature. /// May return null or empty if the variable does not exist or is not set. /// - /// - /// For a list of common server variables available in IIS, see http://go.microsoft.com/fwlink/?LinkId=52471. - /// - public static string GetIISServerVariable(this HttpContext context, string variableName) - { - var feature = context.Features.Get(); - - if (feature == null) - { - return null; - } - - return feature[variableName]; - } + [Obsolete("This is obsolete and will be removed in a future version. Use " + nameof(HttpContextServerVariableExtensions.GetServerVariable) + " instead.")] + public static string GetIISServerVariable(this HttpContext context, string variableName) => + context.GetServerVariable(variableName); } } diff --git a/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj b/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj index dd160c168a..e72a107035 100644 --- a/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj +++ b/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.0 @@ -35,6 +35,8 @@ + + diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessNewShimWebSite/InProcessNewShimWebSite.csproj b/src/Servers/IIS/IIS/test/testassets/InProcessNewShimWebSite/InProcessNewShimWebSite.csproj index 69852cbf81..a27cd396a8 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessNewShimWebSite/InProcessNewShimWebSite.csproj +++ b/src/Servers/IIS/IIS/test/testassets/InProcessNewShimWebSite/InProcessNewShimWebSite.csproj @@ -30,14 +30,30 @@ - - - - - - - - + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.WebSockets.cs b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.WebSockets.cs index 807301c7b2..b7986cb87b 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.WebSockets.cs +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.WebSockets.cs @@ -47,8 +47,11 @@ namespace TestSite app.Run(async context => { var ws = await Upgrade(context); - +#if FORWARDCOMPAT + var appLifetime = app.ApplicationServices.GetRequiredService(); +#else var appLifetime = app.ApplicationServices.GetRequiredService(); +#endif await Echo(ws, appLifetime.ApplicationStopping); }); diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs index 1825ac7a1d..9b2011346e 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs @@ -26,6 +26,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Primitives; using Xunit; +using HttpFeatures = Microsoft.AspNetCore.Http.Features; namespace TestSite { @@ -35,15 +36,20 @@ namespace TestSite { TestStartup.Register(app, this); } - + public void ConfigureServices(IServiceCollection serviceCollection) { serviceCollection.AddResponseCompression(); } +#if FORWARDCOMPAT + private async Task ContentRootPath(HttpContext ctx) => await ctx.Response.WriteAsync(ctx.RequestServices.GetService().ContentRootPath); + private async Task WebRootPath(HttpContext ctx) => await ctx.Response.WriteAsync(ctx.RequestServices.GetService().WebRootPath); +#else private async Task ContentRootPath(HttpContext ctx) => await ctx.Response.WriteAsync(ctx.RequestServices.GetService().ContentRootPath); private async Task WebRootPath(HttpContext ctx) => await ctx.Response.WriteAsync(ctx.RequestServices.GetService().WebRootPath); +#endif private async Task CurrentDirectory(HttpContext ctx) => await ctx.Response.WriteAsync(Environment.CurrentDirectory); @@ -118,7 +124,11 @@ namespace TestSite public Task CreateFile(HttpContext context) { +#if FORWARDCOMPAT + var hostingEnv = context.RequestServices.GetService(); +#else var hostingEnv = context.RequestServices.GetService(); +#endif if (context.Connection.LocalIpAddress == null || context.Connection.RemoteIpAddress == null) { @@ -434,7 +444,11 @@ namespace TestSite private async Task WaitForAppToStartShuttingDown(HttpContext ctx) { await ctx.Response.WriteAsync("test1"); +#if FORWARDCOMPAT + var lifetime = ctx.RequestServices.GetService(); +#else var lifetime = ctx.RequestServices.GetService(); +#endif lifetime.ApplicationStopping.WaitHandle.WaitOne(); await ctx.Response.WriteAsync("test2"); } @@ -797,7 +811,11 @@ namespace TestSite private async Task Shutdown(HttpContext ctx) { await ctx.Response.WriteAsync("Shutting down"); +#if FORWARDCOMPAT + ctx.RequestServices.GetService().StopApplication(); +#else ctx.RequestServices.GetService().StopApplication(); +#endif } private async Task ShutdownStopAsync(HttpContext ctx) @@ -844,8 +862,8 @@ namespace TestSite // This test simulates the scenario where native Flush call is being // executed on background thread while request thread calls GetServerVariable // concurrent native calls may cause native object corruption - var serverVariableFeature = ctx.Features.Get(); + await ctx.Response.WriteAsync("Response Begin"); for (int i = 0; i < 1000; i++) {