@@ -791,6 +791,191 @@ TEST_F(FilterManagerTest, IdleTimerResets) {
791791 filter_1->decoder_callbacks_ ->encodeTrailers (std::move (basic_resp_trailers));
792792 filter_manager_->destroyFilters ();
793793}
794+
795+ // Verify that decodeData is not called on filters after the stream has been reset.
796+ TEST_F (FilterManagerTest, DecodeDataNotCalledAfterDownstreamReset) {
797+ initialize ();
798+
799+ std::shared_ptr<MockStreamDecoderFilter> filter (new NiceMock<MockStreamDecoderFilter>());
800+
801+ EXPECT_CALL (filter_factory_, createFilterChain (_))
802+ .WillOnce (Invoke ([&](FilterChainFactoryCallbacks& callbacks) -> bool {
803+ auto factory = createDecoderFilterFactoryCb (filter);
804+ callbacks.setFilterConfigName (" test_filter" );
805+ factory (callbacks);
806+ return true ;
807+ }));
808+ filter_manager_->createDownstreamFilterChain ();
809+
810+ RequestHeaderMapPtr headers{
811+ new TestRequestHeaderMapImpl{{" :authority" , " host" }, {" :path" , " /" }, {" :method" , " POST" }}};
812+ ON_CALL (filter_manager_callbacks_, requestHeaders ()).WillByDefault (Return (makeOptRef (*headers)));
813+
814+ EXPECT_CALL (*filter, decodeHeaders (_, false )).WillOnce (Return (FilterHeadersStatus::Continue));
815+ filter_manager_->requestHeadersInitialized ();
816+ filter_manager_->decodeHeaders (*headers, false );
817+
818+ // Simulate a downstream reset.
819+ filter_manager_->onDownstreamReset ();
820+
821+ // After reset, decodeData should not be called on the filter.
822+ EXPECT_CALL (*filter, decodeData (_, _)).Times (0 );
823+
824+ Buffer::OwnedImpl data (" test_data" );
825+ filter_manager_->decodeData (data, false );
826+
827+ filter_manager_->destroyFilters ();
828+ }
829+
830+ // Verify that decodeHeaders is not called on filters after the stream has been reset.
831+ TEST_F (FilterManagerTest, DecodeHeadersNotCalledAfterDownstreamReset) {
832+ initialize ();
833+
834+ std::shared_ptr<MockStreamDecoderFilter> filter (new NiceMock<MockStreamDecoderFilter>());
835+
836+ EXPECT_CALL (filter_factory_, createFilterChain (_))
837+ .WillOnce (Invoke ([&](FilterChainFactoryCallbacks& callbacks) -> bool {
838+ auto factory = createDecoderFilterFactoryCb (filter);
839+ callbacks.setFilterConfigName (" test_filter" );
840+ factory (callbacks);
841+ return true ;
842+ }));
843+ filter_manager_->createDownstreamFilterChain ();
844+
845+ // Simulate a downstream reset before headers are processed.
846+ filter_manager_->onDownstreamReset ();
847+
848+ // After reset, decodeHeaders should not be called on the filter.
849+ EXPECT_CALL (*filter, decodeHeaders (_, _)).Times (0 );
850+
851+ RequestHeaderMapPtr headers{
852+ new TestRequestHeaderMapImpl{{" :authority" , " host" }, {" :path" , " /" }, {" :method" , " GET" }}};
853+ ON_CALL (filter_manager_callbacks_, requestHeaders ()).WillByDefault (Return (makeOptRef (*headers)));
854+
855+ filter_manager_->decodeHeaders (*headers, true );
856+
857+ filter_manager_->destroyFilters ();
858+ }
859+
860+ // Verify that decodeTrailers is not called on filters after the stream has been reset.
861+ TEST_F (FilterManagerTest, DecodeTrailersNotCalledAfterDownstreamReset) {
862+ initialize ();
863+
864+ std::shared_ptr<MockStreamDecoderFilter> filter (new NiceMock<MockStreamDecoderFilter>());
865+
866+ EXPECT_CALL (filter_factory_, createFilterChain (_))
867+ .WillOnce (Invoke ([&](FilterChainFactoryCallbacks& callbacks) -> bool {
868+ auto factory = createDecoderFilterFactoryCb (filter);
869+ callbacks.setFilterConfigName (" test_filter" );
870+ factory (callbacks);
871+ return true ;
872+ }));
873+ filter_manager_->createDownstreamFilterChain ();
874+
875+ RequestHeaderMapPtr headers{
876+ new TestRequestHeaderMapImpl{{" :authority" , " host" }, {" :path" , " /" }, {" :method" , " POST" }}};
877+ ON_CALL (filter_manager_callbacks_, requestHeaders ()).WillByDefault (Return (makeOptRef (*headers)));
878+
879+ EXPECT_CALL (*filter, decodeHeaders (_, false )).WillOnce (Return (FilterHeadersStatus::Continue));
880+ filter_manager_->requestHeadersInitialized ();
881+ filter_manager_->decodeHeaders (*headers, false );
882+
883+ // Simulate a downstream reset.
884+ filter_manager_->onDownstreamReset ();
885+
886+ // After reset, decodeTrailers should not be called on the filter.
887+ EXPECT_CALL (*filter, decodeTrailers (_)).Times (0 );
888+
889+ RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{" foo" , " bar" }}};
890+ ON_CALL (filter_manager_callbacks_, requestTrailers ())
891+ .WillByDefault (Return (makeOptRef (*trailers)));
892+
893+ filter_manager_->decodeTrailers (*trailers);
894+
895+ filter_manager_->destroyFilters ();
896+ }
897+
898+ // Verify that decodeMetadata is not called on filters after the stream has been reset.
899+ TEST_F (FilterManagerTest, DecodeMetadataNotCalledAfterDownstreamReset) {
900+ initialize ();
901+
902+ std::shared_ptr<MockStreamDecoderFilter> filter (new NiceMock<MockStreamDecoderFilter>());
903+
904+ EXPECT_CALL (filter_factory_, createFilterChain (_))
905+ .WillOnce (Invoke ([&](FilterChainFactoryCallbacks& callbacks) -> bool {
906+ auto factory = createDecoderFilterFactoryCb (filter);
907+ callbacks.setFilterConfigName (" test_filter" );
908+ factory (callbacks);
909+ return true ;
910+ }));
911+ filter_manager_->createDownstreamFilterChain ();
912+
913+ RequestHeaderMapPtr headers{
914+ new TestRequestHeaderMapImpl{{" :authority" , " host" }, {" :path" , " /" }, {" :method" , " POST" }}};
915+ ON_CALL (filter_manager_callbacks_, requestHeaders ()).WillByDefault (Return (makeOptRef (*headers)));
916+
917+ EXPECT_CALL (*filter, decodeHeaders (_, false )).WillOnce (Return (FilterHeadersStatus::Continue));
918+ filter_manager_->requestHeadersInitialized ();
919+ filter_manager_->decodeHeaders (*headers, false );
920+
921+ // Simulate a downstream reset.
922+ filter_manager_->onDownstreamReset ();
923+
924+ // After reset, decodeMetadata should not be called on the filter.
925+ EXPECT_CALL (*filter, decodeMetadata (_)).Times (0 );
926+
927+ MetadataMap metadata_map{{" key" , " value" }};
928+ filter_manager_->decodeMetadata (metadata_map);
929+
930+ filter_manager_->destroyFilters ();
931+ }
932+
933+ // Verify that multiple decode operations are all blocked after downstream reset.
934+ TEST_F (FilterManagerTest, AllDecodeOperationsBlockedAfterDownstreamReset) {
935+ initialize ();
936+
937+ std::shared_ptr<MockStreamDecoderFilter> filter (new NiceMock<MockStreamDecoderFilter>());
938+
939+ EXPECT_CALL (filter_factory_, createFilterChain (_))
940+ .WillOnce (Invoke ([&](FilterChainFactoryCallbacks& callbacks) -> bool {
941+ auto factory = createDecoderFilterFactoryCb (filter);
942+ callbacks.setFilterConfigName (" test_filter" );
943+ factory (callbacks);
944+ return true ;
945+ }));
946+ filter_manager_->createDownstreamFilterChain ();
947+
948+ RequestHeaderMapPtr headers{
949+ new TestRequestHeaderMapImpl{{" :authority" , " host" }, {" :path" , " /" }, {" :method" , " POST" }}};
950+ ON_CALL (filter_manager_callbacks_, requestHeaders ()).WillByDefault (Return (makeOptRef (*headers)));
951+
952+ EXPECT_CALL (*filter, decodeHeaders (_, false )).WillOnce (Return (FilterHeadersStatus::Continue));
953+ filter_manager_->requestHeadersInitialized ();
954+ filter_manager_->decodeHeaders (*headers, false );
955+
956+ // Simulate a downstream reset.
957+ filter_manager_->onDownstreamReset ();
958+
959+ // After reset, none of the decode operations should call the filter.
960+ EXPECT_CALL (*filter, decodeData (_, _)).Times (0 );
961+ EXPECT_CALL (*filter, decodeTrailers (_)).Times (0 );
962+ EXPECT_CALL (*filter, decodeMetadata (_)).Times (0 );
963+
964+ // Try all decode operations. None of them should reach the filter.
965+ Buffer::OwnedImpl data (" test_data" );
966+ filter_manager_->decodeData (data, false );
967+
968+ MetadataMap metadata_map{{" key" , " value" }};
969+ filter_manager_->decodeMetadata (metadata_map);
970+
971+ RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{" foo" , " bar" }}};
972+ ON_CALL (filter_manager_callbacks_, requestTrailers ())
973+ .WillByDefault (Return (makeOptRef (*trailers)));
974+ filter_manager_->decodeTrailers (*trailers);
975+
976+ filter_manager_->destroyFilters ();
977+ }
978+
794979} // namespace
795980} // namespace Http
796981} // namespace Envoy
0 commit comments