Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion api/envoy/data/tap/v2alpha/http.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ import "envoy/api/v2/core/base.proto";
// A fully buffered HTTP trace message.
message HttpBufferedTrace {
// Request headers.
repeated api.v2.core.HeaderValue request_headers = 2;
repeated api.v2.core.HeaderValue request_headers = 1;

// Request trailers.
repeated api.v2.core.HeaderValue request_trailers = 2;

// Response headers.
repeated api.v2.core.HeaderValue response_headers = 3;

// Response trailers.
Comment thread
mattklein123 marked this conversation as resolved.
Outdated
repeated api.v2.core.HeaderValue response_trailers = 4;
}
26 changes: 13 additions & 13 deletions api/envoy/service/tap/v2alpha/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,23 @@ message MatchPredicate {
// The match configuration will always match.
bool any_match = 4 [(validate.rules).bool.const = true];

// HTTP request match configuration.
HttpRequestMatch http_request_match = 5;
// HTTP request headers match configuration.
HttpHeadersMatch http_request_headers_match = 5;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we organize this a bit, just like how BufferedTrace organized? i.e.

message HttpMessageMatch {
  HttpHeadersMatch headers_match;
  HttpTrailersMatch trailers_match;
}

?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how I had this originally, but IMO we don't want this, because it makes it much more confusing on how to apply and/or logic.


// HTTP response match configuration.
HttpResponseMatch http_response_match = 6;
}
}
// HTTP request trailers match configuration.
HttpHeadersMatch http_request_trailers_match = 6;

// HTTP request match configuration.
message HttpRequestMatch {
// HTTP request headers to match.
repeated api.v2.route.HeaderMatcher headers = 1;
// HTTP response headers match configuration.
HttpHeadersMatch http_response_headers_match = 7;

// HTTP response trailers match configuration.
HttpHeadersMatch http_response_trailers_match = 8;
}
}

