From 5e9e3a857418cb3cd0c6c18be8c5ed86984cffad Mon Sep 17 00:00:00 2001 From: Tornhoof Date: Wed, 29 Nov 2017 21:30:27 +0100 Subject: [PATCH] Make sure to add whitespace after the status code even if the reasonphrase is empty (#2184) --- .../Internal/Http/ReasonPhrases.cs | 6 +++-- test/Kestrel.Core.Tests/ReasonPhrasesTests.cs | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 test/Kestrel.Core.Tests/ReasonPhrasesTests.cs diff --git a/src/Kestrel.Core/Internal/Http/ReasonPhrases.cs b/src/Kestrel.Core/Internal/Http/ReasonPhrases.cs index 36eaaacf87..d372113bda 100644 --- a/src/Kestrel.Core/Internal/Http/ReasonPhrases.cs +++ b/src/Kestrel.Core/Internal/Http/ReasonPhrases.cs @@ -222,9 +222,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http default: var predefinedReasonPhrase = WebUtilities.ReasonPhrases.GetReasonPhrase(statusCode); + // https://tools.ietf.org/html/rfc7230#section-3.1.2 requires trailing whitespace regardless of reason phrase + var formattedStatusCode = statusCode.ToString(CultureInfo.InvariantCulture) + " "; return string.IsNullOrEmpty(predefinedReasonPhrase) - ? Encoding.ASCII.GetBytes(statusCode.ToString(CultureInfo.InvariantCulture)) - : Encoding.ASCII.GetBytes(statusCode.ToString(CultureInfo.InvariantCulture) + " " + predefinedReasonPhrase); + ? Encoding.ASCII.GetBytes(formattedStatusCode) + : Encoding.ASCII.GetBytes(formattedStatusCode + predefinedReasonPhrase); } } diff --git a/test/Kestrel.Core.Tests/ReasonPhrasesTests.cs b/test/Kestrel.Core.Tests/ReasonPhrasesTests.cs new file mode 100644 index 0000000000..9a7957735b --- /dev/null +++ b/test/Kestrel.Core.Tests/ReasonPhrasesTests.cs @@ -0,0 +1,24 @@ +// 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 Xunit; +using Microsoft.AspNetCore.Http; +using System.Text; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests +{ + public class ReasonPhraseTests + { + [Theory] + [InlineData(999, "Unknown", "999 Unknown")] + [InlineData(999, null, "999 ")] + [InlineData(StatusCodes.Status200OK, "OK", "200 OK")] + [InlineData(StatusCodes.Status200OK, null, "200 OK")] + public void Formatting(int statusCode, string reasonPhrase, string expectedResult) + { + var bytes = Internal.Http.ReasonPhrases.ToStatusBytes(statusCode, reasonPhrase); + Assert.NotNull(bytes); + Assert.Equal(expectedResult, Encoding.ASCII.GetString(bytes)); + } + } +} \ No newline at end of file