-
Notifications
You must be signed in to change notification settings - Fork 5.2k
http-tap: gracefully handle request termination #40907
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
Conversation
Signed-off-by: Vadym Sukolen <[email protected]>
|
Hi @sukolenvo, welcome and thank you for your contribution. We will try to review your Pull Request as quickly as possible. In the meantime, please take a look at the contribution guidelines if you have not done so already. |
|
/assign-from @envoyproxy/envoy-maintainers |
|
@envoyproxy/envoy-maintainers assignee is @ravenblackx |
| EXPECT_TRUE(tapper_->onDestroyLog()); | ||
| } | ||
|
|
||
| TEST_F(HttpPerRequestTapperImplTest, StreamedMatchShortCircuit) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you name this something that explains what it's verifying, and/or add some comments along the way explaining what the test is doing?
Specifically worth calling out that onResponseHeaders before request_headers have been recorded is the point of the test. It took me a while of digging to figure that out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added comments and explicitly stated scenario that test covers. Sorry my PR description wasn't clear enough and caused digging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, comment is really great, everything super clear now. :)
Signed-off-by: Vadym S <[email protected]>
Commit Message: http-tap: gracefully handle request termination
Additional Description:
Steps to reproduce the issue and backstrace are awailable in the ticket.
Additionally I've recorded sequence of method calls in TapFilter with
short header and large header for comparison. Issue is caused because
request headers were accessed without
`HttpPerRequestTapperImpl::onRequestHeaders` being called.
<details>
<summary>Short header (successfull) call sequence</summary>
```
#0 0x000055555c422214 in Envoy::Extensions::HttpFilters::TapFilter::TapFilterFactory::createFilterFactoryFromProtoTyped(envoy::extensions::filters::http::tap::v3::Tap const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::Server::Configuration::FactoryContext&)::$_0::operator()(Envoy::Http::FilterChainFactoryCallbacks&) const ()
#0 0x000055555c425174 in Envoy::Extensions::HttpFilters::TapFilter::Filter* std::__1::__construct_at[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::Filter, std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::FilterConfig> const&, Envoy::Extensions::HttpFilters::TapFilter::Filter*>(Envoy::Extensions::HttpFilters::TapFilter::Filter*, std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::FilterConfig> const&) ()
#0 0x000055555c4251a4 in Envoy::Extensions::HttpFilters::TapFilter::Filter* std::__1::construct_at[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::Filter, std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::FilterConfig> const&, Envoy::Extensions::HttpFilters::TapFilter::Filter*>(Envoy::Extensions::HttpFilters::TapFilter::Filter*, std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::FilterConfig> const&) ()
#0 0x000055555c425224 in Envoy::Extensions::HttpFilters::TapFilter::Filter::Filter(std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::FilterConfig>) ()
#0 0x000055555c42ee44 in Envoy::Extensions::HttpFilters::TapFilter::Filter::setDecoderFilterCallbacks(Envoy::Http::StreamDecoderFilterCallbacks&) ()
#0 0x000055555c42e4c4 in Envoy::Extensions::HttpFilters::TapFilter::FilterConfigImpl::currentConfig() ()
#0 0x000055555c42f184 in Envoy::Extensions::HttpFilters::TapFilter::FilterConfigImpl::getTapConfig() const ()
#0 0x000055555c426134 in Envoy::Extensions::HttpFilters::TapFilter::HttpTapConfigImpl::createPerRequestTapper(envoy::extensions::filters::http::tap::v3::Tap const&, unsigned long, Envoy::OptRef<Envoy::Network::Connection const>) ()
#0 0x000055555c42d7a4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::HttpPerRequestTapperImpl(std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::HttpTapConfig>, envoy::extensions::filters::http::tap::v3::Tap const&, unsigned long, Envoy::OptRef<Envoy::Network::Connection const>) ()
#0 0x000055555c42da44 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapper::HttpPerRequestTapper() ()
#0 0x000055555c42dbe4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl*& std::__1::__compressed_pair<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl*, std::__1::default_delete<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl> >::__compressed_pair[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl*&, std::__1::__value_init_tag>(std::__1::__value_init_tag&&)
()
#0 0x000055555c42ddc4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl*&& std::__1::__compressed_pair<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapper*, std::__1::default_delete<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapper> >::__compressed_pair[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl*, std::__1::default_delete<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl> >(std::__1::default_delete<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl>&&) ()
#0 0x000055555c42efd4 in Envoy::Extensions::HttpFilters::TapFilter::Filter::setEncoderFilterCallbacks(Envoy::Http::StreamEncoderFilterCallbacks&) ()
#0 0x000055555c42e724 in Envoy::Extensions::HttpFilters::TapFilter::Filter::decodeHeaders(Envoy::Http::RequestHeaderMap&, bool) ()
#0 0x000055555c4263e4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::onRequestHeaders(Envoy::Http::RequestHeaderMap const&) ()
#0 0x000055555c426234 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::streamRequestHeaders() ()
#0 0x000055555c42a334 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::makeTraceSegment() ()
#0 0x000055555c4263a4 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*) ()
#0 0x000055555c428db4 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0&& std::__1::__function::__value_func<Envoy::Http::HeaderMap::Iterate (Envoy::Http::HeaderEntry const&)>::__value_func[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0, std::__1::allocator<Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0> >(std::__1::allocator<Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0> const&) ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c42e914 in Envoy::Extensions::HttpFilters::TapFilter::Filter::encodeHeaders(Envoy::Http::ResponseHeaderMap&, bool) ()
#0 0x000055555c427c74 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::onResponseHeaders(Envoy::Http::ResponseHeaderMap const&) ()
#0 0x000055555c427b04 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::streamResponseHeaders() ()
#0 0x000055555c42a334 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::makeTraceSegment() ()
#0 0x000055555c4263a4 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*) ()
#0 0x000055555c428db4 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0&& std::__1::__function::__value_func<Envoy::Http::HeaderMap::Iterate (Envoy::Http::HeaderEntry const&)>::__value_func[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0, std::__1::allocator<Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0> >(std::__1::allocator<Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0> const&) ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c429e24 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0::operator()(Envoy::Http::HeaderEntry const&) const ()
#0 0x000055555c42e9b4 in Envoy::Extensions::HttpFilters::TapFilter::Filter::encodeData(Envoy::Buffer::Instance&, bool) ()
#0 0x000055555c427df4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::onResponseBody(Envoy::Buffer::Instance const&) ()
#0 0x000055555c4269b4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::onBody(Envoy::Buffer::Instance const&, std::__1::unique_ptr<envoy::data::tap::v3::TraceWrapper, std::__1::default_delete<envoy::data::tap::v3::TraceWrapper> >&, unsigned int, envoy::data::tap::v3::Body* (envoy::data::tap::v3::HttpStreamedTraceSegment::*)(), envoy::data::tap::v3::HttpBufferedTrace_Message* (envoy::data::tap::v3::HttpBufferedTrace::*)(), bool) ()
#0 0x000055555c42a334 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::makeTraceSegment() ()
#0 0x000055555c42e9b4 in Envoy::Extensions::HttpFilters::TapFilter::Filter::encodeData(Envoy::Buffer::Instance&, bool) ()
#0 0x000055555c427df4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::onResponseBody(Envoy::Buffer::Instance const&) ()
#0 0x000055555c4269b4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::onBody(Envoy::Buffer::Instance const&, std::__1::unique_ptr<envoy::data::tap::v3::TraceWrapper, std::__1::default_delete<envoy::data::tap::v3::TraceWrapper> >&, unsigned int, envoy::data::tap::v3::Body* (envoy::data::tap::v3::HttpStreamedTraceSegment::*)(), envoy::data::tap::v3::HttpBufferedTrace_Message* (envoy::data::tap::v3::HttpBufferedTrace::*)(), bool) ()
#0 0x000055555c42a334 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::makeTraceSegment() ()
#0 0x000055555c42e9b4 in Envoy::Extensions::HttpFilters::TapFilter::Filter::encodeData(Envoy::Buffer::Instance&, bool) ()
#0 0x000055555c42eb04 in Envoy::Extensions::HttpFilters::TapFilter::Filter::log(Envoy::Formatter::HttpFormatterContext const&, Envoy::StreamInfo::StreamInfo const&) ()
#0 0x000055555c428114 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::onDestroyLog() ()
#0 0x000055555c42f1a4 in Envoy::Extensions::HttpFilters::TapFilter::FilterConfigImpl::stats() ()
[New Thread 0x7fffe8ad16c0 (LWP 336946)]
[2025-08-31T11:23:18.073Z] "GET / HTTP/1.1" 200 - 0 15986 427 243 "-" "curl/8.5.0" "266b6d40-7784-4a7c-919d-d8ae6401442a" "www.envoyproxy.io" "54.253.94.210:443"
#0 0x000055555c42ee34 in Envoy::Extensions::HttpFilters::TapFilter::Filter::onDestroy() ()
#0 0x000055555c42eda4 in Envoy::Extensions::HttpFilters::TapFilter::Filter::~Filter() ()
#0 0x000055555c42f274 in Envoy::Extensions::HttpFilters::TapFilter::Filter::~Filter() ()
#0 0x000055555c42aca4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::~HttpPerRequestTapperImpl() ()
#0 0x000055555c42ac14 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::~HttpPerRequestTapperImpl() ()
#0 0x000055555c42db14 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapper::~HttpPerRequestTapper() ()
```
</details>
<details>
<summary>Large header (segfault) call sequence</summary>
```
#0 0x000055555c422214 in Envoy::Extensions::HttpFilters::TapFilter::TapFilterFactory::createFilterFactoryFromProtoTyped(envoy::extensions::filters::http::tap::v3::Tap const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::Server::Configuration::FactoryContext&)::$_0::operator()(Envoy::Http::FilterChainFactoryCallbacks&) const ()
#0 0x000055555c425174 in Envoy::Extensions::HttpFilters::TapFilter::Filter* std::__1::__construct_at[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::Filter, std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::FilterConfig> const&, Envoy::Extensions::HttpFilters::TapFilter::Filter*>(Envoy::Extensions::HttpFilters::TapFilter::Filter*, std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::FilterConfig> const&) ()
#0 0x000055555c4251a4 in Envoy::Extensions::HttpFilters::TapFilter::Filter* std::__1::construct_at[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::Filter, std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::FilterConfig> const&, Envoy::Extensions::HttpFilters::TapFilter::Filter*>(Envoy::Extensions::HttpFilters::TapFilter::Filter*, std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::FilterConfig> const&) ()
#0 0x000055555c425224 in Envoy::Extensions::HttpFilters::TapFilter::Filter::Filter(std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::FilterConfig>) ()
#0 0x000055555c42ee44 in Envoy::Extensions::HttpFilters::TapFilter::Filter::setDecoderFilterCallbacks(Envoy::Http::StreamDecoderFilterCallbacks&) ()
#0 0x000055555c42e4c4 in Envoy::Extensions::HttpFilters::TapFilter::FilterConfigImpl::currentConfig() ()
#0 0x000055555c42f184 in Envoy::Extensions::HttpFilters::TapFilter::FilterConfigImpl::getTapConfig() const ()
#0 0x000055555c426134 in Envoy::Extensions::HttpFilters::TapFilter::HttpTapConfigImpl::createPerRequestTapper(envoy::extensions::filters::http::tap::v3::Tap const&, unsigned long, Envoy::OptRef<Envoy::Network::Connection const>) ()
#0 0x000055555c42d7a4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::HttpPerRequestTapperImpl(std::__1::shared_ptr<Envoy::Extensions::HttpFilters::TapFilter::HttpTapConfig>, envoy::extensions::filters::http::tap::v3::Tap const&, unsigned long, Envoy::OptRef<Envoy::Network::Connection const>) ()
#0 0x000055555c42da44 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapper::HttpPerRequestTapper() ()
#0 0x000055555c42dbe4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl*& std::__1::__compressed_pair<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl*, std::__1::default_delete<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl> >::__compressed_pair[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl*&, std::__1::__value_init_tag>(std::__1::__value_init_tag&&)
()
#0 0x000055555c42ddc4 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl*&& std::__1::__compressed_pair<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapper*, std::__1::default_delete<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapper> >::__compressed_pair[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl*, std::__1::default_delete<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl> >(std::__1::default_delete<Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl>&&) ()
#0 0x000055555c42efd4 in Envoy::Extensions::HttpFilters::TapFilter::Filter::setEncoderFilterCallbacks(Envoy::Http::StreamEncoderFilterCallbacks&) ()
#0 0x000055555c42e914 in Envoy::Extensions::HttpFilters::TapFilter::Filter::encodeHeaders(Envoy::Http::ResponseHeaderMap&, bool) ()
#0 0x000055555c427c74 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::onResponseHeaders(Envoy::Http::ResponseHeaderMap const&) ()
#0 0x000055555c426234 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::streamRequestHeaders() ()
#0 0x000055555c42a334 in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::makeTraceSegment() ()
#0 0x000055555c4263a4 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*) ()
#0 0x000055555c428db4 in Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0&& std::__1::__function::__value_func<Envoy::Http::HeaderMap::Iterate (Envoy::Http::HeaderEntry const&)>::__value_func[abi:ne180100]<Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0, std::__1::allocator<Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0> >(std::__1::allocator<Envoy::Extensions::HttpFilters::TapFilter::(anonymous namespace)::fillHeaderList(google::protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>*)::$_0> const&) ()
Thread 16 "wrk:worker_4" received signal SIGSEGV, Segmentation fault.
0x000055555c4262cd in Envoy::Extensions::HttpFilters::TapFilter::HttpPerRequestTapperImpl::streamRequestHeaders() ()
```
</details>
Risk Level: Low
Testing: Unit test added. Also I manually tested locally - after fix
Response code 431 returned for large header instead of segmentation
fault.
Docs Changes: N/A
Release Notes: N/A
Platform Specific Features: N/A
Fixes envoyproxy#39063
---------
Signed-off-by: Vadym Sukolen <[email protected]>
Signed-off-by: Vadym S <[email protected]>
Signed-off-by: Misha Badov <[email protected]>
Commit Message: http-tap: gracefully handle request termination
Additional Description:
Steps to reproduce the issue and backstrace are awailable in the ticket. Additionally I've recorded sequence of method calls in TapFilter with short header and large header for comparison. Issue is caused because request headers were accessed without
HttpPerRequestTapperImpl::onRequestHeadersbeing called.Short header (successfull) call sequence
Large header (segfault) call sequence
Risk Level: Low
Testing: Unit test added. Also I manually tested locally - after fix Response code 431 returned for large header instead of segmentation fault.
Docs Changes: N/A
Release Notes: N/A
Platform Specific Features: N/A
Fixes #39063