| File: Logging\RequestHeadersLogEnricher.cs | Web Access |
| Project: src\src\Libraries\Microsoft.AspNetCore.Diagnostics.Middleware\Microsoft.AspNetCore.Diagnostics.Middleware.csproj (Microsoft.AspNetCore.Diagnostics.Middleware) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Compliance.Classification; using Microsoft.Extensions.Compliance.Redaction; using Microsoft.Extensions.Diagnostics.Enrichment; using Microsoft.Extensions.Options; using Microsoft.Shared.Diagnostics; namespace Microsoft.AspNetCore.Diagnostics.Logging; /// <summary> /// Enriches logs with Request headers information. /// </summary> internal sealed class RequestHeadersLogEnricher : ILogEnricher { private readonly KeyValuePair<string, DataClassification>[] _headersDataClasses; private readonly string[] _normalizedHeaders; private readonly IHttpContextAccessor _httpContextAccessor; private readonly IRedactorProvider? _redactorProvider; /// <summary> /// Initializes a new instance of the <see cref="RequestHeadersLogEnricher"/> class. /// </summary> /// <param name="httpContextAccessor">HttpContextAccessor responsible for obtaining properties from HTTP context.</param> /// <param name="options">Options to customize configuration of <see cref="RequestHeadersLogEnricher"/>.</param> /// <param name="redactorProvider">RedactorProvider to get redactor to redact enriched data according to the data class.</param> public RequestHeadersLogEnricher(IHttpContextAccessor httpContextAccessor, IOptions<RequestHeadersLogEnricherOptions> options, IRedactorProvider? redactorProvider = null) { var opt = Throw.IfMemberNull(options, options.Value); _httpContextAccessor = httpContextAccessor; _headersDataClasses = opt.HeadersDataClasses.Count == 0 ? [] : opt.HeadersDataClasses.ToArray(); _normalizedHeaders = HeaderNormalizer.PrepareNormalizedHeaderNames(_headersDataClasses, HttpLoggingTagNames.RequestHeaderPrefix); if (_headersDataClasses.Length > 0) { _redactorProvider = Throw.IfNull(redactorProvider); } } public void Enrich(IEnrichmentTagCollector collector) { try { if (_httpContextAccessor.HttpContext?.Request == null) { return; } var request = _httpContextAccessor.HttpContext.Request; if (_headersDataClasses.Length == 0) { return; } if (_headersDataClasses.Length != 0) { for (int i = 0; i < _headersDataClasses.Length; i++) { var header = _headersDataClasses[i]; if (request.Headers.TryGetValue(header.Key, out var headerValue) && !string.IsNullOrEmpty(headerValue)) { var redactor = _redactorProvider!.GetRedactor(header.Value); var redacted = redactor.Redact(headerValue); collector.Add(_normalizedHeaders[i], redacted); } } } } catch (ObjectDisposedException) { // Noop. } } }