Skip to content

Commit

Permalink
Add unit test to verify that decodeMetadata is not run after local re…
Browse files Browse the repository at this point in the history
…ply.

Signed-off-by: Yiming Jin <[email protected]>
  • Loading branch information
GinYM committed May 15, 2021
1 parent 27e1563 commit 2373b0a
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/integration/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ envoy_cc_test_library(
"//source/extensions/filters/http/health_check:config",
"//test/common/http/http2:http2_frame",
"//test/integration/filters:continue_after_local_reply_filter_lib",
"//test/integration/filters:continue_after_local_reply_filter_with_metadata_lib",
"//test/integration/filters:continue_headers_only_inject_body",
"//test/integration/filters:encoder_decoder_buffer_filter_lib",
"//test/integration/filters:invalid_header_filter_lib",
Expand Down
15 changes: 15 additions & 0 deletions test/integration/filters/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,21 @@ envoy_cc_test_library(
],
)

envoy_cc_test_library(
name = "continue_after_local_reply_filter_with_metadata_lib",
srcs = [
"continue_after_local_reply_with_metadata_filter.cc",
],
deps = [
":common_lib",
"//include/envoy/http:filter_interface",
"//include/envoy/registry",
"//include/envoy/server:filter_config_interface",
"//source/extensions/filters/http/common:pass_through_filter_lib",
"//test/extensions/filters/http/common:empty_http_filter_config_lib",
],
)

envoy_cc_test_library(
name = "continue_headers_only_inject_body",
srcs = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "envoy/registry/registry.h"
#include "envoy/server/filter_config.h"

#include "extensions/filters/http/common/pass_through_filter.h"

#include "test/extensions/filters/http/common/empty_http_filter_config.h"
#include "test/integration/filters/common.h"

#include "gtest/gtest.h"

namespace Envoy {

// A filter that calls Http::FilterHeadersStatus::Continue and set metadata after a local reply.
class ContinueAfterLocalReplyWithMetadataFilter : public Http::PassThroughFilter {
public:
constexpr static char name[] = "continue-after-local-reply-with-metadata-filter";

Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool) override {
Http::MetadataMap metadata_map = {{"headers", "headers"}, {"duplicate", "duplicate"}};
Http::MetadataMapPtr metadata_map_ptr = std::make_unique<Http::MetadataMap>(metadata_map);
decoder_callbacks_->addDecodedMetadata().emplace_back(std::move(metadata_map_ptr));
decoder_callbacks_->sendLocalReply(Envoy::Http::Code::OK, "", nullptr, absl::nullopt,
"ContinueAfterLocalReplyFilter is ready");
return Http::FilterHeadersStatus::Continue;
}

// Adds new metadata to metadata_map directly
Http::FilterMetadataStatus decodeMetadata(Http::MetadataMap& metadata_map) override {
metadata_map["data"] = "data";
throw EnvoyException("Should not call decode metadata after local reply.");
return Http::FilterMetadataStatus::Continue;
}
};

constexpr char ContinueAfterLocalReplyWithMetadataFilter::name[];
static Registry::RegisterFactory<SimpleFilterConfig<ContinueAfterLocalReplyWithMetadataFilter>,
Server::Configuration::NamedHttpFilterConfigFactory>
register_;

} // namespace Envoy
25 changes: 25 additions & 0 deletions test/integration/protocol_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2314,4 +2314,29 @@ TEST_P(DownstreamProtocolIntegrationTest, HeaderNormalizationRejection) {
EXPECT_EQ("400", response->headers().getStatusValue());
}

// Tests a filter that returns a FilterHeadersStatus::Continue after a local reply without
// processing new metadata generated in decodeHeader
TEST_P(DownstreamProtocolIntegrationTest, ContinueAfterLocalReplyWithMetadata) {
config_helper_.addFilter(R"EOF(
name: continue-after-local-reply-with-metadata-filter
typed_config:
"@type": type.googleapis.com/google.protobuf.Empty
)EOF");
initialize();

codec_client_ = makeHttpConnection(lookupPort("http"));
// Send a headers only request.
IntegrationStreamDecoderPtr response;
EXPECT_ENVOY_BUG(
{
response = codec_client_->makeHeaderOnlyRequest(default_request_headers_);
ASSERT_TRUE(response->waitForEndStream());
ASSERT_TRUE(response->complete());
ASSERT_EQ("200", response->headers().getStatusValue());
ENVOY_LOG(info, "test upstream request");
},
"envoy bug failure: !continue_iteration || !state_.local_complete_. "
"Details: Filter did not return StopAll or StopIteration after sending a local reply.");
}

} // namespace Envoy

0 comments on commit 2373b0a

Please sign in to comment.