Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/common/formatter/stream_info_formatter.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <bitset>
4
#include <functional>
5
#include <list>
6
#include <regex>
7
#include <string>
8
#include <vector>
9
10
#include "envoy/formatter/substitution_formatter.h"
11
#include "envoy/stream_info/stream_info.h"
12
13
#include "source/common/common/utility.h"
14
#include "source/common/formatter/substitution_format_utility.h"
15
16
#include "absl/container/flat_hash_map.h"
17
#include "absl/types/optional.h"
18
19
namespace Envoy {
20
namespace Formatter {
21
22
class StreamInfoFormatterProvider {
23
public:
24
274k
  virtual ~StreamInfoFormatterProvider() = default;
25
26
  virtual absl::optional<std::string> format(const StreamInfo::StreamInfo&) const PURE;
27
  virtual ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo&) const PURE;
28
};
29
30
using StreamInfoFormatterProviderPtr = std::unique_ptr<StreamInfoFormatterProvider>;
31
using StreamInfoFormatterProviderCreateFunc =
32
    std::function<StreamInfoFormatterProviderPtr(const std::string&, absl::optional<size_t>)>;
33
34
enum class StreamInfoAddressFieldExtractionType { WithPort, WithoutPort, JustPort };
35
36
/**
37
 * Base formatter for formatting Metadata objects
38
 */
39
class MetadataFormatter : public StreamInfoFormatterProvider {
40
public:
41
  using GetMetadataFunction =
42
      std::function<const envoy::config::core::v3::Metadata*(const StreamInfo::StreamInfo&)>;
43
  MetadataFormatter(const std::string& filter_namespace, const std::vector<std::string>& path,
44
                    absl::optional<size_t> max_length, GetMetadataFunction get);
45
46
  // StreamInfoFormatterProvider
47
  absl::optional<std::string> format(const StreamInfo::StreamInfo& stream_info) const override;
48
  ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo& stream_info) const override;
49
50
protected:
51
  absl::optional<std::string>
52
  formatMetadata(const envoy::config::core::v3::Metadata& metadata) const;
53
  ProtobufWkt::Value formatMetadataValue(const envoy::config::core::v3::Metadata& metadata) const;
54
55
private:
56
  std::string filter_namespace_;
57
  std::vector<std::string> path_;
58
  absl::optional<size_t> max_length_;
59
  GetMetadataFunction get_func_;
60
};
61
62
/**
63
 * FormatterProvider for DynamicMetadata from StreamInfo.
64
 */
65
class DynamicMetadataFormatter : public MetadataFormatter {
66
public:
67
  DynamicMetadataFormatter(const std::string& filter_namespace,
68
                           const std::vector<std::string>& path, absl::optional<size_t> max_length);
69
};
70
71
/**
72
 * FormatterProvider for ClusterMetadata from StreamInfo.
73
 */
74
class ClusterMetadataFormatter : public MetadataFormatter {
75
public:
76
  ClusterMetadataFormatter(const std::string& filter_namespace,
77
                           const std::vector<std::string>& path, absl::optional<size_t> max_length);
78
};
79
80
/**
81
 * FormatterProvider for UpstreamHostMetadata from StreamInfo.
82
 */
83
class UpstreamHostMetadataFormatter : public MetadataFormatter {
84
public:
85
  UpstreamHostMetadataFormatter(const std::string& filter_namespace,
86
                                const std::vector<std::string>& path,
87
                                absl::optional<size_t> max_length);
88
};
89
90
enum class FilterStateFormat { String, Proto, Field };
91
92
/**
93
 * StreamInfoFormatterProvider for FilterState from StreamInfo.
94
 */
95
class FilterStateFormatter : public StreamInfoFormatterProvider {
96
public:
97
  static std::unique_ptr<FilterStateFormatter>
98
  create(const std::string& format, const absl::optional<size_t>& max_length, bool is_upstream);
99
100
  FilterStateFormatter(const std::string& key, absl::optional<size_t> max_length,
101
                       bool serialize_as_string, bool is_upstream = false,
102
                       const std::string& field_name = "");
103
104
  // StreamInfoFormatterProvider
105
  absl::optional<std::string> format(const StreamInfo::StreamInfo&) const override;
106
  ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo&) const override;
107
108
private:
109
  const Envoy::StreamInfo::FilterState::Object*
