diff --git a/src/Microsoft.AspNetCore.Diagnostics/StatusCodePage/StatusCodePagesOptions.cs b/src/Microsoft.AspNetCore.Diagnostics/StatusCodePage/StatusCodePagesOptions.cs index 37a8b92360..0e3e53e8a3 100644 --- a/src/Microsoft.AspNetCore.Diagnostics/StatusCodePage/StatusCodePagesOptions.cs +++ b/src/Microsoft.AspNetCore.Diagnostics/StatusCodePage/StatusCodePagesOptions.cs @@ -20,15 +20,29 @@ namespace Microsoft.AspNetCore.Builder HandleAsync = context => { // TODO: Render with a pre-compiled html razor view. - // Note the 500 spaces are to work around an IE 'feature' var statusCode = context.HttpContext.Response.StatusCode; - var body = string.Format(CultureInfo.InvariantCulture, "Status Code: {0}; {1}", - statusCode, ReasonPhrases.GetReasonPhrase(statusCode)) + new string(' ', 500); + + var body = BuildResponseBody(statusCode); + context.HttpContext.Response.ContentType = "text/plain"; return context.HttpContext.Response.WriteAsync(body); }; } + private string BuildResponseBody(int httpStatusCode) + { + // Note the 500 spaces are to work around an IE 'feature' + string internetExplorerWorkaround = new string(' ', 500); + + var reasonPhrase = ReasonPhrases.GetReasonPhrase(httpStatusCode); + + return string.Format(CultureInfo.InvariantCulture, "Status Code: {0}{1}{2}{3}", + httpStatusCode, + string.IsNullOrWhiteSpace(reasonPhrase) ? "" : "; ", + reasonPhrase, + internetExplorerWorkaround); + } + public Func HandleAsync { get; set; } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Diagnostics.FunctionalTests/StatusCodeSampleTest.cs b/test/Microsoft.AspNetCore.Diagnostics.FunctionalTests/StatusCodeSampleTest.cs index 1ff77bb6b6..058f33dade 100644 --- a/test/Microsoft.AspNetCore.Diagnostics.FunctionalTests/StatusCodeSampleTest.cs +++ b/test/Microsoft.AspNetCore.Diagnostics.FunctionalTests/StatusCodeSampleTest.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 Microsoft.AspNetCore.WebUtilities; using System.Net; using System.Net.Http; using System.Threading.Tasks; @@ -31,5 +32,45 @@ namespace Microsoft.AspNetCore.Diagnostics.FunctionalTests Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Contains("Status Code: 417", body); } + + [Fact] + public async Task StatusCodePageOptions_ExcludesSemicolon_WhenReasonPhrase_IsUnknown() + { + //Arrange + var httpStatusCode = 541; + var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost/?statuscode={httpStatusCode}"); + + //Act + var response = await Client.SendAsync(request); + + var statusCode = response.StatusCode; + + var responseBody = await response.Content.ReadAsStringAsync(); + + //Assert + Assert.Equal((HttpStatusCode)httpStatusCode, response.StatusCode); + Assert.DoesNotContain(";", responseBody); + } + + [Fact] + public async Task StatusCodePageOptions_IncludesSemicolon__AndReasonPhrase_WhenReasonPhrase_IsKnown() + { + //Arrange + var httpStatusCode = 400; + var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost/?statuscode={httpStatusCode}"); + + //Act + var response = await Client.SendAsync(request); + + var statusCode = response.StatusCode; + var statusCodeReasonPhrase = ReasonPhrases.GetReasonPhrase(httpStatusCode); + + var responseBody = await response.Content.ReadAsStringAsync(); + + //Assert + Assert.Equal((HttpStatusCode)httpStatusCode, response.StatusCode); + Assert.Contains(";", responseBody); + Assert.Contains(statusCodeReasonPhrase, responseBody); + } } -} +} \ No newline at end of file