Line data Source code
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 2039 : 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 3176 : CommonPlainStringFormatterBase(const std::string& str) { str_.set_string_value(str); } 213 : 214 : // FormatterProviderBase 215 : absl::optional<std::string> formatWithContext(const FormatterContext&, 216 10144 : const StreamInfo::StreamInfo&) const override { 217 10144 : return str_.string_value(); 218 10144 : } 219 : ProtobufWkt::Value formatValueWithContext(const FormatterContext&, 220 1 : const StreamInfo::StreamInfo&) const override { 221 1 : return str_; 222 1 : } 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 0 : 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 0 : const StreamInfo::StreamInfo&) const override { 250 0 : return num_; 251 0 : } 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 2050 : absl::optional<size_t> max_length = absl::nullopt) { 271 : 272 2050 : const auto& formatters = getKnownStreamInfoFormatterProviders(); 273 : 274 2050 : auto it = formatters.find(command); 275 : 276 2050 : if (it == formatters.end()) { 277 7 : throwEnvoyExceptionOrPanic(fmt::format("Not supported field in StreamInfo: {}", command)); 278 7 : } 279 : 280 : // Check flags for the command. 281 2043 : 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 2043 : formatter_ = (*it).second.second(sub_command, max_length); 286 2043 : } 287 : 288 : CommonStreamInfoFormatterBase(StreamInfoFormatterProviderPtr formatter) 289 0 : : formatter_(std::move(formatter)) {} 290 : 291 : // FormatterProvider 292 : absl::optional<std::string> 293 : formatWithContext(const FormatterContext&, 294 5524 : const StreamInfo::StreamInfo& stream_info) const override { 295 5524 : return formatter_->format(stream_info); 296 5524 : } 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