diff --git a/src/Hosting/Hosting/src/Internal/HostingRequestFinishedLog.cs b/src/Hosting/Hosting/src/Internal/HostingRequestFinishedLog.cs index f22edd59cf4e..65feb02a5d5c 100644 --- a/src/Hosting/Hosting/src/Internal/HostingRequestFinishedLog.cs +++ b/src/Hosting/Hosting/src/Internal/HostingRequestFinishedLog.cs @@ -13,12 +13,13 @@ internal sealed class HostingRequestFinishedLog : IReadOnlyList Callback = (state, exception) => ((HostingRequestFinishedLog)state).ToString(); + private const string OriginalFormat = "Request finished {Protocol} {Method} {Scheme}://{Host}{PathBase}{Path}{QueryString} - {StatusCode} {ContentLength} {ContentType} {ElapsedMilliseconds}ms"; private readonly HostingApplication.Context _context; private string? _cachedToString; public TimeSpan Elapsed { get; } - public int Count => 11; + public int Count => 12; public KeyValuePair this[int index] { @@ -42,6 +43,7 @@ internal sealed class HostingRequestFinishedLog : IReadOnlyList new KeyValuePair(nameof(request.PathBase), request.PathBase.Value), 9 => new KeyValuePair(nameof(request.Path), request.Path.Value), 10 => new KeyValuePair(nameof(request.QueryString), request.QueryString.Value), + 11 => new KeyValuePair("{OriginalFormat}", OriginalFormat), _ => throw new IndexOutOfRangeException(nameof(index)), }; } @@ -57,10 +59,11 @@ public override string ToString() { if (_cachedToString == null) { - Debug.Assert(_context.HttpContext != null && _context.StartLog != null); + Debug.Assert(_context.HttpContext != null); + var request = _context.HttpContext.Request; var response = _context.HttpContext.Response; - _cachedToString = $"Request finished {_context.StartLog.ToStringWithoutPreamble()} - {response.StatusCode.ToString(CultureInfo.InvariantCulture)} {ValueOrEmptyMarker(response.ContentLength)} {EscapedValueOrEmptyMarker(response.ContentType)} {Elapsed.TotalMilliseconds.ToString("0.0000", CultureInfo.InvariantCulture)}ms"; + _cachedToString = $"Request finished {request.Protocol} {request.Method} {request.Scheme}://{request.Host.Value}{request.PathBase.Value}{request.Path.Value}{request.QueryString.Value} - {response.StatusCode.ToString(CultureInfo.InvariantCulture)} {ValueOrEmptyMarker(response.ContentLength)} {EscapedValueOrEmptyMarker(response.ContentType)} {Elapsed.TotalMilliseconds.ToString("0.0000", CultureInfo.InvariantCulture)}ms"; } return _cachedToString; diff --git a/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs b/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs index 9cc4a03ebcb2..68af45f74144 100644 --- a/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs +++ b/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Hosting; internal sealed class HostingRequestStartingLog : IReadOnlyList> { - private const string LogPreamble = "Request starting "; + private const string OriginalFormat = "Request starting {Protocol} {Method} {Scheme}://{Host}{PathBase}{Path}{QueryString} - {ContentType} {ContentLength}"; private const string EmptyEntry = "-"; internal static readonly Func Callback = (state, exception) => ((HostingRequestStartingLog)state).ToString(); @@ -18,7 +18,7 @@ internal sealed class HostingRequestStartingLog : IReadOnlyList 9; + public int Count => 10; public KeyValuePair this[int index] => index switch { @@ -31,6 +31,7 @@ internal sealed class HostingRequestStartingLog : IReadOnlyList new KeyValuePair(nameof(_request.PathBase), _request.PathBase.Value), 7 => new KeyValuePair(nameof(_request.Path), _request.Path.Value), 8 => new KeyValuePair(nameof(_request.QueryString), _request.QueryString.Value), + 9 => new KeyValuePair("{OriginalFormat}", OriginalFormat), _ => throw new IndexOutOfRangeException(nameof(index)), }; @@ -44,7 +45,7 @@ public override string ToString() if (_cachedToString == null) { var request = _request; - _cachedToString = $"{LogPreamble}{request.Protocol} {request.Method} {request.Scheme}://{request.Host.Value}{request.PathBase.Value}{request.Path.Value}{request.QueryString.Value} {EscapedValueOrEmptyMarker(request.ContentType)} {ValueOrEmptyMarker(request.ContentLength)}"; + _cachedToString = $"Request starting {request.Protocol} {request.Method} {request.Scheme}://{request.Host.Value}{request.PathBase.Value}{request.Path.Value}{request.QueryString.Value} - {EscapedValueOrEmptyMarker(request.ContentType)} {ValueOrEmptyMarker(request.ContentLength)}"; } return _cachedToString; @@ -63,9 +64,6 @@ IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); } - internal string ToStringWithoutPreamble() - => ToString().Substring(LogPreamble.Length); - internal static string EscapedValueOrEmptyMarker(string? potentialValue) // Encode space as + => potentialValue?.Length > 0 ? potentialValue.Replace(' ', '+') : EmptyEntry; diff --git a/src/Hosting/Hosting/test/Internal/HostingRequestStartLogTests.cs b/src/Hosting/Hosting/test/Internal/HostingRequestStartLogTests.cs index da6b851b6412..689ad9186ace 100644 --- a/src/Hosting/Hosting/test/Internal/HostingRequestStartLogTests.cs +++ b/src/Hosting/Hosting/test/Internal/HostingRequestStartLogTests.cs @@ -9,8 +9,8 @@ namespace Microsoft.AspNetCore.Hosting.Tests; public class HostingRequestStartLogTests { [Theory] - [InlineData(",XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "Request starting GET 1.1 http://,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX//?query test 0")] - [InlineData(" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "Request starting GET 1.1 http:// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX//?query test 0")] + [InlineData(",XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "Request starting GET 1.1 http://,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX//?query - test 0")] + [InlineData(" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "Request starting GET 1.1 http:// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX//?query - test 0")] public void InvalidHttpContext_DoesNotThrowOnAccessingProperties(string input, string expected) { var mockRequest = new Mock();