From 4c61d7a0c0edfe5cc2038806519c4283114fe8fd Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 20 Apr 2020 15:45:45 -0700 Subject: [PATCH] cherry-pick of https://github.com/envoyproxy/envoy-wasm/pull/486 Signed-off-by: Kuat Yessenov --- source/extensions/common/wasm/context.cc | 20 +++++++++++++------- source/extensions/common/wasm/context.h | 12 ++++++++---- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/source/extensions/common/wasm/context.cc b/source/extensions/common/wasm/context.cc index 463d30e8a25c..a79cbfad64f0 100644 --- a/source/extensions/common/wasm/context.cc +++ b/source/extensions/common/wasm/context.cc @@ -397,7 +397,7 @@ static absl::flat_hash_map property_tokens = {PROPER #undef _PARI absl::optional -Context::FindValue(absl::string_view name, Protobuf::Arena* arena) const { +Context::findValue(absl::string_view name, Protobuf::Arena* arena, bool last) const { using google::api::expr::runtime::CelValue; const StreamInfo::StreamInfo* info = getConstRequestStreamInfo(); @@ -411,11 +411,15 @@ Context::FindValue(absl::string_view name, Protobuf::Arena* arena) const { const WasmState* state; if (info->filterState().hasData(key)) { state = &info->filterState().getDataReadOnly(key); - } else if (info->upstreamFilterState()->hasData(key)) { + } else if (info->upstreamFilterState() && + info->upstreamFilterState()->hasData(key)) { state = &info->upstreamFilterState()->getDataReadOnly(key); } else { return {}; } + if (last) { + return CelValue::CreateBytes(&state->value()); + } return state->exprValue(arena); } return {}; @@ -542,7 +546,7 @@ WasmResult Context::getProperty(absl::string_view path, std::string* result) { if (first) { // top-level ident first = false; - auto top_value = FindValue(part, &arena); + auto top_value = findValue(part, &arena, start >= path.size()); if (!top_value.has_value()) { return WasmResult::NotFound; } @@ -1066,12 +1070,14 @@ WasmResult Context::setProperty(absl::string_view path, absl::string_view value) state = &stream_info->filterState()->getDataMutable(key); } else { const auto& it = rootContext()->state_prototypes_.find(path); - auto state_ptr = std::make_unique(it == rootContext()->state_prototypes_.end() - ? DefaultWasmStatePrototype::get() - : *it->second.get()); + const WasmStatePrototype& prototype = it == rootContext()->state_prototypes_.end() + ? DefaultWasmStatePrototype::get() + : *it->second.get(); + auto state_ptr = std::make_unique(prototype); state = state_ptr.get(); stream_info->filterState()->setData(key, std::move(state_ptr), - StreamInfo::FilterState::StateType::ReadOnly); + StreamInfo::FilterState::StateType::Mutable, + prototype.life_span_); } if (!state->setValue(value)) { return WasmResult::BadArgument; diff --git a/source/extensions/common/wasm/context.h b/source/extensions/common/wasm/context.h index dd7fc0351b51..6c30dc1ebbbc 100644 --- a/source/extensions/common/wasm/context.h +++ b/source/extensions/common/wasm/context.h @@ -306,13 +306,17 @@ class Context : public Logger::Loggable, bool end_stream); // stream only // CEL evaluation - virtual std::vector + std::vector FindFunctionOverloads(absl::string_view) const override { return {}; } - virtual absl::optional - FindValue(absl::string_view name, Protobuf::Arena* arena) const override; - virtual bool IsPathUnknown(absl::string_view) const override { return false; } + absl::optional + findValue(absl::string_view name, Protobuf::Arena* arena, bool last) const; + absl::optional + FindValue(absl::string_view name, Protobuf::Arena* arena) const override { + return findValue(name, arena, false); + } + bool IsPathUnknown(absl::string_view) const override { return false; } const std::vector& unknown_attribute_patterns() const override { static const std::vector empty;