3
3
#include < iterator>
4
4
5
5
#include " absl/strings/str_replace.h"
6
+ #include " absl/strings/ascii.h"
6
7
7
8
#include " source/common/buffer/buffer_impl.h"
8
9
#include " source/common/common/macros.h"
@@ -230,6 +231,12 @@ TransformerInstance::TransformerInstance(ThreadLocal::Slot &tls, Envoy::Random::
230
231
env_.add_callback (" extraction" , 1 , [this ](Arguments &args) {
231
232
return extracted_callback (args);
232
233
});
234
+ env_.add_callback (" data_source" , 1 , [this ](Arguments &args) {
235
+ return data_source_callback (args);
236
+ });
237
+ env_.add_callback (" trim" , 1 , [this ](Arguments &args) {
238
+ return trim_callback (args);
239
+ });
233
240
env_.add_callback (" context" , 0 , [this ](Arguments &) { return *tls_.getTyped <ThreadLocalTransformerContext>().context_ ; });
234
241
env_.add_callback (" body" , 0 , [this ](Arguments &) { return (*tls_.getTyped <ThreadLocalTransformerContext>().body_ )(); });
235
242
env_.add_callback (" env" , 1 , [this ](Arguments &args) { return env (args); });
@@ -394,6 +401,21 @@ json TransformerInstance::extracted_callback(const inja::Arguments &args) const
394
401
return " " ;
395
402
}
396
403
404
+ json TransformerInstance::data_source_callback (const inja::Arguments &args) const {
405
+ const auto & ctx = tls_.getTyped <ThreadLocalTransformerContext>();
406
+ const std::string &name = args.at (0 )->get_ref <const std::string &>();
407
+ const auto value_it = ctx.data_sources_ ->find (name);
408
+ if (value_it != ctx.data_sources_ ->end ()) {
409
+ return value_it->second ->data ();
410
+ }
411
+ return " " ;
412
+ }
413
+
414
+ json TransformerInstance::trim_callback (const inja::Arguments &args) const {
415
+ const std::string& s = args.at (0 )->get_ref <const std::string &>();
416
+ return absl::StripAsciiWhitespace (s);
417
+ }
418
+
397
419
json TransformerInstance::env (const inja::Arguments &args) const {
398
420
const auto & ctx = tls_.getTyped <ThreadLocalTransformerContext>();
399
421
const std::string &key = args.at (0 )->get_ref <const std::string &>();
@@ -690,8 +712,9 @@ std::string TransformerInstance::render(const inja::Template &input) {
690
712
691
713
// An InjaTransformer is constructed on initialization on the main thread
692
714
InjaTransformer::InjaTransformer (const TransformationTemplate &transformation,
693
- Envoy::Random::RandomGenerator &rng,
694
715
google::protobuf::BoolValue log_request_response_info,
716
+ Event::Dispatcher& main_thread_dispatcher,
717
+ Envoy::Api::Api& api,
695
718
ThreadLocal::SlotAllocator &tls)
696
719
: Transformer(log_request_response_info),
697
720
advanced_templates_(transformation.advanced_templates()),
@@ -700,7 +723,7 @@ InjaTransformer::InjaTransformer(const TransformationTemplate &transformation,
700
723
ignore_error_on_parse_(transformation.ignore_error_on_parse()),
701
724
escape_characters_(transformation.escape_characters()),
702
725
tls_(tls.allocateSlot()),
703
- instance_(std::make_unique<TransformerInstance>(*tls_, rng )) {
726
+ instance_(std::make_unique<TransformerInstance>(*tls_, api.randomGenerator() )) {
704
727
if (advanced_templates_) {
705
728
instance_->set_element_notation (inja::ElementNotation::Pointer);
706
729
}
@@ -715,6 +738,23 @@ InjaTransformer::InjaTransformer(const TransformationTemplate &transformation,
715
738
for (auto it = extractors.begin (); it != extractors.end (); it++) {
716
739
extractors_.emplace_back (std::make_pair (it->first , it->second ));
717
740
}
741
+ uint32_t max_size = 4096 ;
742
+ if (transformation.data_source_max_size () > 0 ) {
743
+ max_size = transformation.data_source_max_size ();
744
+ }
745
+
746
+ const auto &data_sources = transformation.data_sources ();
747
+ for (auto it = data_sources.begin (); it != data_sources.end (); it++) {
748
+ auto provider_or_error = Envoy::Config::DataSource::DataSourceProvider::create (
749
+ it->second , main_thread_dispatcher, tls, api, true , max_size);
750
+ if (provider_or_error.ok ()) {
751
+ data_sources_.emplace (std::make_pair (it->first , std::move (provider_or_error.value ())));
752
+ } else {
753
+ throw EnvoyException (fmt::format (
754
+ " Failed to create data source provider '{}': {}" , it->first , provider_or_error.status ().message ()));
755
+ }
756
+ }
757
+
718
758
const auto &headers = transformation.headers ();
719
759
for (auto it = headers.begin (); it != headers.end (); it++) {
720
760
Http::LowerCaseString header_name (it->first );
@@ -980,6 +1020,7 @@ void InjaTransformer::transform(Http::RequestOrResponseHeaderMap &header_map,
980
1020
typed_tls_data.request_headers_ = request_headers;
981
1021
typed_tls_data.body_ = &get_body;
982
1022
typed_tls_data.extractions_ = &extractions;
1023
+ typed_tls_data.data_sources_ = &data_sources_;
983
1024
typed_tls_data.destructive_extractions_ = &destructive_extractions;
984
1025
typed_tls_data.context_ = &json_body;
985
1026
typed_tls_data.environ_ = &environ_;
0 commit comments