110
  filterState(const StreamInfo::StreamInfo& stream_info) const;
111
112
  std::string key_;
113
  absl::optional<size_t> max_length_;
114
115
  const bool is_upstream_;
116
  FilterStateFormat format_;
117
  std::string field_name_;
118
  StreamInfo::FilterState::ObjectFactory* factory_;
119
};
120
121
/**
122
 * Base StreamInfoFormatterProvider for system times from StreamInfo.
123
 */
124
class SystemTimeFormatter : public StreamInfoFormatterProvider {
125
public:
126
  using TimeFieldExtractor =
127
      std::function<absl::optional<SystemTime>(const StreamInfo::StreamInfo& stream_info)>;
128
  using TimeFieldExtractorPtr = std::unique_ptr<TimeFieldExtractor>;
129
130
  SystemTimeFormatter(const std::string& format, TimeFieldExtractorPtr f);
131
132
  // StreamInfoFormatterProvider
133
  absl::optional<std::string> format(const StreamInfo::StreamInfo&) const override;
134
  ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo&) const override;
135
136
private:
137
  const Envoy::DateFormatter date_formatter_;
138
  const TimeFieldExtractorPtr time_field_extractor_;
139
};
140
141
/**
142
 * SystemTimeFormatter (FormatterProvider) for request start time from StreamInfo.
143
 */
144
class StartTimeFormatter : public SystemTimeFormatter {
145
public:
146
  StartTimeFormatter(const std::string& format);
147
};
148
149
/**
150
 * SystemTimeFormatter (FormatterProvider) for downstream cert start time from the StreamInfo's
151
 * ConnectionInfo.
152
 */
153
class DownstreamPeerCertVStartFormatter : public SystemTimeFormatter {
154
public:
155
  DownstreamPeerCertVStartFormatter(const std::string& format);
156
};
157
158
/**
159
 * SystemTimeFormatter (FormatterProvider) for downstream cert end time from the StreamInfo's
160
 * ConnectionInfo.
161
 */
162
class DownstreamPeerCertVEndFormatter : public SystemTimeFormatter {
163
public:
164
  DownstreamPeerCertVEndFormatter(const std::string& format);
165
};
166
167
/**
168
 * SystemTimeFormatter (FormatterProvider) for upstream cert start time from the StreamInfo's
169
 * upstreamInfo.
170
 */
171
class UpstreamPeerCertVStartFormatter : public SystemTimeFormatter {
172
public:
173
  UpstreamPeerCertVStartFormatter(const std::string& format);
174
};
175
176
/**
177
 * SystemTimeFormatter (FormatterProvider) for upstream cert end time from the StreamInfo's
178
 * upstreamInfo.
179
 */
180
class UpstreamPeerCertVEndFormatter : public SystemTimeFormatter {
181
public:
182
  UpstreamPeerCertVEndFormatter(const std::string& format);
183
};
184
185
/**
186
 * FormatterProvider for environment. If no valid environment value then
187
 */
188
class EnvironmentFormatter : public StreamInfoFormatterProvider {
189
public:
190
  EnvironmentFormatter(const std::string& key, absl::optional<size_t> max_length);
191
192
  // StreamInfoFormatterProvider
193
  absl::optional<std::string> format(const StreamInfo::StreamInfo&) const override;
194
  ProtobufWkt::Value formatValue(const StreamInfo::StreamInfo&) const override;
195
196
private:
197
  ProtobufWkt::Value str_;
198
};
199
200
using StreamInfoFormatterProviderLookupTable =
201
    absl::flat_hash_map<absl::string_view, std::pair<CommandSyntaxChecker::CommandSyntaxFlags,
202
                                                     StreamInfoFormatterProviderCreateFunc>>;
203
const StreamInfoFormatterProviderLookupTable& getKnownStreamInfoFormatterProviders();
204
205
/**
206
 * FormatterProvider for string literals. It ignores headers and stream info and returns string by
207
 * which it was initialized.
208
 */
