diff --git a/DiagnosticsPages.sln b/DiagnosticsPages.sln index a04d598db8..28c91bf29d 100644 --- a/DiagnosticsPages.sln +++ b/DiagnosticsPages.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.22228.1 +VisualStudioVersion = 14.0.22530.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{509A6F36-AD80-4A18-B5B1-717D38DFF29D}" EndProject @@ -38,6 +38,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Diagnostic EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StatusCodePagesSample", "samples\StatusCodePagesSample\StatusCodePagesSample.kproj", "{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Diagnostics.Interfaces", "src\Microsoft.AspNet.Diagnostics.Interfaces\Microsoft.AspNet.Diagnostics.Interfaces.kproj", "{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -178,6 +180,18 @@ Global {CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|Mixed Platforms.Build.0 = Release|Any CPU {CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|x86.ActiveCfg = Release|Any CPU {CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|x86.Build.0 = Release|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|x86.ActiveCfg = Debug|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|x86.Build.0 = Debug|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Any CPU.Build.0 = Release|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|x86.ActiveCfg = Release|Any CPU + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -195,5 +209,6 @@ Global {2F9B479D-8247-4210-804B-78E6DD5C3E98} = {2AF90579-B118-4583-AE88-672EFACB5BC4} {624B0019-956A-4157-B008-270C5B229553} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D} {CC1F5841-FE10-4DDB-8477-C4DE92BA759F} = {ACAA0157-A8C4-4152-93DE-90CCDF304087} + {83FFB65A-97B1-45AA-BCB8-3F43966BC8A3} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D} EndGlobalSection EndGlobal diff --git a/samples/StatusCodePagesSample/Startup.cs b/samples/StatusCodePagesSample/Startup.cs index 04e7cb71c8..bf5ccb4668 100644 --- a/samples/StatusCodePagesSample/Startup.cs +++ b/samples/StatusCodePagesSample/Startup.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; @@ -25,54 +26,75 @@ namespace StatusCodePagesSample // app.UseStatusCodePagesWithReExecute("/errors/{0}"); // "/[?statuscode=400]" - app.Use((context, next) => + app.Use(async (context, next) => { - if (context.Request.Path.HasValue && !context.Request.Path.Equals(new PathString("/"))) - { - return next(); - } - // Check for ?statuscode=400 var requestedStatusCode = context.Request.Query["statuscode"]; if (!string.IsNullOrEmpty(requestedStatusCode)) { context.Response.StatusCode = int.Parse(requestedStatusCode); - return Task.FromResult(0); + + // To turn off the StatusCode feature - For example the below code turns off the StatusCode middleware + // if the query contains a disableStatusCodePages=true parameter. + var disableStatusCodePages = context.Request.Query["disableStatusCodePages"]; + if (disableStatusCodePages == "true") + { + var statusCodePagesFeature = context.GetFeature(); + if (statusCodePagesFeature != null) + { + statusCodePagesFeature.Enabled = false; + } + } + + await Task.FromResult(0); } - - var builder = new StringBuilder(); - builder.AppendLine(""); - builder.AppendLine("" + - WebUtility.HtmlEncode(context.Request.PathBase.ToString()) + "/missingpage/
"); - - for (int statusCode = 400; statusCode < 600; statusCode++) + else { - builder.AppendLine("" + statusCode + "
"); + await next(); } - builder.AppendLine(""); - return context.Response.SendAsync(builder.ToString(), "text/html"); }); // "/errors/400" - app.Use((context, next) => + app.Map("/errors", error => { - PathString remainder; - if (context.Request.Path.StartsWithSegments(new PathString("/errors"), out remainder)) + error.Run(async context => { var builder = new StringBuilder(); builder.AppendLine(""); - builder.AppendLine("An error occurred, Status Code: " + WebUtility.HtmlEncode(remainder.ToString().Substring(1)) + "
"); + builder.AppendLine("An error occurred, Status Code: " + WebUtility.HtmlEncode(context.Request.Path.ToString().Substring(1)) + "
"); var referrer = context.Request.Headers["referer"]; if (!string.IsNullOrEmpty(referrer)) { builder.AppendLine("Retry " + WebUtility.HtmlEncode(referrer) + "
"); } builder.AppendLine(""); - return context.Response.SendAsync(builder.ToString(), "text/html"); + await context.Response.SendAsync(builder.ToString(), "text/html"); + }); + }); + + app.Run(async context => + { + // Generates the HTML with all status codes. + var builder = new StringBuilder(); + builder.AppendLine(""); + builder.AppendLine("" + + WebUtility.HtmlEncode(context.Request.PathBase.ToString()) + "/missingpage/
"); + + var space = string.Concat(Enumerable.Repeat(" ", 12)); + builder.AppendFormat("
{0}{1}{2}
", "Status Code", space, "Status Code Pages"); + for (int statusCode = 400; statusCode < 600; statusCode++) + { + builder.AppendFormat("{0}{1}{2}{3}
", + statusCode, + space + space, + string.Format("[Enabled]{1}", statusCode, space), + string.Format("[Disabled]{1}", statusCode, space)); } - return next(); + + builder.AppendLine(""); + await context.Response.SendAsync(builder.ToString(), "text/html"); }); } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics.Elm/project.json b/src/Microsoft.AspNet.Diagnostics.Elm/project.json index 4d832c4969..5c7d1770e0 100644 --- a/src/Microsoft.AspNet.Diagnostics.Elm/project.json +++ b/src/Microsoft.AspNet.Diagnostics.Elm/project.json @@ -2,8 +2,7 @@ "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.Diagnostics": "1.0.0-*", - "Microsoft.Framework.Logging.Interfaces": { "version": "1.0.0-*", "type": "build" }, - "Microsoft.Framework.Runtime.Interfaces": { "version": "1.0.0-*", "type": "build" } + "Microsoft.Framework.Logging.Interfaces": "1.0.0-*" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Diagnostics/Compilation/ICompilationException.cs b/src/Microsoft.AspNet.Diagnostics.Interfaces/Compilation/ICompilationException.cs similarity index 91% rename from src/Microsoft.AspNet.Diagnostics/Compilation/ICompilationException.cs rename to src/Microsoft.AspNet.Diagnostics.Interfaces/Compilation/ICompilationException.cs index ba9102a35b..31e9a01347 100644 --- a/src/Microsoft.AspNet.Diagnostics/Compilation/ICompilationException.cs +++ b/src/Microsoft.AspNet.Diagnostics.Interfaces/Compilation/ICompilationException.cs @@ -2,14 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using Microsoft.Framework.Runtime; namespace Microsoft.AspNet.Diagnostics { /// /// Specifies the contract for an exception representing compilation failure. /// - [AssemblyNeutral] public interface ICompilationException { /// diff --git a/src/Microsoft.AspNet.Diagnostics/Compilation/ICompilationFailure.cs b/src/Microsoft.AspNet.Diagnostics.Interfaces/Compilation/ICompilationFailure.cs similarity index 95% rename from src/Microsoft.AspNet.Diagnostics/Compilation/ICompilationFailure.cs rename to src/Microsoft.AspNet.Diagnostics.Interfaces/Compilation/ICompilationFailure.cs index bf16458fc6..ede7bcd270 100644 --- a/src/Microsoft.AspNet.Diagnostics/Compilation/ICompilationFailure.cs +++ b/src/Microsoft.AspNet.Diagnostics.Interfaces/Compilation/ICompilationFailure.cs @@ -2,14 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using Microsoft.Framework.Runtime; namespace Microsoft.AspNet.Diagnostics { /// /// Specifies the contract for a file that fails compilation. /// - [AssemblyNeutral] public interface ICompilationFailure { /// diff --git a/src/Microsoft.AspNet.Diagnostics/Compilation/ICompilationMessage.cs b/src/Microsoft.AspNet.Diagnostics.Interfaces/Compilation/ICompilationMessage.cs similarity index 95% rename from src/Microsoft.AspNet.Diagnostics/Compilation/ICompilationMessage.cs rename to src/Microsoft.AspNet.Diagnostics.Interfaces/Compilation/ICompilationMessage.cs index ed3ca5fed8..237dcd2332 100644 --- a/src/Microsoft.AspNet.Diagnostics/Compilation/ICompilationMessage.cs +++ b/src/Microsoft.AspNet.Diagnostics.Interfaces/Compilation/ICompilationMessage.cs @@ -1,15 +1,12 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.Framework.Runtime; - namespace Microsoft.AspNet.Diagnostics { /// /// Specifies the contract for diagnostic messages produced as result of compiling an instance /// of . /// - [AssemblyNeutral] public interface ICompilationMessage { /// diff --git a/src/Microsoft.AspNet.Diagnostics/IErrorHandlerFeature.cs b/src/Microsoft.AspNet.Diagnostics.Interfaces/IErrorHandlerFeature.cs similarity index 85% rename from src/Microsoft.AspNet.Diagnostics/IErrorHandlerFeature.cs rename to src/Microsoft.AspNet.Diagnostics.Interfaces/IErrorHandlerFeature.cs index b53949b2a9..a231a3585c 100644 --- a/src/Microsoft.AspNet.Diagnostics/IErrorHandlerFeature.cs +++ b/src/Microsoft.AspNet.Diagnostics.Interfaces/IErrorHandlerFeature.cs @@ -2,11 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.Framework.Runtime; namespace Microsoft.AspNet.Diagnostics { - [AssemblyNeutral] public interface IErrorHandlerFeature { Exception Error { get; } diff --git a/src/Microsoft.AspNet.Diagnostics.Interfaces/IStatusCodePagesFeature.cs b/src/Microsoft.AspNet.Diagnostics.Interfaces/IStatusCodePagesFeature.cs new file mode 100644 index 0000000000..f8fa50b8ec --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics.Interfaces/IStatusCodePagesFeature.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Diagnostics +{ + /// + /// Represents the Status code pages feature. + /// + public interface IStatusCodePagesFeature + { + /// + /// Indicates if the status code middleware will handle responses. + /// + bool Enabled { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics/IStatusCodeReExecuteFeature.cs b/src/Microsoft.AspNet.Diagnostics.Interfaces/IStatusCodeReExecuteFeature.cs similarity index 86% rename from src/Microsoft.AspNet.Diagnostics/IStatusCodeReExecuteFeature.cs rename to src/Microsoft.AspNet.Diagnostics.Interfaces/IStatusCodeReExecuteFeature.cs index 241b73b9af..2ea75e5ac9 100644 --- a/src/Microsoft.AspNet.Diagnostics/IStatusCodeReExecuteFeature.cs +++ b/src/Microsoft.AspNet.Diagnostics.Interfaces/IStatusCodeReExecuteFeature.cs @@ -1,11 +1,8 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.Framework.Runtime; - namespace Microsoft.AspNet.Diagnostics { - [AssemblyNeutral] public interface IStatusCodeReExecuteFeature { string OriginalPathBase { get; set; } diff --git a/src/Microsoft.AspNet.Diagnostics.Interfaces/Microsoft.AspNet.Diagnostics.Interfaces.kproj b/src/Microsoft.AspNet.Diagnostics.Interfaces/Microsoft.AspNet.Diagnostics.Interfaces.kproj new file mode 100644 index 0000000000..fea38c9a39 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics.Interfaces/Microsoft.AspNet.Diagnostics.Interfaces.kproj @@ -0,0 +1,20 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + 83ffb65a-97b1-45aa-bcb8-3f43966bc8a3 + Microsoft.AspNet.Diagnostics.Interfaces + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + + 2.0 + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics.Interfaces/project.json b/src/Microsoft.AspNet.Diagnostics.Interfaces/project.json new file mode 100644 index 0000000000..7ceb752a0b --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics.Interfaces/project.json @@ -0,0 +1,13 @@ +{ + "version": "1.0.0-*", + "description": "ASP.NET 5 diagnostics middleware interfaces.", + "compilationOptions": { "warningsAsErrors": true }, + "frameworks": { + "aspnet50": { }, + "aspnetcore50": { + "dependencies": { + "System.Runtime": "4.0.20-beta-*" + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics/StatusCodePagesFeature.cs b/src/Microsoft.AspNet.Diagnostics/StatusCodePagesFeature.cs new file mode 100644 index 0000000000..10bd775088 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/StatusCodePagesFeature.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Diagnostics +{ + /// + /// Represents the Status code pages feature. + /// + public class StatusCodePagesFeature : IStatusCodePagesFeature + { + public bool Enabled { get; set; } = true; + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics/StatusCodePagesMiddleware.cs b/src/Microsoft.AspNet.Diagnostics/StatusCodePagesMiddleware.cs index a123a367bf..f6a17d879f 100644 --- a/src/Microsoft.AspNet.Diagnostics/StatusCodePagesMiddleware.cs +++ b/src/Microsoft.AspNet.Diagnostics/StatusCodePagesMiddleware.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Diagnostics private readonly RequestDelegate _next; private readonly StatusCodePagesOptions _options; - public StatusCodePagesMiddleware(RequestDelegate next, [NotNull]StatusCodePagesOptions options) + public StatusCodePagesMiddleware(RequestDelegate next, StatusCodePagesOptions options) { _next = next; _options = options; @@ -25,8 +25,18 @@ namespace Microsoft.AspNet.Diagnostics public async Task Invoke(HttpContext context) { + var statusCodeFeature = new StatusCodePagesFeature(); + context.SetFeature(statusCodeFeature); + await _next(context); + if (!statusCodeFeature.Enabled) + { + // Check if the feature is still available because other middleware (such as a web API written in MVC) could + // have disabled the feature to prevent HTML status code responses from showing up to an API client. + return; + } + // Do nothing if a response body has already been provided. if (context.Response.HeadersSent || context.Response.StatusCode < 400 diff --git a/src/Microsoft.AspNet.Diagnostics/project.json b/src/Microsoft.AspNet.Diagnostics/project.json index cee4486e1e..bfadf7dffa 100644 --- a/src/Microsoft.AspNet.Diagnostics/project.json +++ b/src/Microsoft.AspNet.Diagnostics/project.json @@ -2,16 +2,16 @@ "version": "1.0.0-*", "description": "ASP.NET 5 Middleware for error handling, error pages, and diagnostics information.", "dependencies": { + "Microsoft.AspNet.Diagnostics.Interfaces": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", - "Microsoft.AspNet.WebUtilities": "1.0.0-*", - "Microsoft.Framework.Runtime.Interfaces": { "version": "1.0.0-*", "type": "build" } + "Microsoft.AspNet.WebUtilities": "1.0.0-*" }, "frameworks": { - "aspnet50": { }, + "aspnet50": {}, "aspnetcore50": { "dependencies": { "System.Reflection.Extensions": "4.0.0-beta-*" } } } -} +} \ No newline at end of file