Add getter to grpc_metadata_batch. (#25395)

pull/25531/merge
Ashitha Santhosh 4 years ago committed by GitHub
parent 061fcbb214
commit dbe50923b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc
  2. 10
      src/core/lib/security/authorization/evaluate_args.cc
  3. 11
      src/core/lib/security/authorization/evaluate_args.h
  4. 27
      src/core/lib/transport/metadata_batch.cc
  5. 14
      src/core/lib/transport/metadata_batch.h
  6. 24
      test/core/security/evaluate_args_test.cc
  7. 66
      test/core/transport/metadata_test.cc

@ -518,29 +518,6 @@ void XdsResolver::XdsConfigSelector::MaybeAddCluster(const std::string& name) {
}
}
absl::optional<absl::string_view> GetMetadataValue(
const std::string& target_key, grpc_metadata_batch* initial_metadata,
std::string* concatenated_value) {
// Find all values for the specified key.
GPR_DEBUG_ASSERT(initial_metadata != nullptr);
absl::InlinedVector<absl::string_view, 1> values;
for (grpc_linked_mdelem* md = initial_metadata->list.head; md != nullptr;
md = md->next) {
absl::string_view key = StringViewFromSlice(GRPC_MDKEY(md->md));
absl::string_view value = StringViewFromSlice(GRPC_MDVALUE(md->md));
if (target_key == key) values.push_back(value);
}
// If none found, no match.
if (values.empty()) return absl::nullopt;
// If exactly one found, return it as-is.
if (values.size() == 1) return values.front();
// If more than one found, concatenate the values, using
// *concatenated_values as a temporary holding place for the
// concatenated string.
*concatenated_value = absl::StrJoin(values, ",");
return *concatenated_value;
}
bool HeaderMatchHelper(const HeaderMatcher& header_matcher,
grpc_metadata_batch* initial_metadata) {
std::string concatenated_value;
@ -554,8 +531,8 @@ bool HeaderMatchHelper(const HeaderMatcher& header_matcher,
} else if (header_matcher.name() == "content-type") {
value = "application/grpc";
} else {
value = GetMetadataValue(header_matcher.name(), initial_metadata,
&concatenated_value);
value = grpc_metadata_batch_get_value(
initial_metadata, header_matcher.name(), &concatenated_value);
}
return header_matcher.Match(value);
}