209
template <class FormatterContext>
210
class CommonPlainStringFormatterBase : public FormatterProviderBase<FormatterContext> {
211
public:
212
559k
  CommonPlainStringFormatterBase(const std::string& str) { str_.set_string_value(str); }
213
214
  // FormatterProviderBase
215
  absl::optional<std::string> formatWithContext(const FormatterContext&,
216
490k
                                                const StreamInfo::StreamInfo&) const override {
217
490k
    return str_.string_value();
218
490k
  }
219
  ProtobufWkt::Value formatValueWithContext(const FormatterContext&,
220
7.77k
                                            const StreamInfo::StreamInfo&) const override {
221
7.77k
    return str_;
222
7.77k
  }
223
224
private:
225
  ProtobufWkt::Value str_;
226
};
227
228
template <class FormatterContext>
229
class PlainStringFormatterBase : public CommonPlainStringFormatterBase<FormatterContext> {
230
public:
231
  using CommonPlainStringFormatterBase<FormatterContext>::CommonPlainStringFormatterBase;
232
};
233
234
/**
235
 * FormatterProvider for numbers.
236
 */
237
template <class FormatterContext>
238
class CommonPlainNumberFormatterBase : public FormatterProviderBase<FormatterContext> {
239
public:
240
6.60k
  CommonPlainNumberFormatterBase(double num) { num_.set_number_value(num); }
241
242
  // FormatterProviderBase
243
  absl::optional<std::string> formatWithContext(const FormatterContext&,
244
0
                                                const StreamInfo::StreamInfo&) const override {
245
0
    std::string str = absl::StrFormat("%g", num_.number_value());
246
0
    return str;
247
0
  }
248
  ProtobufWkt::Value formatValueWithContext(const FormatterContext&,
249
5.89k
                                            const StreamInfo::StreamInfo&) const override {
250
5.89k
    return num_;
251
5.89k
  }
252
253
private:
254
  ProtobufWkt::Value num_;
255
};
256
257
template <class FormatterContext>
258
class PlainNumberFormatterBase : public CommonPlainNumberFormatterBase<FormatterContext> {
259
public:
260
  using CommonPlainNumberFormatterBase<FormatterContext>::CommonPlainNumberFormatterBase;
261
};
262
263
/**
264
 * FormatterProvider based on StreamInfo fields.
265
 */
266
template <class FormatterContext>
267
class CommonStreamInfoFormatterBase : public FormatterProviderBase<FormatterContext> {
268
public:
269
  CommonStreamInfoFormatterBase(const std::string& command, const std::string& sub_command = "",
270
275k
                                absl::optional<size_t> max_length = absl::nullopt) {
271
272
275k
    const auto& formatters = getKnownStreamInfoFormatterProviders();
273
274
275k
    auto it = formatters.find(command);
275
276
275k
    if (it == formatters.end()) {
277
415
      throwEnvoyExceptionOrPanic(fmt::format("Not supported field in StreamInfo: {}", command));
278
415
    }
279
280
    // Check flags for the command.
281
274k
    CommandSyntaxChecker::verifySyntax((*it).second.first, command, sub_command, max_length);
282
283
    // Create a pointer to the formatter by calling a function
284
    // associated with formatter's name.
285
274k
    formatter_ = (*it).second.second(sub_command, max_length);
286
274k
  }
287
288
  CommonStreamInfoFormatterBase(StreamInfoFormatterProviderPtr formatter)
289
0
      : formatter_(std::move(formatter)) {}
290
291
  // FormatterProvider
292
  absl::optional<std::string>
293
  formatWithContext(const FormatterContext&,
294
235k
                    const StreamInfo::StreamInfo& stream_info) const override {
295
235k
    return formatter_->format(stream_info);
296
235k
  }
297
  ProtobufWkt::Value
298
  formatValueWithContext(const FormatterContext&,
299
0
                         const StreamInfo::StreamInfo& stream_info) const override {
300
0
    return formatter_->formatValue(stream_info);
301
0
  }
302
303
private:
304
  StreamInfoFormatterProviderPtr formatter_;
305
};
306
307
template <class FormatterContext>
308
class StreamInfoFormatterBase : public CommonStreamInfoFormatterBase<FormatterContext> {
309
public:
310
  using CommonStreamInfoFormatterBase<FormatterContext>::CommonStreamInfoFormatterBase;
311
};
312
313
// Aliases for backward compatibility.
314
using PlainNumberFormatter = PlainNumberFormatterBase<HttpFormatterContext>;
315
using PlainStringFormatter = PlainStringFormatterBase<HttpFormatterContext>;
316
using StreamInfoFormatter = StreamInfoFormatterBase<HttpFormatterContext>;
317
318
} // namespace Formatter
319
} // namespace Envoy