LCOV - code coverage report
Current view: top level - lib/src/util - header_redaction.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 14 14
Test Date: 2026-08-27 23:42:02 Functions: - 0 0

            Line data    Source code
       1              : // Copyright The OpenTelemetry Authors
       2              : // SPDX-License-Identifier: Apache-2.0
       3              : 
       4              : /// Redaction of header values written to the debug log.
       5              : ///
       6              : /// Which OTLP header holds a credential depends on the backend
       7              : /// (`authorization`, `x-api-key`, `x-honeycomb-team`, `dd-api-key`), so a list
       8              : /// of names to hide leaks anything not on it. This is the other way round: an
       9              : /// allowlist of names whose values are safe to print, everything else redacted.
      10              : ///
      11              : /// Only values are opted in. Header names and the header count are always
      12              : /// logged, so the default empty allowlist still shows which headers are
      13              : /// configured.
      14              : library;
      15              : 
      16              : /// Written in place of a header value that is not allowed to be logged.
      17              : ///
      18              : /// Without the value length, which would narrow the search space for the token.
      19              : const String redactedHeaderPlaceholder = '[REDACTED]';
      20              : 
      21              : /// Header names whose values are never logged, whatever the allowlist says.
      22              : const Set<String> alwaysRedactedHeaderNames = <String>{
      23              :   'authorization',
      24              :   'proxy-authorization',
      25              : };
      26              : 
      27           42 : Set<String> _allowedHeaderNames = const <String>{};
      28              : 
      29              : /// The header names whose values are currently allowed to be logged.
      30              : ///
      31              : /// Lowercased, and never contains a name in [alwaysRedactedHeaderNames].
      32            2 : Set<String> get allowedHeaderLogNames => _allowedHeaderNames;
      33              : 
      34              : /// Sets the header names whose values may be logged, replacing any previous
      35              : /// allowlist rather than adding to it.
      36              : ///
      37              : /// Names are lowercased here so [redactHeaderValue] only has to lowercase its
      38              : /// argument. Null or empty restores the default of redacting every value.
      39          154 : void configureHeaderLogAllowlist(Iterable<String>? headerNames) {
      40              :   if (headerNames == null) {
      41              :     _allowedHeaderNames = const <String>{};
      42              :     return;
      43              :   }
      44              :   _allowedHeaderNames = <String>{
      45          154 :     for (final name in headerNames)
      46            4 :       if (name.trim().isNotEmpty) name.trim().toLowerCase(),
      47          154 :   }..removeAll(alwaysRedactedHeaderNames);
      48              : }
      49              : 
      50              : /// Parses the comma separated form used by the environment variable.
      51              : ///
      52              : /// Entries are trimmed, empty ones are dropped, and the result is a set, so
      53              : /// `" x-trace-id , ,X-Trace-Id "` gives `{'x-trace-id'}`.
      54          154 : Set<String> parseHeaderLogAllowlist(String? value) {
      55              :   if (value == null) {
      56              :     return const <String>{};
      57              :   }
      58              :   return <String>{
      59            1 :     for (final name in value.split(','))
      60            4 :       if (name.trim().isNotEmpty) name.trim().toLowerCase(),
      61            1 :   }..removeAll(alwaysRedactedHeaderNames);
      62              : }
      63              : 
      64              : /// Returns [value] when [name] is allowed to be logged, and
      65              : /// [redactedHeaderPlaceholder] otherwise.
      66           40 : String redactHeaderValue(String name, String value) {
      67          120 :   return _allowedHeaderNames.contains(name.toLowerCase())
      68              :       ? value
      69              :       : redactedHeaderPlaceholder;
      70              : }
      71              : 
      72              : /// Formats one header for the debug log as `name: value-or-placeholder`.
      73           40 : String formatHeaderForLog(String name, String value) {
      74           80 :   return '$name: ${redactHeaderValue(name, value)}';
      75              : }
        

Generated by: LCOV version 2.0-1