LCOV - code coverage report
Current view: top level - source/extensions/tracers/xray - util.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 29 31 93.5 %
Date: 2024-01-05 06:35:25 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #include "source/extensions/tracers/xray/util.h"
       2             : 
       3             : #include "absl/strings/ascii.h"
       4             : 
       5             : namespace Envoy {
       6             : namespace Extensions {
       7             : namespace Tracers {
       8             : namespace XRay {
       9             : 
      10             : // AWS X-Ray has two sources of sampling rules (wildcard patterns):
      11             : //
      12             : // 1- The manifest file (static config)
      13             : // 2- The X-Ray Service - periodically polled for new rules. (dynamic config)
      14             : //
      15             : // X-Ray will inspect every single request and try to match it against the set of rules it has to
      16             : // decide whether or not a given request should be sampled. That means this wildcard matching
      17             : // routine is on the hot path. I've spent a great deal of time to make this function optimal and not
      18             : // allocate.
      19             : // Using regex matching here has many downsides and it would require us to:
      20             : // 1- escape/lint the user input pattern to avoid messing up its meaning (think '.' character is a
      21             : // valid regex and URL character) 2- compile the regex and store it with every corresponding part of
      22             : // the rule
      23             : //
      24             : // Those two steps would add significant overhead to the tracer. Meanwhile, the following function
      25             : // has a comprehensive test suite and fuzz tests.
      26          77 : bool wildcardMatch(absl::string_view pattern, absl::string_view input) {
      27          77 :   if (pattern.empty()) {
      28           0 :     return input.empty();
      29           0 :   }
      30             : 
      31             :   // Check the special case of a single * pattern, as it's common.
      32          77 :   constexpr char glob = '*';
      33          77 :   if (pattern.size() == 1 && pattern[0] == glob) {
      34           5 :     return true;
      35           5 :   }
      36             : 
      37          72 :   size_t i = 0, p = 0, i_star = input.size(), p_star = 0;
      38        2593 :   while (i < input.size()) {
      39        2537 :     if (p < pattern.size() && absl::ascii_tolower(input[i]) == absl::ascii_tolower(pattern[p])) {
      40        1158 :       ++i;
      41        1158 :       ++p;
      42        1379 :     } else if (p < pattern.size() && '?' == pattern[p]) {
      43         300 :       ++i;
      44         300 :       ++p;
      45        1079 :     } else if (p < pattern.size() && pattern[p] == glob) {
      46         217 :       i_star = i;
      47         217 :       p_star = p++;
      48         862 :     } else if (i_star != input.size()) {
      49         846 :       i = ++i_star;
      50         846 :       p = p_star + 1;
      51         846 :     } else {
      52          16 :       return false;
      53          16 :     }
      54        2537 :   }
      55             : 
      56          90 :   while (p < pattern.size() && pattern[p] == glob) {
      57          34 :     ++p;
      58          34 :   }
      59             : 
      60          56 :   return p == pattern.size() && i == input.size();
      61          72 : }
      62             : 
      63             : } // namespace XRay
      64             : } // namespace Tracers
      65             : } // namespace Extensions
      66             : } // namespace Envoy

Generated by: LCOV version 1.15