/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 |