Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/common/router/config_utility.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/common/router/config_utility.h"
2
3
#include <string>
4
#include <vector>
5
6
#include "envoy/config/core/v3/base.pb.h"
7
#include "envoy/config/route/v3/route_components.pb.h"
8
#include "envoy/type/matcher/v3/string.pb.h"
9
10
#include "source/common/common/assert.h"
11
#include "source/common/common/regex.h"
12
#include "source/common/config/datasource.h"
13
14
namespace Envoy {
15
namespace Router {
16
namespace {
17
18
absl::optional<Matchers::StringMatcherImpl<envoy::type::matcher::v3::StringMatcher>>
19
18.3k
maybeCreateStringMatcher(const envoy::config::route::v3::QueryParameterMatcher& config) {
20
18.3k
  switch (config.query_parameter_match_specifier_case()) {
21
1.08k
  case envoy::config::route::v3::QueryParameterMatcher::QueryParameterMatchSpecifierCase::
22
1.08k
      kStringMatch:
23
1.08k
    return Matchers::StringMatcherImpl(config.string_match());
24
1.36k
  case envoy::config::route::v3::QueryParameterMatcher::QueryParameterMatchSpecifierCase::
25
1.36k
      kPresentMatch:
26
1.36k
    return absl::nullopt;
27
15.8k
  case envoy::config::route::v3::QueryParameterMatcher::QueryParameterMatchSpecifierCase::
28
15.8k
      QUERY_PARAMETER_MATCH_SPECIFIER_NOT_SET:
29
15.8k
    return absl::nullopt;
30
18.3k
  }
31
32
0
  return absl::nullopt;
33
18.3k
}
34
35
} // namespace
36
37
ConfigUtility::QueryParameterMatcher::QueryParameterMatcher(
38
    const envoy::config::route::v3::QueryParameterMatcher& config)
39
18.3k
    : name_(config.name()), matcher_(maybeCreateStringMatcher(config)) {}
40
41
bool ConfigUtility::QueryParameterMatcher::matches(
42
6.47k
    const Http::Utility::QueryParamsMulti& request_query_params) const {
43
  // This preserves the legacy behavior of ignoring all but the first value for a given key
44
6.47k
  auto data = request_query_params.getFirstValue(name_);
45
6.47k
  if (!data.has_value()) {
46
4.38k
    return false;
47
4.38k
  }
48
49
2.08k
  if (!matcher_.has_value()) {
50
    // Present check
51
1.89k
    return true;
52
1.89k
  }
53
54
187
  return matcher_.value().match(data.value());
55
2.08k
}
56
57
Upstream::ResourcePriority
58
84.5k
ConfigUtility::parsePriority(const envoy::config::core::v3::RoutingPriority& priority) {
59
84.5k
  switch (priority) {
60
0
    PANIC_ON_PROTO_ENUM_SENTINEL_VALUES;
61
80.8k
  case envoy::config::core::v3::DEFAULT:
62
80.8k
    return Upstream::ResourcePriority::Default;
63
3.72k
  case envoy::config::core::v3::HIGH:
64
3.72k
    return Upstream::ResourcePriority::High;
65
84.5k
  }
66
0
  PANIC_DUE_TO_CORRUPT_ENUM;
67
0
}
68
69
bool ConfigUtility::matchQueryParams(
70
    const Http::Utility::QueryParamsMulti& query_params,
71
5.61k
    const std::vector<QueryParameterMatcherPtr>& config_query_params) {
72
6.47k
  for (const auto& config_query_param : config_query_params) {
73
6.47k
    if (!config_query_param->matches(query_params)) {
74
4.49k
      return false;
75
4.49k
    }
76
6.47k
  }
77
78
1.12k
  return true;
79
5.61k
}
80
81
Http::Code ConfigUtility::parseRedirectResponseCode(
82
50.1k
    const envoy::config::route::v3::RedirectAction::RedirectResponseCode& code) {
83
50.1k
  switch (code) {
84
0
    PANIC_ON_PROTO_ENUM_SENTINEL_VALUES;
85
38.8k
  case envoy::config::route::v3::RedirectAction::MOVED_PERMANENTLY:
86
38.8k
    return Http::Code::MovedPermanently;
87
2.97k
  case envoy::config::route::v3::RedirectAction::FOUND:
88
2.97k
    return Http::Code::Found;
89
2.98k
  case envoy::config::route::v3::RedirectAction::SEE_OTHER:
90
2.98k
    return Http::Code::SeeOther;
91
1.54k
  case envoy::config::route::v3::RedirectAction::TEMPORARY_REDIRECT:
92
1.54k
    return Http::Code::TemporaryRedirect;
93
3.77k
  case envoy::config::route::v3::RedirectAction::PERMANENT_REDIRECT:
94
3.77k
    return Http::Code::PermanentRedirect;
95
50.1k
  }
96
0
  PANIC_DUE_TO_CORRUPT_ENUM;
97
0
}
98
99
absl::optional<Http::Code>
100
84.5k
ConfigUtility::parseDirectResponseCode(const envoy::config::route::v3::Route& route) {
101
84.5k
  if (route.has_redirect()) {
102
50.1k
    return parseRedirectResponseCode(route.redirect().response_code());
103
50.1k
  } else if (route.has_direct_response()) {
104
6.07k
    return static_cast<Http::Code>(route.direct_response().status());
105
6.07k
  }
106
28.3k
  return {};
107
84.5k
}
108
109
std::string ConfigUtility::parseDirectResponseBody(const envoy::config::route::v3::Route& route,
110
84.6k
                                                   Api::Api& api, uint32_t max_body_size_bytes) {
111
84.6k
  if (!route.has_direct_response() || !route.direct_response().has_body()) {
112
82.7k
    return EMPTY_STRING;
113
82.7k
  }
114
1.93k
  const auto& body = route.direct_response().body();
115
116
1.93k
  const std::string string_body =
117
1.93k
      Envoy::Config::DataSource::read(body, true, api, max_body_size_bytes);
118
1.93k
  if (string_body.length() > max_body_size_bytes) {
119
11
    throwEnvoyExceptionOrPanic(fmt::format("response body size is {} bytes; maximum is {}",
120
11
                                           string_body.length(), max_body_size_bytes));
121
11
  }
122
1.92k
  return string_body;
123
1.93k
}
124
125
Http::Code ConfigUtility::parseClusterNotFoundResponseCode(
126
84.5k
    const envoy::config::route::v3::RouteAction::ClusterNotFoundResponseCode& code) {
127
84.5k
  switch (code) {
128
0
    PANIC_ON_PROTO_ENUM_SENTINEL_VALUES;
129
78.1k
  case envoy::config::route::v3::RouteAction::SERVICE_UNAVAILABLE:
130
78.1k
    return Http::Code::ServiceUnavailable;
131
3.39k
  case envoy::config::route::v3::RouteAction::NOT_FOUND:
132
3.39k
    return Http::Code::NotFound;
133
3.02k
  case envoy::config::route::v3::RouteAction::INTERNAL_SERVER_ERROR:
134
3.02k
    return Http::Code::InternalServerError;
135
84.5k
  }
136
0
  PANIC_DUE_TO_CORRUPT_ENUM;
137
0
}
138
139
} // namespace Router
140
} // namespace Envoy