Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to access filter state from with Golang filter #34183

Open
asialea opened this issue May 16, 2024 · 4 comments
Open

Unable to access filter state from with Golang filter #34183

asialea opened this issue May 16, 2024 · 4 comments
Labels
area/golang question Questions that are neither investigations, bugs, nor enhancements

Comments

@asialea
Copy link

asialea commented May 16, 2024

Title: Unable to access filter state from with Golang filter

Description:
Hi team, facing a strange issue attempting to access filter state from within the golang http filter. We have a listener filter which sets keys in both both dynamic metadata and filter state which is successfully accessed by other c++ filters in the chain. When attempting to access these same keys from within the http golang filter, dynamic metadata is empty and the keys do not exist in the filter state.

Any pointers would be appreciated.

[optional Relevant Links:]

func (f *filterState) GetString(key string) string {

@asialea asialea added the triage Issue requires triage label May 16, 2024
@doujiang24
Copy link
Member

Hello @asialea

which is successfully accessed by other c++ filters in the chain

could you please show some related key C++ code? i.e. how they get the values.

And could you please try the Lua http filter to get the dynamicmetadata?

I think there might be some difference to get values which is setted by a listener filter

@asialea
Copy link
Author

asialea commented May 16, 2024

Sure so here is a code snippet on how these values are set inside our custom listener filter

Network::FilterStatus Filter::onAccept(Network::ListenerFilterCallbacks& cb) {
  StreamInfo::FilterState& filter_state = cb.filterState();
  FilterStateUtils::setFilterState(filter_state, key, value, StateType::ReadOnly, LifeSpan::Connection);
  cb.setDynamicMetadata(filter_name, metadata);
}

Here is the setFilterState method used above

static void setFilterState(StreamInfo::FilterState& filter_state, std::string key, std::string value, StateType state_type, LifeSpan life_span) {
            if (state_type == StateType::Mutable || !filter_state.hasDataWithName(key)) {
                filter_state.setData(key,
                                    std::make_shared<Router::StringAccessorImpl>(value),
                                    state_type,
                                    life_span);
            } else {
                ENVOY_LOG(warn, "FilterStateUtils: Not allowed to call setData() twice on same data name '{}' with ReadOnly state", key);
            }
        }

Here is the code on how the state is retrieved in a custom http filter later on in the chain. These same values from filter state is also able to be accessed by the access logger using FormatStrings

Http::FilterHeadersStatus CustomFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) {
  const StreamInfo::FilterStateSharedPtr& filter_state = decoder_callbacks_->streamInfo().filterState();
  auto id= FilterStateUtils::getFilterStateStringData(filter_state, key);
}

Here is the getFilterStateStringData method used above


        static std::string getFilterStateStringData(const StreamInfo::FilterState& filter_state, absl::string_view key) {
            auto filter_state_object = filter_state.getDataReadOnly<Router::StringAccessor>(key);
            if (filter_state_object == nullptr) {
                return EMPTY_STRING;
            }

            return std::string(filter_state_object->asString());
        }

@ravenblackx ravenblackx added question Questions that are neither investigations, bugs, nor enhancements area/golang and removed triage Issue requires triage labels May 16, 2024
@doujiang24
Copy link
Member

https://github.com/envoyproxy/envoy/blob/main/contrib%2Fgolang%2Ffilters%2Fhttp%2Fsource%2Fgolang_filter.cc#L1242-L1244
this is how golang plugin get the filter state, I'll take a deeper look tomorrow.

@doujiang24
Copy link
Member

okay, I see. we should use Router::StringAccessorImpl & Router::StringAccessor instead of GoStringFilterState, it could be better compatibility.
@StarryVae Are you interested to improve it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/golang question Questions that are neither investigations, bugs, nor enhancements
Projects
None yet
Development

No branches or pull requests

3 participants