diff --git a/envoy b/envoy index 519774f742..71248e5125 160000 --- a/envoy +++ b/envoy @@ -1 +1 @@ -Subproject commit 519774f742bb2500cf5f6a00933c9662337acbb2 +Subproject commit 71248e51257e7f9f6fbe9cfb2ead834cd8dff550 diff --git a/library/common/extensions/filters/http/platform_bridge/filter.cc b/library/common/extensions/filters/http/platform_bridge/filter.cc index cae954db13..b243b79285 100644 --- a/library/common/extensions/filters/http/platform_bridge/filter.cc +++ b/library/common/extensions/filters/http/platform_bridge/filter.cc @@ -150,8 +150,18 @@ void PlatformBridgeFilter::onDestroy() { ENVOY_LOG(trace, "PlatformBridgeFilter({})::onDestroy", filter_name_); alive_ = false; - // If the filter chain is destroyed before a response is received, treat as cancellation. - if (!response_filter_base_->state_.stream_complete_ && platform_filter_.on_cancel) { + auto& info = decoder_callbacks_->streamInfo(); + if (response_filter_base_->state_.stream_complete_ && platform_filter_.on_error && + StreamInfo::isStreamIdleTimeout(info)) { + // If the stream info has a response code details with a stream idle timeout, treat as error. + ENVOY_LOG(trace, "PlatformBridgeFilter({})->on_error", filter_name_); + envoy_data error_message = Data::Utility::copyToBridgeData("Stream idle timeout"); + auto& info = decoder_callbacks_->streamInfo(); + int32_t attempts = static_cast(info.attemptCount().value_or(0)); + platform_filter_.on_error({ENVOY_REQUEST_TIMEOUT, error_message, attempts}, streamIntel(), + finalStreamIntel(), platform_filter_.instance_context); + } else if (!response_filter_base_->state_.stream_complete_ && platform_filter_.on_cancel) { + // If the filter chain is destroyed before a response is received, treat as cancellation. ENVOY_LOG(trace, "PlatformBridgeFilter({})->on_cancel", filter_name_); platform_filter_.on_cancel(streamIntel(), finalStreamIntel(), platform_filter_.instance_context); diff --git a/library/common/http/client.cc b/library/common/http/client.cc index d18262cf82..4f631c09a3 100644 --- a/library/common/http/client.cc +++ b/library/common/http/client.cc @@ -320,6 +320,8 @@ envoy_error Client::DirectStreamCallbacks::streamError() { if (info.responseCode().has_value()) { error.error_code = Bridge::Utility::errorCodeFromLocalStatus( static_cast(info.responseCode().value())); + } else if (StreamInfo::isStreamIdleTimeout(info)) { + error.error_code = ENVOY_REQUEST_TIMEOUT; } else { error.error_code = ENVOY_STREAM_RESET; } diff --git a/library/common/stream_info/extra_stream_info.cc b/library/common/stream_info/extra_stream_info.cc index a1373d12c4..0fe7f0a7f3 100644 --- a/library/common/stream_info/extra_stream_info.cc +++ b/library/common/stream_info/extra_stream_info.cc @@ -57,5 +57,10 @@ void setFinalStreamIntel(StreamInfo& stream_info, envoy_final_stream_intel& fina final_intel.response_flags = stream_info.responseFlags(); } +bool isStreamIdleTimeout(const StreamInfo& stream_info) { + return stream_info.responseCodeDetails().has_value() && + stream_info.responseCodeDetails().value() == ResponseCodeDetails::get().StreamIdleTimeout; +} + } // namespace StreamInfo } // namespace Envoy diff --git a/library/common/stream_info/extra_stream_info.h b/library/common/stream_info/extra_stream_info.h index 5cb0ecbc8b..d88c7b0088 100644 --- a/library/common/stream_info/extra_stream_info.h +++ b/library/common/stream_info/extra_stream_info.h @@ -18,6 +18,10 @@ struct ExtraStreamInfo : public FilterState::Object { // Set fields in final_intel based on stream_info. void setFinalStreamIntel(StreamInfo& stream_info, envoy_final_stream_intel& final_intel); +// Returns true if the response code details indicate that this stream info +// has a stream idle timeout error. +bool isStreamIdleTimeout(const StreamInfo& stream_info); + using ExtraStreamInfoPtr = std::unique_ptr; } // namespace StreamInfo