@ -20,6 +20,8 @@
#include "src/core/lib/security/authorization/evaluate_args.h"
#include "absl/strings/str_join.h"
#include "src/core/lib/iomgr/parse_address.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
@ -72,6 +74,14 @@ std::multimap<absl::string_view, absl::string_view> EvaluateArgs::GetHeaders()
return headers;
}
absl::optional<absl::string_view> EvaluateArgs::GetHeaderValue(
absl::string_view key, std::string* concatenated_value) const {
if (metadata_ == nullptr) {
return absl::nullopt;
}
return grpc_metadata_batch_get_value(metadata_, key, concatenated_value);
}
absl::string_view EvaluateArgs::GetLocalAddress() const {
absl::string_view addr = grpc_endpoint_get_local_address(endpoint_);
size_t first_colon = addr.find(":");

@ -23,6 +23,8 @@
#include <map>
#include "absl/types/optional.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/transport/metadata_batch.h"
@ -39,6 +41,15 @@ class EvaluateArgs {
absl::string_view GetHost() const;
absl::string_view GetMethod() const;
std::multimap<absl::string_view, absl::string_view> GetHeaders() const;
// Returns metadata value(s) for the specified key.
// If the key is not present in the batch, returns absl::nullopt.
// If the key is present exactly once in the batch, returns a string_view of
// that value.
// If the key is present more than once in the batch, constructs a
// comma-concatenated string of all values in concatenated_value and returns a
// string_view of that string.
absl::optional<absl::string_view> GetHeaderValue(
absl::string_view key, std::string* concatenated_value) const;
absl::string_view GetLocalAddress() const;
int GetLocalPort() const;
absl::string_view GetPeerAddress() const;

@ -23,6 +23,9 @@
#include <stdbool.h>
#include <string.h>
#include "absl/container/inlined_vector.h"
#include "absl/strings/str_join.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@ -296,6 +299,30 @@ void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage,
GRPC_MDELEM_UNREF(old_mdelem);
}
absl::optional<absl::string_view> grpc_metadata_batch_get_value(
grpc_metadata_batch* batch, absl::string_view target_key,
std::string* concatenated_value) {
// Find all values for the specified key.
GPR_DEBUG_ASSERT(batch != nullptr);
absl::InlinedVector<absl::string_view, 1> values;
for (grpc_linked_mdelem* md = batch->list.head; md != nullptr;
md = md->next) {
absl::string_view key = grpc_core::StringViewFromSlice(GRPC_MDKEY(md->md));
absl::string_view value =
grpc_core::StringViewFromSlice(GRPC_MDVALUE(md->md));
if (target_key == key) values.push_back(value);
}
// If none found, no match.
if (values.empty()) return absl::nullopt;
// If exactly one found, return it as-is.
if (values.size() == 1) return values.front();
// If more than one found, concatenate the values, using
// *concatenated_values as a temporary holding place for the
// concatenated string.
*concatenated_value = absl::StrJoin(values, ",");
return *concatenated_value;
}
grpc_error* grpc_metadata_batch_substitute(grpc_metadata_batch* batch,
grpc_linked_mdelem* storage,
grpc_mdelem new_mdelem) {

@ -23,9 +23,12 @@
#include <stdbool.h>
#include "absl/types/optional.h"
#include <grpc/grpc.h>
#include <grpc/slice.h>
#include <grpc/support/time.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/static_metadata.h"
@ -78,6 +81,17 @@ grpc_error* grpc_metadata_batch_substitute(grpc_metadata_batch* batch,
void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage,
const grpc_slice& value);
/** Returns metadata value(s) for the specified key.
If the key is not present in the batch, returns absl::nullopt.
If the key is present exactly once in the batch, returns a string_view of
that value.
If the key is present more than once in the batch, constructs a
comma-concatenated string of all values in concatenated_value and returns a
string_view of that string. */
absl::optional<absl::string_view> grpc_metadata_batch_get_value(
grpc_metadata_batch* batch, absl::string_view target_key,
std::string* concatenated_value);
/** Add \a storage to the beginning of \a batch. storage->md is
assumed to be valid.
\a storage is owned by the caller and must survive for the

@ -72,6 +72,7 @@ TEST(EvaluateArgsMetadataTest, HandlesNullMetadata) {
EXPECT_EQ(eval_args.GetMethod(), nullptr);
EXPECT_EQ(eval_args.GetHost(), nullptr);
EXPECT_THAT(eval_args.GetHeaders(), ::testing::ElementsAre());
EXPECT_EQ(eval_args.GetHeaderValue("some_key", nullptr), absl::nullopt);
}
TEST(EvaluateArgsMetadataTest, HandlesEmptyMetadata) {
@ -82,6 +83,7 @@ TEST(EvaluateArgsMetadataTest, HandlesEmptyMetadata) {
EXPECT_EQ(eval_args.GetMethod(), nullptr);
EXPECT_EQ(eval_args.GetHost(), nullptr);
EXPECT_THAT(eval_args.GetHeaders(), ::testing::ElementsAre());
EXPECT_EQ(eval_args.GetHeaderValue("some_key", nullptr), absl::nullopt);
grpc_metadata_batch_destroy(&metadata);
}
@ -171,6 +173,28 @@ TEST(EvaluateArgsMetadataTest, GetHeadersSuccess) {
grpc_shutdown();
}
TEST(EvaluateArgsMetadataTest, GetHeaderValueSuccess) {
grpc_init();
const char* kKey = "some_key";
const char* kValue = "some_value";
grpc_metadata_batch metadata;
grpc_metadata_batch_init(&metadata);
grpc_linked_mdelem storage;
storage.md = grpc_mdelem_from_slices(
grpc_slice_intern(grpc_slice_from_static_string(kKey)),
grpc_slice_intern(grpc_slice_from_static_string(kValue)));
ASSERT_EQ(grpc_metadata_batch_link_head(&metadata, &storage),
GRPC_ERROR_NONE);
EvaluateArgs eval_args(&metadata, nullptr, nullptr);
std::string concatenated_value;
absl::optional<absl::string_view> value =
eval_args.GetHeaderValue(kKey, &concatenated_value);
ASSERT_TRUE(value.has_value());
EXPECT_EQ(value.value(), kValue);
grpc_metadata_batch_destroy(&metadata);
grpc_shutdown();
}
TEST(EvaluateArgsAuthContextTest, HandlesNullAuthContext) {
EvaluateArgs eval_args(nullptr, nullptr, nullptr);
EXPECT_EQ(eval_args.GetSpiffeId(), nullptr);

@ -23,6 +23,7 @@
#include <string>
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include <grpc/grpc.h>
@ -34,6 +35,7 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/static_metadata.h"
#include "test/core/util/test_config.h"
@ -392,6 +394,67 @@ static void test_copied_static_metadata(bool dup_key, bool dup_value) {
grpc_shutdown();
}
static void test_grpc_metadata_batch_get_value_with_absent_key(void) {
grpc_init();
grpc_metadata_batch metadata;
grpc_metadata_batch_init(&metadata);
std::string concatenated_value;
absl::optional<absl::string_view> value = grpc_metadata_batch_get_value(
&metadata, "absent_key", &concatenated_value);
GPR_ASSERT(value == absl::nullopt);
grpc_metadata_batch_destroy(&metadata);
grpc_shutdown();
}
static void test_grpc_metadata_batch_get_value_returns_one_value(void) {
grpc_init();
const char* kKey = "some_key";
const char* kValue = "some_value";
grpc_metadata_batch metadata;
grpc_metadata_batch_init(&metadata);
grpc_linked_mdelem storage;
storage.md = grpc_mdelem_from_slices(
grpc_slice_intern(grpc_slice_from_static_string(kKey)),
grpc_slice_intern(grpc_slice_from_static_string(kValue)));
GPR_ASSERT(grpc_metadata_batch_link_head(&metadata, &storage) ==
GRPC_ERROR_NONE);
std::string concatenated_value;
absl::optional<absl::string_view> value =
grpc_metadata_batch_get_value(&metadata, kKey, &concatenated_value);
GPR_ASSERT(value.has_value());
GPR_ASSERT(value.value() == kValue);
grpc_metadata_batch_destroy(&metadata);
grpc_shutdown();
}
static void test_grpc_metadata_batch_get_value_returns_multiple_values(void) {
grpc_init();
const char* kKey = "some_key";
const char* kValue1 = "value1";
const char* kValue2 = "value2";
grpc_metadata_batch metadata;
grpc_metadata_batch_init(&metadata);
grpc_linked_mdelem storage1;
storage1.md = grpc_mdelem_from_slices(
grpc_slice_intern(grpc_slice_from_static_string(kKey)),
grpc_slice_intern(grpc_slice_from_static_string(kValue1)));
GPR_ASSERT(grpc_metadata_batch_link_tail(&metadata, &storage1) ==
GRPC_ERROR_NONE);
grpc_linked_mdelem storage2;
storage2.md = grpc_mdelem_from_slices(
grpc_slice_intern(grpc_slice_from_static_string(kKey)),
grpc_slice_intern(grpc_slice_from_static_string(kValue2)));
GPR_ASSERT(grpc_metadata_batch_link_tail(&metadata, &storage2) ==
GRPC_ERROR_NONE);
std::string concatenated_value;
absl::optional<absl::string_view> value =
grpc_metadata_batch_get_value(&metadata, kKey, &concatenated_value);
GPR_ASSERT(value.has_value());
GPR_ASSERT(value.value() == absl::StrCat(kValue1, ",", kValue2));
grpc_metadata_batch_destroy(&metadata);
grpc_shutdown();
}
int main(int argc, char** argv) {
grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
@ -410,6 +473,9 @@ int main(int argc, char** argv) {
test_things_stick_around();
test_user_data_works();
test_user_data_works_for_allocated_md();
test_grpc_metadata_batch_get_value_with_absent_key();
test_grpc_metadata_batch_get_value_returns_one_value();
test_grpc_metadata_batch_get_value_returns_multiple_values();
grpc_shutdown();
return 0;
}

Loading…
Cancel
Save