Properly clear metadata and other structs when reusing ServerContext

pull/17197/head
Vijay Pai 6 years ago
parent b79462f186
commit 0e29d7b9bc
  1. 19
      include/grpcpp/impl/codegen/metadata_map.h
  2. 4
      src/cpp/server/server_context.cc
  3. 17
      test/cpp/end2end/client_callback_end2end_test.cc

@ -32,11 +32,9 @@ const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
class MetadataMap { class MetadataMap {
public: public:
MetadataMap() { memset(&arr_, 0, sizeof(arr_)); } MetadataMap() { Setup(); }
~MetadataMap() { ~MetadataMap() { Destroy(); }
g_core_codegen_interface->grpc_metadata_array_destroy(&arr_);
}
grpc::string GetBinaryErrorDetails() { grpc::string GetBinaryErrorDetails() {
// if filled_, extract from the multimap for O(log(n)) // if filled_, extract from the multimap for O(log(n))
@ -71,11 +69,24 @@ class MetadataMap {
} }
grpc_metadata_array* arr() { return &arr_; } grpc_metadata_array* arr() { return &arr_; }
void Reset() {
filled_ = false;
map_.clear();
Destroy();
Setup();
}
private: private:
bool filled_ = false; bool filled_ = false;
grpc_metadata_array arr_; grpc_metadata_array arr_;
std::multimap<grpc::string_ref, grpc::string_ref> map_; std::multimap<grpc::string_ref, grpc::string_ref> map_;
void Destroy() {
g_core_codegen_interface->grpc_metadata_array_destroy(&arr_);
}
void Setup() { memset(&arr_, 0, sizeof(arr_)); }
void FillMap() { void FillMap() {
if (filled_) return; if (filled_) return;
filled_ = true; filled_ = true;

@ -247,6 +247,10 @@ void ServerContext::BindDeadlineAndMetadata(gpr_timespec deadline,
ServerContext::~ServerContext() { Clear(); } ServerContext::~ServerContext() { Clear(); }
void ServerContext::Clear() { void ServerContext::Clear() {
auth_context_.reset();
initial_metadata_.clear();
trailing_metadata_.clear();
client_metadata_.Reset();
if (call_) { if (call_) {
grpc_call_unref(call_); grpc_call_unref(call_);
} }

@ -34,6 +34,7 @@
#include "test/core/util/test_config.h" #include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h" #include "test/cpp/end2end/test_service_impl.h"
#include "test/cpp/util/byte_buffer_proto_helper.h" #include "test/cpp/util/byte_buffer_proto_helper.h"
#include "test/cpp/util/string_ref_helper.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -100,11 +101,13 @@ class ClientCallbackEnd2endTest
test_string += "Hello world. "; test_string += "Hello world. ";
request.set_message(test_string); request.set_message(test_string);
grpc::string val;
if (with_binary_metadata) { if (with_binary_metadata) {
request.mutable_param()->set_echo_metadata(true);
char bytes[8] = {'\0', '\1', '\2', '\3', char bytes[8] = {'\0', '\1', '\2', '\3',
'\4', '\5', '\6', static_cast<char>(i)}; '\4', '\5', '\6', static_cast<char>(i)};
cli_ctx.AddMetadata("custom-bin", grpc::string(bytes, 8)); val = grpc::string(bytes, 8);
cli_ctx.AddMetadata("custom-bin", val);
} }
cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP);
@ -114,10 +117,18 @@ class ClientCallbackEnd2endTest
bool done = false; bool done = false;
stub_->experimental_async()->Echo( stub_->experimental_async()->Echo(
&cli_ctx, &request, &response, &cli_ctx, &request, &response,
[&request, &response, &done, &mu, &cv](Status s) { [&cli_ctx, &request, &response, &done, &mu, &cv, val,
with_binary_metadata](Status s) {
GPR_ASSERT(s.ok()); GPR_ASSERT(s.ok());
EXPECT_EQ(request.message(), response.message()); EXPECT_EQ(request.message(), response.message());
if (with_binary_metadata) {
EXPECT_EQ(
1u, cli_ctx.GetServerTrailingMetadata().count("custom-bin"));
EXPECT_EQ(val, ToString(cli_ctx.GetServerTrailingMetadata()
.find("custom-bin")
->second));
}
std::lock_guard<std::mutex> l(mu); std::lock_guard<std::mutex> l(mu);
done = true; done = true;
cv.notify_one(); cv.notify_one();

Loading…
Cancel
Save