Skip to content

[Hosting] Add {OriginalFormat} to start & stop log state objects #45253

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ internal sealed class HostingRequestFinishedLog : IReadOnlyList<KeyValuePair<str
{
internal static readonly Func<object, Exception?, string> 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<string, object?> this[int index]
{
Expand All @@ -42,6 +43,7 @@ internal sealed class HostingRequestFinishedLog : IReadOnlyList<KeyValuePair<str
8 => new KeyValuePair<string, object?>(nameof(request.PathBase), request.PathBase.Value),
9 => new KeyValuePair<string, object?>(nameof(request.Path), request.Path.Value),
10 => new KeyValuePair<string, object?>(nameof(request.QueryString), request.QueryString.Value),
11 => new KeyValuePair<string, object?>("{OriginalFormat}", OriginalFormat),
_ => throw new IndexOutOfRangeException(nameof(index)),
};
}
Expand All @@ -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;
Expand Down
10 changes: 4 additions & 6 deletions src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Hosting;

internal sealed class HostingRequestStartingLog : IReadOnlyList<KeyValuePair<string, object?>>
{
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<object, Exception?, string> Callback = (state, exception) => ((HostingRequestStartingLog)state).ToString();
Expand All @@ -18,7 +18,7 @@ internal sealed class HostingRequestStartingLog : IReadOnlyList<KeyValuePair<str

private string? _cachedToString;

public int Count => 9;
public int Count => 10;

public KeyValuePair<string, object?> this[int index] => index switch
{
Expand All @@ -31,6 +31,7 @@ internal sealed class HostingRequestStartingLog : IReadOnlyList<KeyValuePair<str
6 => new KeyValuePair<string, object?>(nameof(_request.PathBase), _request.PathBase.Value),
7 => new KeyValuePair<string, object?>(nameof(_request.Path), _request.Path.Value),
8 => new KeyValuePair<string, object?>(nameof(_request.QueryString), _request.QueryString.Value),
9 => new KeyValuePair<string, object?>("{OriginalFormat}", OriginalFormat),
_ => throw new IndexOutOfRangeException(nameof(index)),
};

Expand All @@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<HttpRequest>();
Expand Down