Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/extensions/filters/common/fault/fault_config.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/extensions/filters/common/fault/fault_config.h"
2
3
#include "envoy/extensions/filters/common/fault/v3/fault.pb.h"
4
#include "envoy/extensions/filters/http/fault/v3/fault.pb.h"
5
6
#include "source/common/protobuf/utility.h"
7
8
namespace Envoy {
9
namespace Extensions {
10
namespace Filters {
11
namespace Common {
12
namespace Fault {
13
14
envoy::type::v3::FractionalPercent
15
573
HeaderPercentageProvider::percentage(const Http::RequestHeaderMap* request_headers) const {
16
573
  if (request_headers == nullptr) {
17
    // If request_headers is nullptr, return the default percentage.
18
572
    return percentage_;
19
572
  }
20
1
  const auto header = request_headers->get(header_name_);
21
1
  if (header.empty()) {
22
1
    return percentage_;
23
1
  }
24
25
0
  uint32_t header_numerator;
26
  // This is an implicitly untrusted header, so per the API documentation only the first
27
  // value is used.
28
0
  if (!absl::SimpleAtoi(header[0]->value().getStringView(), &header_numerator)) {
29
0
    return percentage_;
30
0
  }
31
32
0
  envoy::type::v3::FractionalPercent result;
33
0
  result.set_numerator(std::min(header_numerator, percentage_.numerator()));
34
0
  result.set_denominator(percentage_.denominator());
35
0
  return result;
36
0
}
37
38
FaultAbortConfig::FaultAbortConfig(
39
0
    const envoy::extensions::filters::http::fault::v3::FaultAbort& abort_config) {
40
0
  switch (abort_config.error_type_case()) {
41
0
  case envoy::extensions::filters::http::fault::v3::FaultAbort::ErrorTypeCase::kHttpStatus:
42
0
    provider_ =
43
0
        std::make_unique<FixedAbortProvider>(static_cast<Http::Code>(abort_config.http_status()),
44
0
                                             absl::nullopt, abort_config.percentage());
45
0
    break;
46
0
  case envoy::extensions::filters::http::fault::v3::FaultAbort::ErrorTypeCase::kGrpcStatus:
47
0
    provider_ = std::make_unique<FixedAbortProvider>(
48
0
        absl::nullopt, static_cast<Grpc::Status::GrpcStatus>(abort_config.grpc_status()),
49
0
        abort_config.percentage());
50
0
    break;
51
0
  case envoy::extensions::filters::http::fault::v3::FaultAbort::ErrorTypeCase::kHeaderAbort:
52
0
    provider_ = std::make_unique<HeaderAbortProvider>(abort_config.percentage());
53
0
    break;
54
0
  case envoy::extensions::filters::http::fault::v3::FaultAbort::ErrorTypeCase::ERROR_TYPE_NOT_SET:
55
0
    PANIC("not set");
56
0
  }
57
0
}
58
59
absl::optional<Http::Code> FaultAbortConfig::HeaderAbortProvider::httpStatusCode(
60
0
    const Http::RequestHeaderMap* request_headers) const {
61
0
  absl::optional<Http::Code> ret = absl::nullopt;
62
0
  auto header = request_headers->get(Filters::Common::Fault::HeaderNames::get().AbortRequest);
63
0
  if (header.empty()) {
64
0
    return ret;
65
0
  }
66
67
0
  uint64_t code;
68
  // This is an implicitly untrusted header, so per the API documentation only the first
69
  // value is used.
70
0
  if (!absl::SimpleAtoi(header[0]->value().getStringView(), &code)) {
71
0
    return ret;
72
0
  }
73
74
0
  if (code >= 200 && code < 600) {
75
0
    ret = static_cast<Http::Code>(code);
76
0
  }
77
78
0
  return ret;
79
0
}
80
81
absl::optional<Grpc::Status::GrpcStatus> FaultAbortConfig::HeaderAbortProvider::grpcStatusCode(
82
0
    const Http::RequestHeaderMap* request_headers) const {
83
0
  auto header = request_headers->get(Filters::Common::Fault::HeaderNames::get().AbortGrpcRequest);
84
0
  if (header.empty()) {
85
0
    return absl::nullopt;
86
0
  }
87
88
0
  uint64_t code;
89
  // This is an implicitly untrusted header, so per the API documentation only the first
90
  // value is used.
91
0
  if (!absl::SimpleAtoi(header[0]->value().getStringView(), &code)) {
92
0
    return absl::nullopt;
93
0
  }
94
95
0
  return static_cast<Grpc::Status::GrpcStatus>(code);
96
0
}
97
98
FaultDelayConfig::FaultDelayConfig(
99
122
    const envoy::extensions::filters::common::fault::v3::FaultDelay& delay_config) {
100
122
  switch (delay_config.fault_delay_secifier_case()) {
101
31
  case envoy::extensions::filters::common::fault::v3::FaultDelay::FaultDelaySecifierCase::
102
31
      kFixedDelay:
103
31
    provider_ = std::make_unique<FixedDelayProvider>(
104
31
        std::chrono::milliseconds(PROTOBUF_GET_MS_REQUIRED(delay_config, fixed_delay)),
105
31
        delay_config.percentage());
106
31
    break;
107
91
  case envoy::extensions::filters::common::fault::v3::FaultDelay::FaultDelaySecifierCase::
108
91
      kHeaderDelay:
109
91
    provider_ = std::make_unique<HeaderDelayProvider>(delay_config.percentage());
110
91
    break;
111
0
  case envoy::extensions::filters::common::fault::v3::FaultDelay::FaultDelaySecifierCase::
112
0
      FAULT_DELAY_SECIFIER_NOT_SET:
113
0
    PANIC("not set");
114
122
  }
115
122
}
116
117
absl::optional<std::chrono::milliseconds> FaultDelayConfig::HeaderDelayProvider::duration(
118
0
    const Http::RequestHeaderMap* request_headers) const {
119
0
  const auto header = request_headers->get(HeaderNames::get().DelayRequest);
120
0
  if (header.empty()) {
121
0
    return absl::nullopt;
122
0
  }
123
124
0
  uint64_t value;
125
  // This is an implicitly untrusted header, so per the API documentation only the first
126
  // value is used.
127
0
  if (!absl::SimpleAtoi(header[0]->value().getStringView(), &value)) {
128
0
    return absl::nullopt;
129
0
  }
130
131
0
  return std::chrono::milliseconds(value);
132
0
}
133
134
FaultRateLimitConfig::FaultRateLimitConfig(
135
1
    const envoy::extensions::filters::common::fault::v3::FaultRateLimit& rate_limit_config) {
136
1
  switch (rate_limit_config.limit_type_case()) {
137
0
  case envoy::extensions::filters::common::fault::v3::FaultRateLimit::LimitTypeCase::kFixedLimit:
138
0
    provider_ = std::make_unique<FixedRateLimitProvider>(
139
0
        rate_limit_config.fixed_limit().limit_kbps(), rate_limit_config.percentage());
140
0
    break;
141
1
  case envoy::extensions::filters::common::fault::v3::FaultRateLimit::LimitTypeCase::kHeaderLimit:
142
1
    provider_ = std::make_unique<HeaderRateLimitProvider>(rate_limit_config.percentage());
143
1
    break;
144
0
  case envoy::extensions::filters::common::fault::v3::FaultRateLimit::LimitTypeCase::
145
0
      LIMIT_TYPE_NOT_SET:
146
0
    PANIC("not set");
147
1
  }
148
1
}
149
150
absl::optional<uint64_t> FaultRateLimitConfig::HeaderRateLimitProvider::rateKbps(
151
0
    const Http::RequestHeaderMap* request_headers) const {
152
0
  const auto header = request_headers->get(HeaderNames::get().ThroughputResponse);
153
0
  if (header.empty()) {
154
0
    return absl::nullopt;
155
0
  }
156
157
0
  uint64_t value;
158
  // This is an implicitly untrusted header, so per the API documentation only the first
159
  // value is used.
160
0
  if (!absl::SimpleAtoi(header[0]->value().getStringView(), &value)) {
161
0
    return absl::nullopt;
162
0
  }
163
164
0
  if (value == 0) {
165
0
    return absl::nullopt;
166
0
  }
167
168
0
  return value;
169
0
}
170
171
} // namespace Fault
172
} // namespace Common
173
} // namespace Filters
174
} // namespace Extensions
175
} // namespace Envoy