// HTTP response match configuration.
message HttpResponseMatch {
// HTTP response headers to match.
// HTTP headers match configuration.
message HttpHeadersMatch {
// HTTP headers to match.
repeated api.v2.route.HeaderMatcher headers = 1;
}

Expand Down
8 changes: 4 additions & 4 deletions docs/root/configuration/http_filters/tap_filter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ An example POST body:
match_config:
and_match:
rules:
- http_request_match:
- http_request_headers_match:
headers:
- name: foo
exact_match: bar
- http_response_match:
- http_response_headers_match:
headers:
- name: bar
exact_match: baz
Expand All @@ -90,11 +90,11 @@ Another example POST body:
match_config:
or_match:
rules:
- http_request_match:
- http_request_headers_match:
headers:
- name: foo
exact_match: bar
- http_response_match:
- http_response_headers_match:
headers:
- name: bar
exact_match: baz
Expand Down
1 change: 1 addition & 0 deletions source/common/router/router.cc
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ Http::FilterDataStatus Filter::decodeData(Buffer::Instance& data, bool end_strea
}

Http::FilterTrailersStatus Filter::decodeTrailers(Http::HeaderMap& trailers) {
ENVOY_STREAM_LOG(debug, "router decoding trailers:\n{}", *callbacks_, trailers);
downstream_trailers_ = &trailers;
upstream_request_->encodeTrailers(trailers);
onRequestComplete();
Expand Down
99 changes: 31 additions & 68 deletions source/extensions/common/tap/tap_matcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,21 @@ void buildMatcher(const envoy::service::tap::v2alpha::MatchPredicate& match_conf
case envoy::service::tap::v2alpha::MatchPredicate::kAnyMatch:
new_matcher = std::make_unique<AnyMatcher>(matchers);
break;
case envoy::service::tap::v2alpha::MatchPredicate::kHttpRequestMatch:
new_matcher = std::make_unique<HttpRequestMatcher>(match_config.http_request_match(), matchers);
case envoy::service::tap::v2alpha::MatchPredicate::kHttpRequestHeadersMatch:
new_matcher = std::make_unique<HttpRequestHeadersMatcher>(
match_config.http_request_headers_match(), matchers);
break;
case envoy::service::tap::v2alpha::MatchPredicate::kHttpResponseMatch:
new_matcher =
std::make_unique<HttpResponseMatcher>(match_config.http_response_match(), matchers);
case envoy::service::tap::v2alpha::MatchPredicate::kHttpRequestTrailersMatch:
new_matcher = std::make_unique<HttpRequestTrailersMatcher>(
match_config.http_request_trailers_match(), matchers);
break;
case envoy::service::tap::v2alpha::MatchPredicate::kHttpResponseHeadersMatch:
new_matcher = std::make_unique<HttpResponseHeadersMatcher>(
match_config.http_response_headers_match(), matchers);
break;
case envoy::service::tap::v2alpha::MatchPredicate::kHttpResponseTrailersMatch:
new_matcher = std::make_unique<HttpResponseTrailersMatcher>(
match_config.http_response_trailers_match(), matchers);
break;
default:
NOT_REACHED_GCOVR_EXCL_LINE;
Expand All @@ -50,14 +59,19 @@ void buildMatcher(const envoy::service::tap::v2alpha::MatchPredicate& match_conf
SetLogicMatcher::SetLogicMatcher(
const envoy::service::tap::v2alpha::MatchPredicate::MatchSet& configs,
std::vector<MatcherPtr>& matchers, Type type)
: Matcher(matchers), matchers_(matchers), type_(type) {
: LogicMatcherBase(matchers), matchers_(matchers), type_(type) {
for (const auto& config : configs.rules()) {
indexes_.push_back(matchers_.size());
buildMatcher(config, matchers_);
}
}

bool SetLogicMatcher::updateLocalStatus(std::vector<bool>& statuses) const {
bool SetLogicMatcher::updateLocalStatus(std::vector<bool>& statuses,
const UpdateFunctor& functor) const {
for (size_t index : indexes_) {
statuses[index] = functor(*matchers_[index], statuses);
}

auto predicate = [&statuses](size_t index) { return statuses[index]; };
if (type_ == Type::And) {
statuses[my_index_] = std::all_of(indexes_.begin(), indexes_.end(), predicate);
Expand All @@ -69,81 +83,30 @@ bool SetLogicMatcher::updateLocalStatus(std::vector<bool>& statuses) const {
return statuses[my_index_];
}

bool SetLogicMatcher::onNewStream(std::vector<bool>& statuses) const {
for (size_t index : indexes_) {
statuses[index] = matchers_[index]->onNewStream(statuses);
}

return updateLocalStatus(statuses);
}

bool SetLogicMatcher::onHttpRequestHeaders(const Http::HeaderMap& request_headers,
std::vector<bool>& statuses) const {
for (size_t index : indexes_) {
statuses[index] = matchers_[index]->onHttpRequestHeaders(request_headers, statuses);
}

return updateLocalStatus(statuses);
}

bool SetLogicMatcher::onHttpResponseHeaders(const Http::HeaderMap& response_headers,
std::vector<bool>& statuses) const {
for (size_t index : indexes_) {
statuses[index] = matchers_[index]->onHttpResponseHeaders(response_headers, statuses);
}

return updateLocalStatus(statuses);
}

NotMatcher::NotMatcher(const envoy::service::tap::v2alpha::MatchPredicate& config,
std::vector<MatcherPtr>& matchers)
: Matcher(matchers), matchers_(matchers), not_index_(matchers.size()) {
: LogicMatcherBase(matchers), matchers_(matchers), not_index_(matchers.size()) {
buildMatcher(config, matchers);
}

bool NotMatcher::onNewStream(std::vector<bool>& statuses) const {
statuses[my_index_] = !matchers_[not_index_]->onNewStream(statuses);
return statuses[my_index_];
}

bool NotMatcher::onHttpRequestHeaders(const Http::HeaderMap& request_headers,
std::vector<bool>& statuses) const {
statuses[my_index_] = !matchers_[not_index_]->onHttpRequestHeaders(request_headers, statuses);
return statuses[my_index_];
}

bool NotMatcher::onHttpResponseHeaders(const Http::HeaderMap& response_headers,
std::vector<bool>& statuses) const {
statuses[my_index_] = !matchers_[not_index_]->onHttpResponseHeaders(response_headers, statuses);
return statuses[my_index_];
}

HttpRequestMatcher::HttpRequestMatcher(const envoy::service::tap::v2alpha::HttpRequestMatch& config,
const std::vector<MatcherPtr>& matchers)
: Matcher(matchers) {
for (const auto& header_match : config.headers()) {
headers_to_match_.emplace_back(header_match);
}
}

bool HttpRequestMatcher::onHttpRequestHeaders(const Http::HeaderMap& request_headers,
std::vector<bool>& statuses) const {
statuses[my_index_] = Http::HeaderUtility::matchHeaders(request_headers, headers_to_match_);
bool NotMatcher::updateLocalStatus(std::vector<bool>& statuses,
const UpdateFunctor& functor) const {
statuses[my_index_] = !functor(*matchers_[not_index_], statuses);
return statuses[my_index_];
}

HttpResponseMatcher::HttpResponseMatcher(
const envoy::service::tap::v2alpha::HttpResponseMatch& config,
HttpHeaderMatcherBase::HttpHeaderMatcherBase(
const envoy::service::tap::v2alpha::HttpHeadersMatch& config,
const std::vector<MatcherPtr>& matchers)
: Matcher(matchers) {
: SimpleMatcher(matchers) {
for (const auto& header_match : config.headers()) {
headers_to_match_.emplace_back(header_match);
}
}

bool HttpResponseMatcher::onHttpResponseHeaders(const Http::HeaderMap& response_headers,
std::vector<bool>& statuses) const {
statuses[my_index_] = Http::HeaderUtility::matchHeaders(response_headers, headers_to_match_);
bool HttpHeaderMatcherBase::matchHeaders(const Http::HeaderMap& headers,
std::vector<bool>& statuses) const {
statuses[my_index_] = Http::HeaderUtility::matchHeaders(headers, headers_to_match_);
return statuses[my_index_];
}

Expand Down
Loading