Move content-type, colon prefixed metadata to new system (#28204)

* Eliminate most of grpc_message metadata handling

* Eliminate most of host metadata handling

* Remove more callouts without fixing code

* fiiixes

* typo

* Automated change: Fix sanity tests

* try-shrink

* Automated change: Fix sanity tests

* size tweaks

* less tricks

* deunique

* commonize

* commonize

* Automated change: Fix sanity tests

* size tuning, fixes

* Automated change: Fix sanity tests

* fix

* size tuning, fixes

* remove constexpr

* fix

* reuse code

* fix

* tweak code

* more tweaks

* tell no lies

* fixes

* fixes

* Automated change: Fix sanity tests

* fix

* fix

* fix

* fix

* fix?

* fix binder

* fix

* fix

* fixes

* Automated change: Fix sanity tests

* fix

* initial refactoring

* optimize status encoding

* Automated change: Fix sanity tests

* Automated change: Fix sanity tests

* content-type

* Automated change: Fix sanity tests

* clang-format

* fix

* Move colon prefixed metadata

* Automated change: Fix sanity tests

* Automated change: Fix sanity tests

* try to fix windows failure

* try and scale sizes better

* ambiguity fix?

* wip metadatavalueasslice

* Fix status code for resource exhaustion

* Revert "Revert "Move a bunch of slice typed metadata to new system (#28107)" (#28208)"

This reverts commit 7717587063.

* fix test

* Automated change: Fix sanity tests

* Automated change: Fix sanity tests

* slice helper

* x

* noinline

* try and scale sizes better

* Automated change: Fix sanity tests

* fixes

* fix

* fix

* fixes

* fix build

* fix overflow

* progress

* Automated change: Fix sanity tests

* fix

* fix

* fix

* Automated change: Fix sanity tests

* fix

* fix

* fix

* compressor for path/authority

* Automated change: Fix sanity tests

* legalize

* status-enc

* fmt

* fix

* fix

* fix

* fix

* fix/opt

* fix

* fix

* fix

* fix

* Automated change: Fix sanity tests

* remove arg

* review feedback

* fix

* Small improvement in memory usage and performance

* Automated change: Fix sanity tests

* fix crash in alts

* review feedback

* fixes

* fixes

* fixes

* Automated change: Fix sanity tests

* speedup

* fix

* fix

* add comment

* add comment

Co-authored-by: ctiller <ctiller@users.noreply.github.com>
pull/28103/head
Craig Tiller 3 years ago committed by GitHub
parent a9a14a461b
commit 0deb64d1f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      src/core/ext/filters/client_channel/client_channel.cc
  2. 9
      src/core/ext/filters/client_channel/health/health_check_client.cc
  3. 1
      src/core/ext/filters/client_channel/health/health_check_client.h
  4. 2
      src/core/ext/filters/client_channel/retry_filter.cc
  5. 170
      src/core/ext/filters/http/client/http_client_filter.cc
  6. 31
      src/core/ext/filters/http/client_authority_filter.cc
  7. 184
      src/core/ext/filters/http/server/http_server_filter.cc
  8. 65
      src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
  9. 3
      src/core/ext/filters/load_reporting/server_load_reporting_filter.h
  10. 32
      src/core/ext/transport/binder/transport/binder_transport.cc
  11. 179
      src/core/ext/transport/chttp2/transport/hpack_encoder.cc
  12. 83
      src/core/ext/transport/chttp2/transport/hpack_encoder.h
  13. 21
      src/core/ext/transport/chttp2/transport/hpack_parser.cc
  14. 8
      src/core/ext/transport/chttp2/transport/hpack_parser_table.h
  15. 36
      src/core/ext/transport/chttp2/transport/writing.cc
  16. 75
      src/core/ext/transport/cronet/transport/cronet_transport.cc
  17. 12
      src/core/ext/xds/xds_server_config_fetcher.cc
  18. 28
      src/core/lib/security/authorization/evaluate_args.cc
  19. 39
      src/core/lib/security/transport/client_auth_filter.cc
  20. 5
      src/core/lib/slice/slice.h
  21. 330
      src/core/lib/slice/static_slice.cc
  22. 135
      src/core/lib/slice/static_slice.h
  23. 52
      src/core/lib/surface/call.cc
  24. 6
      src/core/lib/surface/call.h
  25. 61
      src/core/lib/surface/channel.cc
  26. 4
      src/core/lib/surface/channel.h
  27. 30
      src/core/lib/surface/server.cc
  28. 4
      src/core/lib/surface/server.h
  29. 265
      src/core/lib/transport/metadata_batch.h
  30. 62
      src/core/lib/transport/parsed_metadata.h
  31. 617
      src/core/lib/transport/static_metadata.cc
  32. 49
      src/core/lib/transport/static_metadata.h
  33. 2
      src/core/tsi/alts/handshaker/alts_handshaker_client.cc
  34. 3
      src/cpp/ext/filters/census/client_filter.cc
  35. 9
      src/cpp/ext/filters/census/context.h
  36. 2
      src/cpp/ext/filters/census/open_census_call_tracer.h
  37. 15
      src/cpp/ext/filters/census/server_filter.cc
  38. 3
      src/cpp/ext/filters/census/server_filter.h
  39. 14
      test/core/end2end/fuzzers/hpack.dictionary
  40. 7
      test/core/end2end/tests/filter_status_code.cc
  41. 9
      test/core/end2end/tests/retry_exceeds_buffer_size_in_delay.cc
  42. 9
      test/core/end2end/tests/retry_server_pushback_delay.cc
  43. 57
      test/core/transport/binder/binder_transport_test.cc
  44. 33
      test/core/transport/chttp2/hpack_parser_test.cc
  45. 12
      test/core/transport/parsed_metadata_test.cc
  46. 6
      test/core/util/evaluate_args_test_util.h
  47. 281
      test/cpp/microbenchmarks/bm_chttp2_hpack.cc
  48. 34
      test/cpp/microbenchmarks/bm_chttp2_transport.cc
  49. 4
      test/cpp/microbenchmarks/representative_server_initial_metadata.headers
  50. 3
      test/cpp/microbenchmarks/representative_server_trailing_metadata.headers
  51. 9
      tools/codegen/core/gen_static_metadata.py

@ -2433,11 +2433,8 @@ class ClientChannel::LoadBalancedCall::Metadata
class Encoder {
public:
void Encode(grpc_mdelem md) {
auto key = StringViewFromSlice(GRPC_MDKEY(md));
if (key != ":path") {
out_.emplace_back(std::string(key),
std::string(StringViewFromSlice(GRPC_MDVALUE(md))));
}
out_.emplace_back(std::string(StringViewFromSlice(GRPC_MDKEY(md))),
std::string(StringViewFromSlice(GRPC_MDVALUE(md))));
}
template <class Which>
@ -2448,6 +2445,7 @@ class ClientChannel::LoadBalancedCall::Metadata
}
void Encode(GrpcTimeoutMetadata, grpc_millis) {}
void Encode(HttpPathMetadata, const Slice&) {}
std::vector<std::pair<std::string, std::string>> Take() {
return std::move(out_);

@ -326,12 +326,9 @@ void HealthCheckClient::CallState::StartCall() {
batch_.on_complete = GRPC_CLOSURE_INIT(&on_complete_, OnComplete, this,
grpc_schedule_on_exec_ctx);
// Add send_initial_metadata op.
error = grpc_metadata_batch_add_head(
&send_initial_metadata_, &path_metadata_storage_,
grpc_mdelem_from_slices(
GRPC_MDSTR_PATH,
GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH),
GRPC_BATCH_PATH);
send_initial_metadata_.Set(
HttpPathMetadata(),
Slice(GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH));
GPR_ASSERT(error == GRPC_ERROR_NONE);
payload_.send_initial_metadata.send_initial_metadata =
&send_initial_metadata_;

@ -111,7 +111,6 @@ class HealthCheckClient : public InternallyRefCounted<HealthCheckClient> {
// send_initial_metadata
grpc_metadata_batch send_initial_metadata_;
grpc_linked_mdelem path_metadata_storage_;
// send_message
ManualConstructor<SliceBufferByteStream> send_message_;

@ -1544,7 +1544,7 @@ void GetCallStatus(grpc_millis deadline, grpc_metadata_batch* md_batch,
*is_lb_drop = true;
}
} else {
*status = md_batch->get(GrpcStatusMetadata()).value_or(GRPC_STATUS_UNKNOWN);
*status = *md_batch->get(GrpcStatusMetadata());
*server_pushback_ms = md_batch->get(GrpcRetryPushbackMsMetadata());
}
GRPC_ERROR_UNREF(error);

@ -75,10 +75,6 @@ struct call_data {
~call_data() { GRPC_ERROR_UNREF(recv_initial_metadata_error); }
grpc_core::CallCombiner* call_combiner;
// State for handling send_initial_metadata ops.
grpc_linked_mdelem method;
grpc_linked_mdelem scheme;
grpc_linked_mdelem content_type;
// State for handling recv_initial_metadata ops.
grpc_metadata_batch* recv_initial_metadata;
grpc_error_handle recv_initial_metadata_error = GRPC_ERROR_NONE;
@ -102,7 +98,7 @@ struct call_data {
};
struct channel_data {
grpc_mdelem static_scheme;
grpc_core::HttpSchemeMetadata::ValueType static_scheme;
grpc_core::Slice user_agent;
size_t max_payload_size_for_get;
};
@ -110,32 +106,27 @@ struct channel_data {
static grpc_error_handle client_filter_incoming_metadata(
grpc_metadata_batch* b) {
if (b->legacy_index()->named.status != nullptr) {
if (auto* status = b->get_pointer(grpc_core::HttpStatusMetadata())) {
/* If both gRPC status and HTTP status are provided in the response, we
* should prefer the gRPC status code, as mentioned in
* https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md.
*/
const grpc_status_code* grpc_status =
b->get_pointer(grpc_core::GrpcStatusMetadata());
if (grpc_status != nullptr ||
grpc_mdelem_static_value_eq(b->legacy_index()->named.status->md,
GRPC_MDELEM_STATUS_200)) {
b->Remove(GRPC_BATCH_STATUS);
if (grpc_status != nullptr || *status == 200) {
b->Remove(grpc_core::HttpStatusMetadata());
} else {
char* val = grpc_dump_slice(
GRPC_MDVALUE(b->legacy_index()->named.status->md), GPR_DUMP_ASCII);
std::string msg =
absl::StrCat("Received http2 header with status: ", val);
absl::StrCat("Received http2 header with status: ", *status);
grpc_error_handle e = grpc_error_set_str(
grpc_error_set_int(
grpc_error_set_str(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Received http2 :status header with non-200 OK status"),
GRPC_ERROR_STR_VALUE, val),
GRPC_ERROR_STR_VALUE, std::to_string(*status)),
GRPC_ERROR_INT_GRPC_STATUS,
grpc_http2_status_to_grpc_status(atoi(val))),
grpc_http2_status_to_grpc_status(*status)),
GRPC_ERROR_STR_GRPC_MESSAGE, msg);
gpr_free(val);
return e;
}
}
@ -146,38 +137,7 @@ static grpc_error_handle client_filter_incoming_metadata(
grpc_core::PermissivePercentDecodeSlice(std::move(*grpc_message));
}
if (b->legacy_index()->named.content_type != nullptr) {
if (!grpc_mdelem_static_value_eq(
b->legacy_index()->named.content_type->md,
GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) {
if (grpc_slice_buf_start_eq(
GRPC_MDVALUE(b->legacy_index()->named.content_type->md),
EXPECTED_CONTENT_TYPE, EXPECTED_CONTENT_TYPE_LENGTH) &&
(GRPC_SLICE_START_PTR(GRPC_MDVALUE(
b->legacy_index()
->named.content_type->md))[EXPECTED_CONTENT_TYPE_LENGTH] ==
'+' ||
GRPC_SLICE_START_PTR(GRPC_MDVALUE(
b->legacy_index()
->named.content_type->md))[EXPECTED_CONTENT_TYPE_LENGTH] ==
';')) {
/* Although the C implementation doesn't (currently) generate them,
any custom +-suffix is explicitly valid. */
/* TODO(klempner): We should consider preallocating common values such
as +proto or +json, or at least stashing them if we see them. */
/* TODO(klempner): Should we be surfacing this to application code? */
} else {
/* TODO(klempner): We're currently allowing this, but we shouldn't
see it without a proxy so log for now. */
char* val = grpc_dump_slice(
GRPC_MDVALUE(b->legacy_index()->named.content_type->md),
GPR_DUMP_ASCII);
gpr_log(GPR_INFO, "Unexpected content-type '%s'", val);
gpr_free(val);
}
}
b->Remove(GRPC_BATCH_CONTENT_TYPE);
}
b->Remove(grpc_core::ContentTypeMetadata());
return GRPC_ERROR_NONE;
}
@ -308,53 +268,41 @@ static char* slice_buffer_to_string(grpc_slice_buffer* slice_buffer) {
// Modifies the path entry in the batch's send_initial_metadata to
// append the base64-encoded query for a GET request.
static grpc_error_handle update_path_for_get(
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
static void update_path_for_get(grpc_call_element* elem,
grpc_transport_stream_op_batch* batch) {
grpc_metadata_batch* b =
batch->payload->send_initial_metadata.send_initial_metadata;
call_data* calld = static_cast<call_data*>(elem->call_data);
grpc_slice path_slice =
GRPC_MDVALUE(batch->payload->send_initial_metadata.send_initial_metadata
->legacy_index()
->named.path->md);
const grpc_core::Slice& path_slice =
*b->get_pointer(grpc_core::HttpPathMetadata());
/* sum up individual component's lengths and allocate enough memory to
* hold combined path+query */
size_t estimated_len = GRPC_SLICE_LENGTH(path_slice);
size_t estimated_len = path_slice.size();
estimated_len++; /* for the '?' */
estimated_len += grpc_base64_estimate_encoded_size(
batch->payload->send_message.send_message->length(),
false /* multi_line */);
grpc_core::UnmanagedMemorySlice path_with_query_slice(estimated_len);
grpc_core::MutableSlice path_with_query_slice =
grpc_core::MutableSlice::CreateUninitialized(estimated_len);
/* memcopy individual pieces into this slice */
char* write_ptr =
reinterpret_cast<char*> GRPC_SLICE_START_PTR(path_with_query_slice);
char* original_path =
reinterpret_cast<char*> GRPC_SLICE_START_PTR(path_slice);
memcpy(write_ptr, original_path, GRPC_SLICE_LENGTH(path_slice));
write_ptr += GRPC_SLICE_LENGTH(path_slice);
uint8_t* write_ptr = path_with_query_slice.begin();
const uint8_t* original_path = path_slice.data();
memcpy(write_ptr, original_path, path_slice.size());
write_ptr += path_slice.size();
*write_ptr++ = '?';
char* payload_bytes =
slice_buffer_to_string(calld->send_message_cache->cache_buffer());
grpc_base64_encode_core(write_ptr, payload_bytes,
grpc_base64_encode_core(reinterpret_cast<char*>(write_ptr), payload_bytes,
batch->payload->send_message.send_message->length(),
true /* url_safe */, false /* multi_line */);
gpr_free(payload_bytes);
/* remove trailing unused memory and add trailing 0 to terminate string */
char* t =
reinterpret_cast<char*> GRPC_SLICE_START_PTR(path_with_query_slice) +
GRPC_SLICE_LENGTH(path_slice);
char* t = reinterpret_cast<char*>(path_with_query_slice.begin()) +
path_slice.size();
/* safe to use strlen since base64_encode will always add '\0' */
path_with_query_slice = grpc_slice_sub_no_ref(
path_with_query_slice, 0, GRPC_SLICE_LENGTH(path_slice) + strlen(t));
/* substitute previous path with the new path+query */
grpc_mdelem mdelem_path_and_query =
grpc_mdelem_from_slices(GRPC_MDSTR_PATH, path_with_query_slice);
grpc_metadata_batch* b =
batch->payload->send_initial_metadata.send_initial_metadata;
return b->Substitute(b->legacy_index()->named.path, mdelem_path_and_query);
}
static void remove_if_present(grpc_metadata_batch* batch,
grpc_metadata_batch_callouts_index idx) {
batch->Remove(idx);
b->Set(grpc_core::HttpPathMetadata(),
grpc_core::Slice(path_with_query_slice.TakeSubSlice(
0, path_slice.size() + strlen(t))));
}
static void http_client_start_transport_stream_op_batch(
@ -390,7 +338,8 @@ static void http_client_start_transport_stream_op_batch(
// cacheable, and the operation contains both initial metadata and send
// message, and the payload is below the size threshold, and all the data
// for this request is immediately available.
grpc_mdelem method = GRPC_MDELEM_METHOD_POST;
grpc_core::HttpMethodMetadata::ValueType method =
grpc_core::HttpMethodMetadata::kPost;
if (batch->send_message &&
(batch->payload->send_initial_metadata.send_initial_metadata_flags &
GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) &&
@ -410,9 +359,8 @@ static void http_client_start_transport_stream_op_batch(
// If all the data has been read, then we can use GET.
if (calld->send_message_bytes_read ==
calld->send_message_caching_stream->length()) {
method = GRPC_MDELEM_METHOD_GET;
error = update_path_for_get(elem, batch);
if (error != GRPC_ERROR_NONE) goto done;
method = grpc_core::HttpMethodMetadata::kGet;
update_path_for_get(elem, batch);
batch->send_message = false;
calld->send_message_caching_stream->Orphan();
} else {
@ -427,36 +375,20 @@ static void http_client_start_transport_stream_op_batch(
} else if (batch->payload->send_initial_metadata
.send_initial_metadata_flags &
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) {
method = GRPC_MDELEM_METHOD_PUT;
method = grpc_core::HttpMethodMetadata::kPut;
}
remove_if_present(
batch->payload->send_initial_metadata.send_initial_metadata,
GRPC_BATCH_METHOD);
remove_if_present(
batch->payload->send_initial_metadata.send_initial_metadata,
GRPC_BATCH_SCHEME);
remove_if_present(
batch->payload->send_initial_metadata.send_initial_metadata,
GRPC_BATCH_CONTENT_TYPE);
/* Send : prefixed headers, which have to be before any application
layer headers. */
error = grpc_metadata_batch_add_head(
batch->payload->send_initial_metadata.send_initial_metadata,
&calld->method, method, GRPC_BATCH_METHOD);
if (error != GRPC_ERROR_NONE) goto done;
error = grpc_metadata_batch_add_head(
batch->payload->send_initial_metadata.send_initial_metadata,
&calld->scheme, channeld->static_scheme, GRPC_BATCH_SCHEME);
if (error != GRPC_ERROR_NONE) goto done;
batch->payload->send_initial_metadata.send_initial_metadata->Set(
grpc_core::HttpMethodMetadata(), method);
batch->payload->send_initial_metadata.send_initial_metadata->Set(
grpc_core::HttpSchemeMetadata(), channeld->static_scheme);
batch->payload->send_initial_metadata.send_initial_metadata->Set(
grpc_core::TeMetadata(), grpc_core::TeMetadata::kTrailers);
error = grpc_metadata_batch_add_tail(
batch->payload->send_initial_metadata.send_initial_metadata,
&calld->content_type, GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC,
GRPC_BATCH_CONTENT_TYPE);
if (error != GRPC_ERROR_NONE) goto done;
batch->payload->send_initial_metadata.send_initial_metadata->Set(
grpc_core::ContentTypeMetadata(),
grpc_core::ContentTypeMetadata::kApplicationGrpc);
batch->payload->send_initial_metadata.send_initial_metadata->Set(
grpc_core::UserAgentMetadata(), channeld->user_agent.Ref());
}
@ -485,25 +417,21 @@ static void http_client_destroy_call_elem(
calld->~call_data();
}
static grpc_mdelem scheme_from_args(const grpc_channel_args* args) {
unsigned i;
size_t j;
grpc_mdelem valid_schemes[] = {GRPC_MDELEM_SCHEME_HTTP,
GRPC_MDELEM_SCHEME_HTTPS};
static grpc_core::HttpSchemeMetadata::ValueType scheme_from_args(
const grpc_channel_args* args) {
if (args != nullptr) {
for (i = 0; i < args->num_args; ++i) {
for (size_t i = 0; i < args->num_args; ++i) {
if (args->args[i].type == GRPC_ARG_STRING &&
strcmp(args->args[i].key, GRPC_ARG_HTTP2_SCHEME) == 0) {
for (j = 0; j < GPR_ARRAY_SIZE(valid_schemes); j++) {
if (0 == grpc_slice_str_cmp(GRPC_MDVALUE(valid_schemes[j]),
args->args[i].value.string)) {
return valid_schemes[j];
}
}
0 == strcmp(args->args[i].key, GRPC_ARG_HTTP2_SCHEME)) {
grpc_core::HttpSchemeMetadata::ValueType scheme =
grpc_core::HttpSchemeMetadata::Parse(
args->args[i].value.string,
[](absl::string_view, const grpc_core::Slice&) {});
if (scheme != grpc_core::HttpSchemeMetadata::kInvalid) return scheme;
}
}
}
return GRPC_MDELEM_SCHEME_HTTP;
return grpc_core::HttpSchemeMetadata::kHttp;
}
static size_t max_payload_size_from_args(const grpc_channel_args* args) {

@ -41,34 +41,23 @@
namespace {
struct call_data {
grpc_linked_mdelem authority_storage;
grpc_core::CallCombiner* call_combiner;
};
struct channel_data {
grpc_core::ManagedMemorySlice default_authority;
grpc_mdelem default_authority_mdelem;
grpc_core::Slice default_authority;
};
void client_authority_start_transport_stream_op_batch(
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
// Handle send_initial_metadata.
// If the initial metadata doesn't already contain :authority, add it.
if (batch->send_initial_metadata &&
batch->payload->send_initial_metadata.send_initial_metadata
->legacy_index()
->named.authority == nullptr) {
grpc_error_handle error = grpc_metadata_batch_add_head(
batch->payload->send_initial_metadata.send_initial_metadata,
&calld->authority_storage,
GRPC_MDELEM_REF(chand->default_authority_mdelem), GRPC_BATCH_AUTHORITY);
if (error != GRPC_ERROR_NONE) {
grpc_transport_stream_op_batch_finish_with_failure(batch, error,
calld->call_combiner);
return;
}
batch->payload->send_initial_metadata.send_initial_metadata->get_pointer(
grpc_core::HttpAuthorityMetadata()) == nullptr) {
batch->payload->send_initial_metadata.send_initial_metadata->Set(
grpc_core::HttpAuthorityMetadata(), chand->default_authority.Ref());
}
// Pass control down the stack.
grpc_call_next_op(elem, batch);
@ -90,7 +79,7 @@ void client_authority_destroy_call_elem(
/* Constructor for channel_data */
grpc_error_handle client_authority_init_channel_elem(
grpc_channel_element* elem, grpc_channel_element_args* args) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
channel_data* chand = new (elem->channel_data) channel_data;
const grpc_arg* default_authority_arg =
grpc_channel_args_find(args->channel_args, GRPC_ARG_DEFAULT_AUTHORITY);
if (default_authority_arg == nullptr) {
@ -105,18 +94,14 @@ grpc_error_handle client_authority_init_channel_elem(
"GRPC_ARG_DEFAULT_AUTHORITY channel arg. must be a string");
}
chand->default_authority =
grpc_core::ManagedMemorySlice(default_authority_str);
chand->default_authority_mdelem = grpc_mdelem_create(
GRPC_MDSTR_AUTHORITY, chand->default_authority, nullptr);
grpc_core::Slice::FromCopiedString(default_authority_str);
GPR_ASSERT(!args->is_last);
return GRPC_ERROR_NONE;
}
/* Destructor for channel data */
void client_authority_destroy_channel_elem(grpc_channel_element* elem) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
grpc_slice_unref_internal(chand->default_authority);
GRPC_MDELEM_UNREF(chand->default_authority_mdelem);
static_cast<channel_data*>(elem->channel_data)->~channel_data();
}
} // namespace

@ -34,9 +34,6 @@
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/static_metadata.h"
#define EXPECTED_CONTENT_TYPE "application/grpc"
#define EXPECTED_CONTENT_TYPE_LENGTH (sizeof(EXPECTED_CONTENT_TYPE) - 1)
static void hs_recv_initial_metadata_ready(void* user_data,
grpc_error_handle err);
static void hs_recv_trailing_metadata_ready(void* user_data,
@ -67,10 +64,6 @@ struct call_data {
grpc_core::CallCombiner* call_combiner;
// Outgoing headers to add to send_initial_metadata.
grpc_linked_mdelem status;
grpc_linked_mdelem content_type;
// If we see the recv_message contents in the GET query string, we
// store it here.
grpc_core::ManualConstructor<grpc_core::SliceBufferByteStream> read_stream;
@ -121,63 +114,37 @@ static void hs_add_error(const char* error_name, grpc_error_handle* cumulative,
*cumulative = grpc_error_add_child(*cumulative, new_err);
}
// Metadata equality within this filter leverages the fact that the sender was
// likely using the gRPC chttp2 transport, in which case the encoder would emit
// indexed values, in which case the local hpack parser would intern the
// relevant metadata, allowing a simple pointer comparison.
//
// That said, if the header was transmitted sans indexing/encoding, we still
// need to do the right thing.
//
// Assumptions:
// 1) The keys for a and b_static must match
// 2) b_static must be a statically allocated metadata object.
// 3) It is assumed that the remote end is indexing, but not necessary.
// TODO(arjunroy): Revisit this method when grpc_mdelem is strongly typed.
static bool md_strict_equal(grpc_mdelem a, grpc_mdelem b_static) {
// Hpack encoder on the remote side should emit indexed values, in which case
// hpack parser on this end should pick up interned values, in which case the
// pointer comparison alone is enough.
//
if (GPR_LIKELY(GRPC_MDELEM_IS_INTERNED(a))) {
return a.payload == b_static.payload;
} else {
return grpc_slice_eq_static_interned(GRPC_MDVALUE(a),
GRPC_MDVALUE(b_static));
}
}
static grpc_error_handle hs_filter_incoming_metadata(grpc_call_element* elem,
grpc_metadata_batch* b) {
call_data* calld = static_cast<call_data*>(elem->call_data);
grpc_error_handle error = GRPC_ERROR_NONE;
static const char* error_name = "Failed processing incoming headers";
if (b->legacy_index()->named.method != nullptr) {
if (md_strict_equal(b->legacy_index()->named.method->md,
GRPC_MDELEM_METHOD_POST)) {
*calld->recv_initial_metadata_flags &=
~(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST |
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST);
} else if (md_strict_equal(b->legacy_index()->named.method->md,
GRPC_MDELEM_METHOD_PUT)) {
*calld->recv_initial_metadata_flags &=
~GRPC_INITIAL_METADATA_CACHEABLE_REQUEST;
*calld->recv_initial_metadata_flags |=
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
} else if (md_strict_equal(b->legacy_index()->named.method->md,
GRPC_MDELEM_METHOD_GET)) {
*calld->recv_initial_metadata_flags |=
GRPC_INITIAL_METADATA_CACHEABLE_REQUEST;
*calld->recv_initial_metadata_flags &=
~GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
} else {
hs_add_error(error_name, &error,
grpc_attach_md_to_error(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"),
b->legacy_index()->named.method->md));
auto method = b->Take(grpc_core::HttpMethodMetadata());
if (method.has_value()) {
switch (*method) {
case grpc_core::HttpMethodMetadata::kPost:
*calld->recv_initial_metadata_flags &=
~(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST |
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST);
break;
case grpc_core::HttpMethodMetadata::kPut:
*calld->recv_initial_metadata_flags &=
~GRPC_INITIAL_METADATA_CACHEABLE_REQUEST;
*calld->recv_initial_metadata_flags |=
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
break;
case grpc_core::HttpMethodMetadata::kGet:
*calld->recv_initial_metadata_flags |=
GRPC_INITIAL_METADATA_CACHEABLE_REQUEST;
*calld->recv_initial_metadata_flags &=
~GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
break;
case grpc_core::HttpMethodMetadata::kInvalid:
hs_add_error(error_name, &error,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad method header"));
break;
}
b->Remove(GRPC_BATCH_METHOD);
} else {
hs_add_error(error_name, &error,
grpc_error_set_str(
@ -198,19 +165,12 @@ static grpc_error_handle hs_filter_incoming_metadata(grpc_call_element* elem,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad te header"));
}
if (b->legacy_index()->named.scheme != nullptr) {
if (!md_strict_equal(b->legacy_index()->named.scheme->md,
GRPC_MDELEM_SCHEME_HTTP) &&
!md_strict_equal(b->legacy_index()->named.scheme->md,
GRPC_MDELEM_SCHEME_HTTPS) &&
!grpc_mdelem_static_value_eq(b->legacy_index()->named.scheme->md,
GRPC_MDELEM_SCHEME_GRPC)) {
auto scheme = b->Take(grpc_core::HttpSchemeMetadata());
if (scheme.has_value()) {
if (*scheme == grpc_core::HttpSchemeMetadata::kInvalid) {
hs_add_error(error_name, &error,
grpc_attach_md_to_error(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"),
b->legacy_index()->named.scheme->md));
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad :scheme header"));
}
b->Remove(GRPC_BATCH_SCHEME);
} else {
hs_add_error(error_name, &error,
grpc_error_set_str(
@ -218,40 +178,10 @@ static grpc_error_handle hs_filter_incoming_metadata(grpc_call_element* elem,
GRPC_ERROR_STR_KEY, ":scheme"));
}
if (b->legacy_index()->named.content_type != nullptr) {
if (!grpc_mdelem_static_value_eq(
b->legacy_index()->named.content_type->md,
GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) {
if (grpc_slice_buf_start_eq(
GRPC_MDVALUE(b->legacy_index()->named.content_type->md),
EXPECTED_CONTENT_TYPE, EXPECTED_CONTENT_TYPE_LENGTH) &&
(GRPC_SLICE_START_PTR(GRPC_MDVALUE(
b->legacy_index()
->named.content_type->md))[EXPECTED_CONTENT_TYPE_LENGTH] ==
'+' ||
GRPC_SLICE_START_PTR(GRPC_MDVALUE(
b->legacy_index()
->named.content_type->md))[EXPECTED_CONTENT_TYPE_LENGTH] ==
';')) {
/* Although the C implementation doesn't (currently) generate them,
any custom +-suffix is explicitly valid. */
/* TODO(klempner): We should consider preallocating common values such
as +proto or +json, or at least stashing them if we see them. */
/* TODO(klempner): Should we be surfacing this to application code? */
} else {
/* TODO(klempner): We're currently allowing this, but we shouldn't
see it without a proxy so log for now. */
char* val = grpc_dump_slice(
GRPC_MDVALUE(b->legacy_index()->named.content_type->md),
GPR_DUMP_ASCII);
gpr_log(GPR_INFO, "Unexpected content-type '%s'", val);
gpr_free(val);
}
}
b->Remove(GRPC_BATCH_CONTENT_TYPE);
}
b->Remove(grpc_core::ContentTypeMetadata());
if (b->legacy_index()->named.path == nullptr) {
grpc_core::Slice* path_slice = b->get_pointer(grpc_core::HttpPathMetadata());
if (path_slice == nullptr) {
hs_add_error(error_name, &error,
grpc_error_set_str(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
@ -260,25 +190,18 @@ static grpc_error_handle hs_filter_incoming_metadata(grpc_call_element* elem,
GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) {
/* We have a cacheable request made with GET verb. The path contains the
* query parameter which is base64 encoded request payload. */
const char k_query_separator = '?';
grpc_slice path_slice = GRPC_MDVALUE(b->legacy_index()->named.path->md);
uint8_t* path_ptr = GRPC_SLICE_START_PTR(path_slice);
size_t path_length = GRPC_SLICE_LENGTH(path_slice);
static const char kQuerySeparator = '?';
/* offset of the character '?' */
size_t offset = 0;
for (offset = 0; offset < path_length && *path_ptr != k_query_separator;
path_ptr++, offset++) {
}
if (offset < path_length) {
grpc_slice query_slice =
grpc_slice_sub(path_slice, offset + 1, path_length);
auto it =
std::find(path_slice->begin(), path_slice->end(), kQuerySeparator);
if (it != path_slice->end()) {
const auto query_start = it - path_slice->begin() + 1;
auto query_slice = path_slice->RefSubSlice(
query_start, path_slice->size() - query_start);
/* substitute path metadata with just the path (not query) */
grpc_mdelem mdelem_path_without_query = grpc_mdelem_from_slices(
GRPC_MDSTR_PATH, grpc_slice_sub(path_slice, 0, offset));
(void)b->Substitute(b->legacy_index()->named.path,
mdelem_path_without_query);
auto path_without_query = path_slice->TakeSubSlice(0, query_start - 1);
*path_slice = std::move(path_without_query);
/* decode payload from query and add to the slice buffer to be returned */
const int k_url_safe = 1;
@ -287,25 +210,24 @@ static grpc_error_handle hs_filter_incoming_metadata(grpc_call_element* elem,
grpc_slice_buffer_add(
&read_slice_buffer,
grpc_base64_decode_with_len(
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(query_slice),
GRPC_SLICE_LENGTH(query_slice), k_url_safe));
reinterpret_cast<const char*>(query_slice.begin()),
query_slice.size(), k_url_safe));
calld->read_stream.Init(&read_slice_buffer, 0);
grpc_slice_buffer_destroy_internal(&read_slice_buffer);
calld->have_read_stream = true;
grpc_slice_unref_internal(query_slice);
} else {
gpr_log(GPR_ERROR, "GET request without QUERY");
}
}
if (b->legacy_index()->named.authority == nullptr) {
if (b->get_pointer(grpc_core::HttpAuthorityMetadata()) == nullptr) {
absl::optional<grpc_core::Slice> host = b->Take(grpc_core::HostMetadata());
if (host.has_value()) {
b->Append(":authority", std::move(*host));
b->Set(grpc_core::HttpAuthorityMetadata(), std::move(*host));
}
}
if (b->legacy_index()->named.authority == nullptr) {
if (b->get_pointer(grpc_core::HttpAuthorityMetadata()) == nullptr) {
hs_add_error(error_name, &error,
grpc_error_set_str(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
@ -410,17 +332,11 @@ static grpc_error_handle hs_mutate_op(grpc_call_element* elem,
if (op->send_initial_metadata) {
grpc_error_handle error = GRPC_ERROR_NONE;
static const char* error_name = "Failed sending initial metadata";
hs_add_error(
error_name, &error,
grpc_metadata_batch_add_head(
op->payload->send_initial_metadata.send_initial_metadata,
&calld->status, GRPC_MDELEM_STATUS_200, GRPC_BATCH_STATUS));
hs_add_error(error_name, &error,
grpc_metadata_batch_add_tail(
op->payload->send_initial_metadata.send_initial_metadata,
&calld->content_type,
GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC,
GRPC_BATCH_CONTENT_TYPE));
op->payload->send_initial_metadata.send_initial_metadata->Set(
grpc_core::HttpStatusMetadata(), 200);
op->payload->send_initial_metadata.send_initial_metadata->Set(
grpc_core::ContentTypeMetadata(),
grpc_core::ContentTypeMetadata::kApplicationGrpc);
hs_add_error(error_name, &error,
hs_filter_outgoing_metadata(
op->payload->send_initial_metadata.send_initial_metadata));

@ -24,6 +24,7 @@
#include <string>
#include "absl/strings/ascii.h"
#include "absl/strings/str_format.h"
#include <grpc/grpc_security.h>
@ -93,14 +94,13 @@ void ServerLoadReportingCallData::Destroy(
{{::grpc::load_reporter::TagKeyToken(),
{client_ip_and_lr_token_, client_ip_and_lr_token_len_}},
{::grpc::load_reporter::TagKeyHost(),
{target_host_, target_host_len_}},
{target_host_.data(), target_host_.length()}},
{::grpc::load_reporter::TagKeyUserId(),
{chand->peer_identity(), chand->peer_identity_len()}},
{::grpc::load_reporter::TagKeyStatus(),
GetStatusTagForStatus(final_info->final_status)}});
gpr_free(client_ip_and_lr_token_);
}
gpr_free(target_host_);
grpc_slice_unref_internal(service_method_);
}
@ -205,35 +205,6 @@ void ServerLoadReportingCallData::StoreClientIpAndLrToken(const char* lr_token,
client_ip_and_lr_token_len_);
}
grpc_filtered_mdelem ServerLoadReportingCallData::RecvInitialMetadataFilter(
void* user_data, grpc_mdelem md) {
grpc_call_element* elem = reinterpret_cast<grpc_call_element*>(user_data);
ServerLoadReportingCallData* calld =
reinterpret_cast<ServerLoadReportingCallData*>(elem->call_data);
if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_PATH)) {
calld->service_method_ = grpc_slice_ref_internal(GRPC_MDVALUE(md));
} else if (calld->target_host_ == nullptr &&
grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_AUTHORITY)) {
grpc_slice target_host_slice = GRPC_MDVALUE(md);
calld->target_host_len_ = GRPC_SLICE_LENGTH(target_host_slice);
calld->target_host_ =
reinterpret_cast<char*>(gpr_zalloc(calld->target_host_len_));
for (size_t i = 0; i < calld->target_host_len_; ++i) {
calld->target_host_[i] = static_cast<char>(
tolower(GRPC_SLICE_START_PTR(target_host_slice)[i]));
}
} else if (grpc_slice_str_cmp(GRPC_MDKEY(md),
grpc_core::kGrpcLbLbTokenMetadataKey) == 0) {
if (calld->client_ip_and_lr_token_ == nullptr) {
calld->StoreClientIpAndLrToken(
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(GRPC_MDVALUE(md)),
GRPC_SLICE_LENGTH(GRPC_MDVALUE(md)));
}
return GRPC_FILTERED_REMOVE();
}
return GRPC_FILTERED_MDELEM(md);
}
void ServerLoadReportingCallData::RecvInitialMetadataReady(
void* arg, grpc_error_handle err) {
grpc_call_element* elem = reinterpret_cast<grpc_call_element*>(arg);
@ -242,11 +213,29 @@ void ServerLoadReportingCallData::RecvInitialMetadataReady(
ServerLoadReportingChannelData* chand =
reinterpret_cast<ServerLoadReportingChannelData*>(elem->channel_data);
if (err == GRPC_ERROR_NONE) {
GRPC_LOG_IF_ERROR(
"server_load_reporting_filter",
grpc_metadata_batch_filter(calld->recv_initial_metadata_,
RecvInitialMetadataFilter, elem,
"recv_initial_metadata filtering error"));
if (const grpc_core::Slice* path =
calld->recv_initial_metadata_->get_pointer(
grpc_core::HttpPathMetadata())) {
calld->service_method_ = path->Ref().TakeCSlice();
}
if (const grpc_core::Slice* authority =
calld->recv_initial_metadata_->get_pointer(
grpc_core::HttpAuthorityMetadata())) {
calld->target_host_ = absl::AsciiStrToLower(authority->as_string_view());
}
std::string buffer;
auto lb_token = calld->recv_initial_metadata_->GetValue(
grpc_core::kGrpcLbLbTokenMetadataKey, &buffer);
if (lb_token.has_value()) {
if (calld->client_ip_and_lr_token_ == nullptr) {
calld->StoreClientIpAndLrToken(lb_token->data(), lb_token->size());
}
auto old = calld->recv_initial_metadata_->Remove(
grpc_core::Slice::FromCopiedString(
grpc_core::kGrpcLbLbTokenMetadataKey)
.c_slice());
if (old.has_value()) grpc_slice_unref_internal(*old);
}
// If the LB token was not found in the recv_initial_metadata, only the
// client IP part will be recorded (with an empty LB token).
if (calld->client_ip_and_lr_token_ == nullptr) {
@ -257,7 +246,7 @@ void ServerLoadReportingCallData::RecvInitialMetadataReady(
{{::grpc::load_reporter::TagKeyToken(),
{calld->client_ip_and_lr_token_, calld->client_ip_and_lr_token_len_}},
{::grpc::load_reporter::TagKeyHost(),
{calld->target_host_, calld->target_host_len_}},
{calld->target_host_.data(), calld->target_host_.length()}},
{::grpc::load_reporter::TagKeyUserId(),
{chand->peer_identity(), chand->peer_identity_len()}}});
}
@ -303,7 +292,7 @@ grpc_filtered_mdelem ServerLoadReportingCallData::SendTrailingMetadataFilter(
{{::grpc::load_reporter::TagKeyToken(),
{calld->client_ip_and_lr_token_, calld->client_ip_and_lr_token_len_}},
{::grpc::load_reporter::TagKeyHost(),
{calld->target_host_, calld->target_host_len_}},
{calld->target_host_.data(), calld->target_host_.length()}},
{::grpc::load_reporter::TagKeyUserId(),
{chand->peer_identity(), chand->peer_identity_len()}},
{::grpc::load_reporter::TagKeyMetricName(),

@ -106,8 +106,7 @@ class ServerLoadReportingCallData : public CallData {
// different from the actual backend in the case of, for example,
// load-balanced targets. We store a copy of the metadata slice in order to
// lowercase it. */
char* target_host_;
size_t target_host_len_;
std::string target_host_;
// The client IP address (including a length prefix) and the load reporting
// token.

@ -123,7 +123,13 @@ static void AssignMetadata(grpc_metadata_batch* mb,
const grpc_binder::Metadata& md) {
mb->Clear();
for (auto& p : md) {
mb->Append(p.first, grpc_core::Slice::FromCopiedString(p.second));
mb->Append(p.first, grpc_core::Slice::FromCopiedString(p.second),
[&](absl::string_view error, const grpc_core::Slice& value) {
gpr_log(GPR_DEBUG, "Failed to parse metadata: %s",
absl::StrCat("key=", p.first, " error=", error,
" value=", value.as_string_view())
.c_str());
});
}
}
@ -326,18 +332,18 @@ class MetadataEncoder {
absl::string_view value = grpc_core::StringViewFromSlice(GRPC_MDVALUE(md));
gpr_log(GPR_INFO, "send metadata key-value %s",
absl::StrCat(key, " ", value).c_str());
if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_PATH)) {
// TODO(b/192208403): Figure out if it is correct to simply drop '/'
// prefix and treat it as rpc method name
GPR_ASSERT(value[0] == '/');
std::string path = std::string(value).substr(1);
// Only client send method ref.
GPR_ASSERT(is_client_);
tx_->SetMethodRef(path);
} else {
init_md_->emplace_back(std::string(key), std::string(value));
}
init_md_->emplace_back(std::string(key), std::string(value));
}
void Encode(grpc_core::HttpPathMetadata, const grpc_core::Slice& value) {
// TODO(b/192208403): Figure out if it is correct to simply drop '/'
// prefix and treat it as rpc method name
GPR_ASSERT(value[0] == '/');
std::string path = std::string(value.as_string_view().substr(1));
// Only client send method ref.
GPR_ASSERT(is_client_);
tx_->SetMethodRef(path);
}
void Encode(grpc_core::GrpcStatusMetadata, grpc_status_code status) {

@ -23,6 +23,8 @@
#include <assert.h>
#include <string.h>
#include "hpack_constants.h"
/* This is here for grpc_is_binary_header
* TODO(murgatroid99): Remove this
*/
@ -395,6 +397,30 @@ void HPackCompressor::Framer::EmitLitHdrWithBinaryStringKeyNotIdx(
Add(emit.data());
}
void HPackCompressor::Framer::EmitLitHdrWithBinaryStringKeyIncIdx(
const grpc_slice& key_slice, const grpc_slice& value_slice) {
GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX_V();
GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED();
StringKey key(key_slice);
key.WritePrefix(0x40, AddTiny(key.prefix_length()));
Add(grpc_slice_ref_internal(key.key()));
BinaryStringValue emit(value_slice, use_true_binary_metadata_);
emit.WritePrefix(AddTiny(emit.prefix_length()));
Add(emit.data());
}
void HPackCompressor::Framer::EmitLitHdrWithBinaryStringKeyNotIdx(
uint32_t key_index, const grpc_slice& value_slice) {
GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX();
GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED();
BinaryStringValue emit(value_slice, use_true_binary_metadata_);
VarintWriter<4> key(key_index);
uint8_t* data = AddTiny(key.length() + emit.prefix_length());
key.Write(0x00, data);
emit.WritePrefix(data + key.length());
Add(emit.data());
}
void HPackCompressor::Framer::EmitLitHdrWithNonBinaryStringKeyNotIdx(
const grpc_slice& key_slice, const grpc_slice& value_slice) {
GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX_V();
@ -525,6 +551,54 @@ void HPackCompressor::Framer::EncodeDynamic(grpc_mdelem elem) {
}
}
void HPackCompressor::SliceIndex::EmitTo(const grpc_slice& key,
const Slice& value, Framer* framer) {
auto& table = framer->compressor_->table_;
using It = std::vector<ValueIndex>::iterator;
It prev = values_.end();
uint32_t transport_length =
GRPC_SLICE_LENGTH(key) + value.length() + hpack_constants::kEntryOverhead;
// Linear scan through previous values to see if we find the value.
for (It it = values_.begin(); it != values_.end(); ++it) {
if (value == it->value) {
// Got a hit... is it still in the decode table?
if (table.ConvertableToDynamicIndex(it->index)) {
// Yes, emit the index and proceed to cleanup.
framer->EmitIndexed(table.DynamicIndex(it->index));
} else {
// Not current, emit a new literal and update the index.
it->index = table.AllocateIndex(transport_length);
framer->EmitLitHdrWithNonBinaryStringKeyIncIdx(key, value.c_slice());
}
// Bubble this entry up if we can - ensures that the most used values end
// up towards the start of the array.
if (prev != values_.end()) std::swap(*prev, *it);
// If there are entries at the end of the array, and those entries are no
// longer in the table, remove them.
while (!values_.empty() &&
!table.ConvertableToDynamicIndex(values_.back().index)) {
values_.pop_back();
}
// All done, early out.
return;
}
prev = it;
}
// No hit, emit a new literal and add it to the index.
uint32_t index = table.AllocateIndex(transport_length);
framer->EmitLitHdrWithNonBinaryStringKeyIncIdx(key, value.c_slice());
values_.emplace_back(value.Ref(), index);
}
void HPackCompressor::Framer::Encode(HttpPathMetadata, const Slice& value) {
compressor_->path_index_.EmitTo(GRPC_MDSTR_PATH, value, this);
}
void HPackCompressor::Framer::Encode(HttpAuthorityMetadata,
const Slice& value) {
compressor_->authority_index_.EmitTo(GRPC_MDSTR_AUTHORITY, value, this);
}
void HPackCompressor::Framer::Encode(TeMetadata, TeMetadata::ValueType value) {
GPR_ASSERT(value == TeMetadata::ValueType::kTrailers);
EncodeAlwaysIndexed(
@ -532,6 +606,97 @@ void HPackCompressor::Framer::Encode(TeMetadata, TeMetadata::ValueType value) {
2 /* te */ + 8 /* trailers */ + hpack_constants::kEntryOverhead);
}
void HPackCompressor::Framer::Encode(ContentTypeMetadata,
ContentTypeMetadata::ValueType value) {
GPR_ASSERT(value == ContentTypeMetadata::ValueType::kApplicationGrpc);
EncodeAlwaysIndexed(
&compressor_->content_type_index_, GRPC_MDSTR_CONTENT_TYPE,
StaticSlice::FromStaticString("application/grpc").c_slice(),
12 /* content-type */ + 16 /* application/grpc */ +
hpack_constants::kEntryOverhead);
}
void HPackCompressor::Framer::Encode(HttpSchemeMetadata,
HttpSchemeMetadata::ValueType value) {
switch (value) {
case HttpSchemeMetadata::ValueType::kHttp:
EmitIndexed(6); // :scheme: http
break;
case HttpSchemeMetadata::ValueType::kHttps:
EmitIndexed(7); // :scheme: https
break;
case HttpSchemeMetadata::ValueType::kInvalid:
GPR_ASSERT(false);
break;
}
}
void HPackCompressor::Framer::Encode(GrpcTraceBinMetadata, const Slice& slice) {
EncodeIndexedKeyWithBinaryValue(&compressor_->grpc_trace_bin_index_,
"grpc-trace-bin", slice.c_slice());
}
void HPackCompressor::Framer::Encode(GrpcTagsBinMetadata, const Slice& slice) {
EncodeIndexedKeyWithBinaryValue(&compressor_->grpc_tags_bin_index_,
"grpc-tags-bin", slice.c_slice());
}
void HPackCompressor::Framer::Encode(HttpStatusMetadata, uint32_t status) {
if (status == 200) {
EmitIndexed(8); // :status: 200
return;
}
uint8_t index = 0;
switch (status) {
case 204:
index = 9; // :status: 204
break;
case 206:
index = 10; // :status: 206
break;
case 304:
index = 11; // :status: 304
break;
case 400:
index = 12; // :status: 400
break;
case 404:
index = 13; // :status: 404
break;
case 500:
index = 14; // :status: 500
break;
}
if (GPR_LIKELY(index != 0)) {
EmitIndexed(index);
} else {
char buffer[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(status, buffer);
EmitLitHdrWithNonBinaryStringKeyIncIdx(
GRPC_MDSTR_STATUS, Slice::FromCopiedString(buffer).c_slice());
}
}
void HPackCompressor::Framer::Encode(HttpMethodMetadata,
HttpMethodMetadata::ValueType method) {
switch (method) {
case HttpMethodMetadata::ValueType::kGet:
EmitIndexed(2); // :method: GET
break;
case HttpMethodMetadata::ValueType::kPost:
EmitIndexed(3); // :method: POST
break;
case HttpMethodMetadata::ValueType::kPut:
EmitLitHdrWithNonBinaryStringKeyNotIdx(
StaticSlice::FromStaticString(":method").c_slice(),
StaticSlice::FromStaticString("PUT").c_slice());
break;
case HttpMethodMetadata::ValueType::kInvalid:
GPR_ASSERT(false);
break;
}
}
void HPackCompressor::Framer::EncodeAlwaysIndexed(uint32_t* index,
const grpc_slice& key,
const grpc_slice& value,
@ -544,6 +709,20 @@ void HPackCompressor::Framer::EncodeAlwaysIndexed(uint32_t* index,
}
}
void HPackCompressor::Framer::EncodeIndexedKeyWithBinaryValue(
uint32_t* index, absl::string_view key, const grpc_slice& value) {
if (compressor_->table_.ConvertableToDynamicIndex(*index)) {
EmitLitHdrWithBinaryStringKeyNotIdx(
compressor_->table_.DynamicIndex(*index), value);
} else {
*index = compressor_->table_.AllocateIndex(key.length() +
GRPC_SLICE_LENGTH(value) +
hpack_constants::kEntryOverhead);
EmitLitHdrWithBinaryStringKeyIncIdx(
StaticSlice::FromStaticString(key).c_slice(), value);
}
}
void HPackCompressor::Framer::Encode(GrpcTimeoutMetadata,
grpc_millis deadline) {
char timeout_str[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE];

@ -21,6 +21,8 @@
#include <grpc/support/port_platform.h>
#include <cstdint>
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
@ -36,48 +38,9 @@ extern grpc_core::TraceFlag grpc_http_trace;
namespace grpc_core {
// Wrapper to take an array of mdelems and make them encodable
class MetadataArray {
public:
MetadataArray(grpc_mdelem** elems, size_t count)
: elems_(elems), count_(count) {}
template <typename Encoder>
void Encode(Encoder* encoder) const {
for (size_t i = 0; i < count_; i++) {
encoder->Encode(*elems_[i]);
}
}
private:
grpc_mdelem** elems_;
size_t count_;
};
namespace metadata_detail {
template <typename A, typename B>
class ConcatMetadata {
public:
ConcatMetadata(const A& a, const B& b) : a_(a), b_(b) {}
template <typename Encoder>
void Encode(Encoder* encoder) const {
a_.Encode(encoder);
b_.Encode(encoder);
}
private:
const A& a_;
const B& b_;
};
} // namespace metadata_detail
template <typename A, typename B>
metadata_detail::ConcatMetadata<A, B> ConcatMetadata(const A& a, const B& b) {
return metadata_detail::ConcatMetadata<A, B>(a, b);
}
class HPackCompressor {
class SliceIndex;
public:
HPackCompressor() = default;
~HPackCompressor() = default;
@ -117,10 +80,18 @@ class HPackCompressor {
Framer& operator=(const Framer&) = delete;
void Encode(grpc_mdelem md);
void Encode(HttpPathMetadata, const Slice& value);
void Encode(HttpAuthorityMetadata, const Slice& value);
void Encode(HttpStatusMetadata, uint32_t status);
void Encode(GrpcTimeoutMetadata, grpc_millis deadline);
void Encode(TeMetadata, TeMetadata::ValueType value);
void Encode(ContentTypeMetadata, ContentTypeMetadata::ValueType value);
void Encode(HttpSchemeMetadata, HttpSchemeMetadata::ValueType value);
void Encode(HttpMethodMetadata, HttpMethodMetadata::ValueType method);
void Encode(UserAgentMetadata, const Slice& slice);
void Encode(GrpcStatusMetadata, grpc_status_code status);
void Encode(GrpcTagsBinMetadata, const Slice& slice);
void Encode(GrpcTraceBinMetadata, const Slice& slice);
void Encode(GrpcMessageMetadata, const Slice& slice) {
if (slice.empty()) return;
EmitLitHdrWithNonBinaryStringKeyNotIdx(
@ -142,6 +113,8 @@ class HPackCompressor {
}
private:
friend class SliceIndex;
struct FramePrefix {
// index (in output_) of the header for the frame
size_t header_idx;
@ -164,8 +137,12 @@ class HPackCompressor {
void EmitLitHdrWithStringKeyIncIdx(grpc_mdelem elem);
void EmitLitHdrWithNonBinaryStringKeyIncIdx(const grpc_slice& key_slice,
const grpc_slice& value_slice);
void EmitLitHdrWithBinaryStringKeyIncIdx(const grpc_slice& key_slice,
const grpc_slice& value_slice);
void EmitLitHdrWithBinaryStringKeyNotIdx(const grpc_slice& key_slice,
const grpc_slice& value_slice);
void EmitLitHdrWithBinaryStringKeyNotIdx(uint32_t key_index,
const grpc_slice& value_slice);
void EmitLitHdrWithNonBinaryStringKeyNotIdx(const grpc_slice& key_slice,
const grpc_slice& value_slice);
void EmitLitHdrWithStringKeyNotIdx(grpc_mdelem elem);
@ -173,6 +150,8 @@ class HPackCompressor {
void EncodeAlwaysIndexed(uint32_t* index, const grpc_slice& key,
const grpc_slice& value,
uint32_t transport_length);
void EncodeIndexedKeyWithBinaryValue(uint32_t* index, absl::string_view key,
const grpc_slice& value);
size_t CurrentFrameSize() const;
void Add(grpc_slice slice);
@ -295,18 +274,40 @@ class HPackCompressor {
uint32_t hash_;
};
class SliceIndex {
public:
void EmitTo(const grpc_slice& key, const Slice& value, Framer* framer);
private:
struct ValueIndex {
ValueIndex(Slice value, uint32_t index)
: value(std::move(value)), index(index) {}
Slice value;
uint32_t index;
};
std::vector<ValueIndex> values_;
};
// entry tables for keys & elems: these tables track values that have been
// seen and *may* be in the decompressor table
HPackEncoderIndex<KeyElem, kNumFilterValues> elem_index_;
HPackEncoderIndex<KeySliceRef, kNumFilterValues> key_index_;
// Index into table_ for the te:trailers metadata element
uint32_t te_index_ = 0;
// Index into table_ for the content-type metadata element
uint32_t content_type_index_ = 0;
// Index into table_ for the user-agent metadata element
uint32_t user_agent_index_ = 0;
// Cached grpc-status values
uint32_t cached_grpc_status_[kNumCachedGrpcStatusValues] = {};
// Index of something that was sent with grpc-tags-bin
uint32_t grpc_tags_bin_index_ = 0;
// Index of something that was sent with grpc-trace-bin
uint32_t grpc_trace_bin_index_ = 0;
// The user-agent string referred to by user_agent_index_
Slice user_agent_;
SliceIndex path_index_;
SliceIndex authority_index_;
};
} // namespace grpc_core

@ -1129,8 +1129,11 @@ class HPackParser::Parser {
auto value_slice = value->Take<TakeValueType>();
const auto transport_size = key_string.size() + value_slice.size() +
hpack_constants::kEntryOverhead;
return grpc_metadata_batch::Parse(key->string_view(),
std::move(value_slice), transport_size);
return grpc_metadata_batch::Parse(
key->string_view(), std::move(value_slice), transport_size,
[key_string](absl::string_view error, const Slice& value) {
ReportMetadataParseError(key_string, error, value.as_string_view());
});
}
// Parse an index encoded key and a string encoded value
@ -1143,7 +1146,11 @@ class HPackParser::Parser {
}
auto value = ParseValueString(elem->is_binary_header());
if (GPR_UNLIKELY(!value.has_value())) return {};
return elem->WithNewValue(value->Take<TakeValueType>());
return elem->WithNewValue(value->Take<TakeValueType>(),
[=](absl::string_view error, const Slice& value) {
ReportMetadataParseError(
elem->key(), error, value.as_string_view());
});
}
// Parse a varint index encoded key and a string encoded value
@ -1230,6 +1237,14 @@ class HPackParser::Parser {
false);
}
static void ReportMetadataParseError(absl::string_view key,
absl::string_view error,
absl::string_view value) {
gpr_log(
GPR_ERROR, "Error parsing metadata: %s",
absl::StrCat("error=", error, " key=", key, " value=", value).c_str());
}
Input* const input_;
grpc_metadata_batch* const metadata_buffer_;
HPackTable* const table_;

@ -71,7 +71,13 @@ class HPackTable {
struct StaticMementos {
StaticMementos() {
for (uint32_t i = 0; i < hpack_constants::kLastStaticEntry; i++) {
memento[i] = Memento(g_static_mdelem_manifested[i]);
const grpc_mdelem_data& sm = g_static_mdelem_table[i].data();
memento[i] = grpc_metadata_batch::Parse(
StringViewFromSlice(sm.key),
Slice(grpc_slice_ref_internal(sm.value)),
GRPC_SLICE_LENGTH(sm.key) + GRPC_SLICE_LENGTH(sm.value) +
hpack_constants::kEntryOverhead,
[](absl::string_view, const Slice&) {});
}
}
Memento memento[hpack_constants::kLastStaticEntry];

@ -570,6 +570,14 @@ class StreamWriteContext {
grpc_chttp2_encode_data(s_->id, &s_->flow_controlled_buffer, 0, true,
&s_->stats.outgoing, &t_->outbuf);
} else {
if (send_status_.has_value()) {
s_->send_trailing_metadata->Set(grpc_core::HttpStatusMetadata(),
*send_status_);
}
if (send_content_type_.has_value()) {
s_->send_trailing_metadata->Set(grpc_core::ContentTypeMetadata(),
*send_content_type_);
}
t_->hpack_compressor.EncodeHeaders(
grpc_core::HPackCompressor::EncodeHeaderOptions{
s_->id, true,
@ -580,12 +588,7 @@ class StreamWriteContext {
t_->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
&s_->stats.outgoing},
grpc_core::ConcatMetadata(
grpc_core::MetadataArray(
extra_headers_for_trailing_metadata_,
num_extra_headers_for_trailing_metadata_),
*s_->send_trailing_metadata),
&t_->outbuf);
*s_->send_trailing_metadata, &t_->outbuf);
}
write_context_->IncTrailingMetadataWrites();
grpc_chttp2_reset_ping_clock(t_);
@ -605,18 +608,10 @@ class StreamWriteContext {
gpr_log(GPR_INFO, "not sending initial_metadata (Trailers-Only)"));
// When sending Trailers-Only, we need to move the :status and
// content-type headers to the trailers.
if (s_->send_initial_metadata->legacy_index()->named.status != nullptr) {
extra_headers_for_trailing_metadata_
[num_extra_headers_for_trailing_metadata_++] =
&s_->send_initial_metadata->legacy_index()->named.status->md;
}
if (s_->send_initial_metadata->legacy_index()->named.content_type !=
nullptr) {
extra_headers_for_trailing_metadata_
[num_extra_headers_for_trailing_metadata_++] =
&s_->send_initial_metadata->legacy_index()
->named.content_type->md;
}
send_status_ =
s_->send_initial_metadata->get(grpc_core::HttpStatusMetadata());
send_content_type_ =
s_->send_initial_metadata->get(grpc_core::ContentTypeMetadata());
}
void SentLastFrame() {
@ -641,8 +636,9 @@ class StreamWriteContext {
grpc_chttp2_transport* const t_;
grpc_chttp2_stream* const s_;
bool stream_became_writable_ = false;
grpc_mdelem* extra_headers_for_trailing_metadata_[2];
size_t num_extra_headers_for_trailing_metadata_ = 0;
absl::optional<uint32_t> send_status_;
absl::optional<grpc_core::ContentTypeMetadata::ValueType> send_content_type_ =
{};
};
} // namespace

@ -417,7 +417,14 @@ static void convert_cronet_array_to_metadata(
value = grpc_slice_intern(
grpc_slice_from_static_string(header_array->headers[i].value));
}
mds->Append(header_array->headers[i].key, grpc_core::Slice(value));
mds->Append(header_array->headers[i].key, grpc_core::Slice(value),
[&](absl::string_view error, const grpc_core::Slice& value) {
gpr_log(GPR_DEBUG, "Failed to parse metadata: %s",
absl::StrCat("key=", header_array->headers[i].key,
" error=", error,
" value=", value.as_string_view())
.c_str());
});
}
}
@ -723,6 +730,38 @@ class CronetMetadataEncoder {
GRPC_MDELEM_UNREF(mdelem);
}
void Encode(grpc_core::HttpSchemeMetadata,
grpc_core::HttpSchemeMetadata::ValueType) {
/* Cronet populates these fields on its own */
}
void Encode(grpc_core::HttpAuthorityMetadata,
const grpc_core::HttpAuthorityMetadata::ValueType&) {
/* Cronet populates these fields on its own */
}
void Encode(grpc_core::HttpMethodMetadata,
grpc_core::HttpMethodMetadata::ValueType method) {
switch (method) {
case grpc_core::HttpMethodMetadata::kPost:
*method_ = "POST";
break;
case grpc_core::HttpMethodMetadata::kPut:
*method_ = "PUT";
break;
case grpc_core::HttpMethodMetadata::kGet:
*method_ = "GET";
break;
case grpc_core::HttpMethodMetadata::kInvalid:
abort();
}
}
void Encode(grpc_core::HttpPathMetadata,
const grpc_core::HttpPathMetadata::ValueType& path) {
/* Create URL by appending :path value to the hostname */
*url_ = absl::StrCat("https://", host_, path.as_string_view());
}
void Encode(grpc_mdelem mdelem) {
char* key = grpc_slice_to_c_string(GRPC_MDKEY(mdelem));
char* value;
@ -733,32 +772,6 @@ class CronetMetadataEncoder {
} else {
value = grpc_slice_to_c_string(GRPC_MDVALUE(mdelem));
}
if (grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), GRPC_MDSTR_SCHEME) ||
grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem),
GRPC_MDSTR_AUTHORITY)) {
/* Cronet populates these fields on its own */
gpr_free(key);
gpr_free(value);
return;
}
if (grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), GRPC_MDSTR_METHOD)) {
if (grpc_slice_eq_static_interned(GRPC_MDVALUE(mdelem), GRPC_MDSTR_PUT)) {
*method_ = "PUT";
} else {
/* POST method in default*/
*method_ = "POST";
}
gpr_free(key);
gpr_free(value);
return;
}
if (grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), GRPC_MDSTR_PATH)) {
/* Create URL by appending :path value to the hostname */
*url_ = absl::StrCat("https://", host_, value);
gpr_free(key);
gpr_free(value);
return;
}
CRONET_LOG(GPR_DEBUG, "header %s = %s", key, value);
GPR_ASSERT(count_ < capacity_);
headers_[count_].key = key;
@ -801,13 +814,7 @@ static void parse_grpc_header(const uint8_t* data, int* length,
}
static bool header_has_authority(const grpc_metadata_batch* b) {
bool found = false;
b->ForEach([&](grpc_mdelem elem) {
if (grpc_slice_eq_static_interned(GRPC_MDKEY(elem), GRPC_MDSTR_AUTHORITY)) {
found = true;
}
});
return found;
return b->get_pointer(grpc_core::HttpAuthorityMetadata()) != nullptr;
}
/*

@ -1097,19 +1097,19 @@ ServerConfigSelector::CallConfig XdsServerConfigFetcher::ListenerWatcher::
FilterChainMatchManager::XdsServerConfigSelector::GetCallConfig(
grpc_metadata_batch* metadata) {
CallConfig call_config;
if (metadata->legacy_index()->named.path == nullptr) {
if (metadata->get_pointer(HttpPathMetadata()) == nullptr) {
call_config.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("No path found");
return call_config;
}
absl::string_view path = StringViewFromSlice(
GRPC_MDVALUE(metadata->legacy_index()->named.path->md));
if (metadata->legacy_index()->named.authority == nullptr) {
absl::string_view path =
metadata->get_pointer(HttpPathMetadata())->as_string_view();
if (metadata->get_pointer(HttpAuthorityMetadata()) == nullptr) {
call_config.error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("No authority found");
return call_config;
}
absl::string_view authority = StringViewFromSlice(
GRPC_MDVALUE(metadata->legacy_index()->named.authority->md));
absl::string_view authority =
metadata->get_pointer(HttpAuthorityMetadata())->as_string_view();
auto vhost_index = XdsRouting::FindVirtualHostForDomain(
VirtualHostListIterator(&virtual_hosts_), authority);
if (!vhost_index.has_value()) {

@ -81,14 +81,13 @@ EvaluateArgs::PerChannelArgs::PerChannelArgs(grpc_auth_context* auth_context,
}
absl::string_view EvaluateArgs::GetPath() const {
absl::string_view path;
if (metadata_ != nullptr &&
metadata_->legacy_index()->named.path != nullptr) {
grpc_linked_mdelem* elem = metadata_->legacy_index()->named.path;
const grpc_slice& val = GRPC_MDVALUE(elem->md);
path = StringViewFromSlice(val);
if (metadata_ != nullptr) {
const auto* path = metadata_->get_pointer(HttpPathMetadata());
if (path != nullptr) {
return path->as_string_view();
}
}
return path;
return absl::string_view();
}
absl::string_view EvaluateArgs::GetHost() const {
@ -102,14 +101,13 @@ absl::string_view EvaluateArgs::GetHost() const {
}
absl::string_view EvaluateArgs::GetMethod() const {
absl::string_view method;
if (metadata_ != nullptr &&
metadata_->legacy_index()->named.method != nullptr) {
grpc_linked_mdelem* elem = metadata_->legacy_index()->named.method;
const grpc_slice& val = GRPC_MDVALUE(elem->md);
method = StringViewFromSlice(val);
}
return method;
if (metadata_ != nullptr) {
auto method_md = metadata_->get(HttpMethodMetadata());
if (method_md.has_value()) {
return HttpMethodMetadata::Encode(*method_md).as_string_view();
}
}
return absl::string_view();
}
absl::optional<absl::string_view> EvaluateArgs::GetHeaderValue(

@ -65,6 +65,8 @@ struct channel_data {
struct call_data {
call_data(grpc_call_element* elem, const grpc_call_element_args& args)
: owning_call(args.call_stack), call_combiner(args.call_combiner) {
host.Init();
method.Init();
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
GPR_ASSERT(args.context != nullptr);
if (args.context[GRPC_CONTEXT_SECURITY].value == nullptr) {
@ -89,16 +91,16 @@ struct call_data {
void destroy() {
grpc_credentials_mdelem_array_destroy(&md_array);
creds.reset();
grpc_slice_unref_internal(host);
grpc_slice_unref_internal(method);
grpc_auth_metadata_context_reset(&auth_md_context);
host.Destroy();
method.Destroy();
}
grpc_call_stack* owning_call;
grpc_core::CallCombiner* call_combiner;
grpc_core::RefCountedPtr<grpc_call_credentials> creds;
grpc_slice host = grpc_empty_slice();
grpc_slice method = grpc_empty_slice();
grpc_core::ManualConstructor<grpc_core::Slice> host;
grpc_core::ManualConstructor<grpc_core::Slice> method;
/* pollset{_set} bound to this call; if we need to make external
network requests, they should be done under a pollset added to this
pollset_set so that work can progress when this call wants work to progress
@ -304,8 +306,9 @@ static void send_security_metadata(grpc_call_element* elem,
}
grpc_auth_metadata_context_build(
chand->security_connector->url_scheme(), calld->host, calld->method,
chand->auth_context.get(), &calld->auth_md_context);
chand->security_connector->url_scheme(), calld->host->c_slice(),
calld->method->c_slice(), chand->auth_context.get(),
&calld->auth_md_context);
GPR_ASSERT(calld->pollent != nullptr);
GRPC_CALL_STACK_REF(calld->owning_call, "get_request_metadata");
@ -340,11 +343,11 @@ static void on_host_checked(void* arg, grpc_error_handle error) {
} else {
grpc_transport_stream_op_batch_finish_with_failure(
batch,
grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
"Invalid host ", grpc_core::StringViewFromSlice(calld->host),
" set in :authority metadata.")),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED),
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
"Invalid host ", calld->host->as_string_view(),
" set in :authority metadata.")),
GRPC_ERROR_INT_GRPC_STATUS,
GRPC_STATUS_UNAUTHENTICATED),
calld->call_combiner);
}
GRPC_CALL_STACK_UNREF(calld->owning_call, "check_call_host");
@ -372,18 +375,18 @@ static void client_auth_start_transport_stream_op_batch(
if (batch->send_initial_metadata) {
grpc_metadata_batch* metadata =
batch->payload->send_initial_metadata.send_initial_metadata;
if (metadata->legacy_index()->named.path != nullptr) {
calld->method = grpc_slice_ref_internal(
GRPC_MDVALUE(metadata->legacy_index()->named.path->md));
if (metadata->get_pointer(grpc_core::HttpPathMetadata()) != nullptr) {
*calld->method =
metadata->get_pointer(grpc_core::HttpPathMetadata())->Ref();
}
if (metadata->legacy_index()->named.authority != nullptr) {
calld->host = grpc_slice_ref_internal(
GRPC_MDVALUE(metadata->legacy_index()->named.authority->md));
if (metadata->get_pointer(grpc_core::HttpAuthorityMetadata()) != nullptr) {
*calld->host =
metadata->get_pointer(grpc_core::HttpAuthorityMetadata())->Ref();
batch->handler_private.extra_arg = elem;
GRPC_CALL_STACK_REF(calld->owning_call, "check_call_host");
GRPC_CLOSURE_INIT(&calld->async_result_closure, on_host_checked, batch,
grpc_schedule_on_exec_ctx);
absl::string_view call_host(grpc_core::StringViewFromSlice(calld->host));
absl::string_view call_host = calld->host->as_string_view();
grpc_error_handle error = GRPC_ERROR_NONE;
if (chand->security_connector->check_call_host(
call_host, chand->auth_context.get(),

@ -328,6 +328,11 @@ class Slice : public slice_detail::BaseSlice,
return Slice(grpc_slice_sub_no_ref(TakeCSlice(), pos, pos + n));
}
// Return a sub slice of this one. Adds a reference to the underlying slice.
Slice RefSubSlice(size_t pos, size_t n) const {
return Slice(grpc_slice_sub(c_slice(), pos, pos + n));
}
Slice Ref() const { return Slice(grpc_slice_ref_internal(c_slice())); }
Slice Copy() const { return Slice(grpc_slice_copy(c_slice())); }

@ -30,59 +30,59 @@
namespace grpc_core {
const uint8_t g_static_metadata_bytes[] = {
58, 112, 97, 116, 104, 58, 109, 101, 116, 104, 111, 100, 58, 115, 116,
97, 116, 117, 115, 58, 97, 117, 116, 104, 111, 114, 105, 116, 121, 58,
115, 99, 104, 101, 109, 101, 103, 114, 112, 99, 45, 101, 110, 99, 111,
100, 105, 110, 103, 103, 114, 112, 99, 45, 97, 99, 99, 101, 112, 116,
45, 101, 110, 99, 111, 100, 105, 110, 103, 99, 111, 110, 116, 101, 110,
116, 45, 116, 121, 112, 101, 99, 111, 110, 116, 101, 110, 116, 45, 101,
110, 99, 111, 100, 105, 110, 103, 97, 99, 99, 101, 112, 116, 45, 101,
110, 99, 111, 100, 105, 110, 103, 103, 114, 112, 99, 45, 105, 110, 116,
101, 114, 110, 97, 108, 45, 101, 110, 99, 111, 100, 105, 110, 103, 45,
114, 101, 113, 117, 101, 115, 116, 103, 114, 112, 99, 45, 116, 105, 109,
101, 111, 117, 116, 47, 103, 114, 112, 99, 46, 108, 98, 46, 118, 49,
46, 76, 111, 97, 100, 66, 97, 108, 97, 110, 99, 101, 114, 47, 66,
97, 108, 97, 110, 99, 101, 76, 111, 97, 100, 47, 101, 110, 118, 111,
121, 46, 115, 101, 114, 118, 105, 99, 101, 46, 108, 111, 97, 100, 95,
115, 116, 97, 116, 115, 46, 118, 50, 46, 76, 111, 97, 100, 82, 101,
112, 111, 114, 116, 105, 110, 103, 83, 101, 114, 118, 105, 99, 101, 47,
83, 116, 114, 101, 97, 109, 76, 111, 97, 100, 83, 116, 97, 116, 115,
103, 114, 112, 99, 45, 101, 110, 99, 111, 100, 105, 110, 103, 103, 114,
112, 99, 45, 97, 99, 99, 101, 112, 116, 45, 101, 110, 99, 111, 100,
105, 110, 103, 99, 111, 110, 116, 101, 110, 116, 45, 101, 110, 99, 111,
100, 105, 110, 103, 97, 99, 99, 101, 112, 116, 45, 101, 110, 99, 111,
100, 105, 110, 103, 103, 114, 112, 99, 45, 105, 110, 116, 101, 114, 110,
97, 108, 45, 101, 110, 99, 111, 100, 105, 110, 103, 45, 114, 101, 113,
117, 101, 115, 116, 103, 114, 112, 99, 45, 116, 105, 109, 101, 111, 117,
116, 47, 103, 114, 112, 99, 46, 108, 98, 46, 118, 49, 46, 76, 111,
97, 100, 66, 97, 108, 97, 110, 99, 101, 114, 47, 66, 97, 108, 97,
110, 99, 101, 76, 111, 97, 100, 47, 101, 110, 118, 111, 121, 46, 115,
101, 114, 118, 105, 99, 101, 46, 108, 111, 97, 100, 95, 115, 116, 97,
116, 115, 46, 118, 50, 46, 76, 111, 97, 100, 82, 101, 112, 111, 114,
116, 105, 110, 103, 83, 101, 114, 118, 105, 99, 101, 47, 83, 116, 114,
101, 97, 109, 76, 111, 97, 100, 83, 116, 97, 116, 115, 47, 101, 110,
118, 111, 121, 46, 115, 101, 114, 118, 105, 99, 101, 46, 108, 111, 97,
100, 95, 115, 116, 97, 116, 115, 46, 118, 51, 46, 76, 111, 97, 100,
82, 101, 112, 111, 114, 116, 105, 110, 103, 83, 101, 114, 118, 105, 99,
101, 47, 83, 116, 114, 101, 97, 109, 76, 111, 97, 100, 83, 116, 97,
116, 115, 47, 103, 114, 112, 99, 46, 104, 101, 97, 108, 116, 104, 46,
118, 49, 46, 72, 101, 97, 108, 116, 104, 47, 87, 97, 116, 99, 104,
47, 101, 110, 118, 111, 121, 46, 115, 101, 114, 118, 105, 99, 101, 46,
108, 111, 97, 100, 95, 115, 116, 97, 116, 115, 46, 118, 51, 46, 76,
111, 97, 100, 82, 101, 112, 111, 114, 116, 105, 110, 103, 83, 101, 114,
118, 105, 99, 101, 47, 83, 116, 114, 101, 97, 109, 76, 111, 97, 100,
83, 116, 97, 116, 115, 47, 103, 114, 112, 99, 46, 104, 101, 97, 108,
116, 104, 46, 118, 49, 46, 72, 101, 97, 108, 116, 104, 47, 87, 97,
116, 99, 104, 47, 101, 110, 118, 111, 121, 46, 115, 101, 114, 118, 105,
99, 101, 46, 100, 105, 115, 99, 111, 118, 101, 114, 121, 46, 118, 50,
46, 65, 103, 103, 114, 101, 103, 97, 116, 101, 100, 68, 105, 115, 99,
111, 118, 101, 114, 121, 83, 101, 114, 118, 105, 99, 101, 47, 83, 116,
114, 101, 97, 109, 65, 103, 103, 114, 101, 103, 97, 116, 101, 100, 82,
101, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 118, 111, 121, 46,
115, 101, 114, 118, 105, 99, 101, 46, 100, 105, 115, 99, 111, 118, 101,
114, 121, 46, 118, 51, 46, 65, 103, 103, 114, 101, 103, 97, 116, 101,
100, 68, 105, 115, 99, 111, 118, 101, 114, 121, 83, 101, 114, 118, 105,
99, 101, 47, 83, 116, 114, 101, 97, 109, 65, 103, 103, 114, 101, 103,
97, 116, 101, 100, 82, 101, 115, 111, 117, 114, 99, 101, 115, 100, 101,
102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116, 114, 101, 97, 109,
47, 103, 122, 105, 112, 116, 101, 116, 114, 97, 105, 108, 101, 114, 115,
71, 69, 84, 80, 79, 83, 84, 47, 47, 105, 110, 100, 101, 120, 46,
104, 116, 109, 108, 104, 116, 116, 112, 104, 116, 116, 112, 115, 50, 48,
48, 50, 48, 52, 50, 48, 54, 51, 48, 52, 52, 48, 48, 52, 48,
52, 53, 48, 48, 97, 99, 99, 101, 112, 116, 45, 99, 104, 97, 114,
115, 101, 116, 103, 122, 105, 112, 44, 32, 100, 101, 102, 108, 97, 116,
101, 97, 99, 99, 101, 112, 116, 45, 108, 97, 110, 103, 117, 97, 103,
101, 97, 99, 99, 101, 112, 116, 45, 114, 97, 110, 103, 101, 115, 97,
99, 99, 101, 112, 116, 97, 99, 99, 101, 115, 115, 45, 99, 111, 110,
116, 114, 111, 108, 45, 97, 108, 108, 111, 119, 45, 111, 114, 105, 103,
105, 110, 97, 103, 101, 97, 108, 108, 111, 119, 97, 117, 116, 104, 111,
114, 105, 122, 97, 116, 105, 111, 110, 99, 97, 99, 104, 101, 45, 99,
111, 110, 116, 114, 111, 108, 99, 111, 110, 116, 101, 110, 116, 45, 100,
105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 99, 111, 110, 116, 101,
110, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 99, 111, 110, 116,
101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 99, 111, 110, 116, 101,
110, 116, 45, 108, 111, 99, 97, 116, 105, 111, 110, 99, 111, 110, 116,
101, 110, 116, 45, 114, 97, 110, 103, 101, 99, 111, 111, 107, 105, 101,
100, 105, 115, 99, 111, 118, 101, 114, 121, 46, 118, 50, 46, 65, 103,
103, 114, 101, 103, 97, 116, 101, 100, 68, 105, 115, 99, 111, 118, 101,
114, 121, 83, 101, 114, 118, 105, 99, 101, 47, 83, 116, 114, 101, 97,
109, 65, 103, 103, 114, 101, 103, 97, 116, 101, 100, 82, 101, 115, 111,
117, 114, 99, 101, 115, 47, 101, 110, 118, 111, 121, 46, 115, 101, 114,
118, 105, 99, 101, 46, 100, 105, 115, 99, 111, 118, 101, 114, 121, 46,
118, 51, 46, 65, 103, 103, 114, 101, 103, 97, 116, 101, 100, 68, 105,
115, 99, 111, 118, 101, 114, 121, 83, 101, 114, 118, 105, 99, 101, 47,
83, 116, 114, 101, 97, 109, 65, 103, 103, 114, 101, 103, 97, 116, 101,
100, 82, 101, 115, 111, 117, 114, 99, 101, 115, 100, 101, 102, 108, 97,
116, 101, 103, 122, 105, 112, 115, 116, 114, 101, 97, 109, 47, 103, 122,
105, 112, 116, 101, 116, 114, 97, 105, 108, 101, 114, 115, 58, 97, 117,
116, 104, 111, 114, 105, 116, 121, 58, 109, 101, 116, 104, 111, 100, 71,
69, 84, 80, 79, 83, 84, 58, 112, 97, 116, 104, 47, 47, 105, 110,
100, 101, 120, 46, 104, 116, 109, 108, 58, 115, 99, 104, 101, 109, 101,
104, 116, 116, 112, 104, 116, 116, 112, 115, 58, 115, 116, 97, 116, 117,
115, 50, 48, 48, 50, 48, 52, 50, 48, 54, 51, 48, 52, 52, 48,
48, 52, 48, 52, 53, 48, 48, 97, 99, 99, 101, 112, 116, 45, 99,
104, 97, 114, 115, 101, 116, 103, 122, 105, 112, 44, 32, 100, 101, 102,
108, 97, 116, 101, 97, 99, 99, 101, 112, 116, 45, 108, 97, 110, 103,
117, 97, 103, 101, 97, 99, 99, 101, 112, 116, 45, 114, 97, 110, 103,
101, 115, 97, 99, 99, 101, 112, 116, 97, 99, 99, 101, 115, 115, 45,
99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108, 111, 119, 45, 111,
114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108, 111, 119, 97, 117,
116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 99, 97, 99, 104,
101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111, 110, 116, 101, 110,
116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 99, 111,
110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 99,
111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 99, 111,
110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116, 105, 111, 110, 99,
111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103, 101, 99, 111, 110,
116, 101, 110, 116, 45, 116, 121, 112, 101, 99, 111, 111, 107, 105, 101,
100, 97, 116, 101, 101, 116, 97, 103, 101, 120, 112, 101, 99, 116, 101,
120, 112, 105, 114, 101, 115, 102, 114, 111, 109, 104, 111, 115, 116, 105,
102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111, 100, 105, 102,
@ -102,14 +102,13 @@ const uint8_t g_static_metadata_bytes[] = {
114, 97, 110, 115, 102, 101, 114, 45, 101, 110, 99, 111, 100, 105, 110,
103, 117, 115, 101, 114, 45, 97, 103, 101, 110, 116, 118, 97, 114, 121,
118, 105, 97, 119, 119, 119, 45, 97, 117, 116, 104, 101, 110, 116, 105,
99, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 97, 112, 112,
108, 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, 112, 99, 103, 114,
112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115, 116, 45, 98, 105,
110, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97,
116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122, 105, 112,
100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112, 105, 100, 101,
110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, 44, 103,
122, 105, 112};
99, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 103, 114, 112,
99, 80, 85, 84, 108, 98, 45, 99, 111, 115, 116, 45, 98, 105, 110,
105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116,
101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122, 105, 112, 100,
101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112, 105, 100, 101, 110,
116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122,
105, 112};
grpc_slice_refcount StaticSliceRefcount::kStaticSubRefcount;
@ -161,116 +160,115 @@ StaticSliceRefcount g_static_metadata_slice_refcounts[GRPC_STATIC_MDSTR_COUNT] =
StaticSliceRefcount(84), StaticSliceRefcount(85),
StaticSliceRefcount(86), StaticSliceRefcount(87),
StaticSliceRefcount(88), StaticSliceRefcount(89),
StaticSliceRefcount(90),
};
const StaticMetadataSlice
g_static_metadata_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
StaticMetadataSlice(&g_static_metadata_slice_refcounts[0].base, 5,
StaticMetadataSlice(&g_static_metadata_slice_refcounts[0].base, 13,
g_static_metadata_bytes + 0),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 7,
g_static_metadata_bytes + 5),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 7,
g_static_metadata_bytes + 12),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[3].base, 10,
g_static_metadata_bytes + 19),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[4].base, 7,
g_static_metadata_bytes + 29),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[5].base, 13,
g_static_metadata_bytes + 36),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 20,
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 20,
g_static_metadata_bytes + 13),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 16,
g_static_metadata_bytes + 33),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[3].base, 15,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[7].base, 12,
g_static_metadata_bytes + 69),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[8].base, 16,
g_static_metadata_bytes + 81),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[9].base, 15,
g_static_metadata_bytes + 97),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[10].base, 30,
g_static_metadata_bytes + 112),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[11].base, 12,
StaticMetadataSlice(&g_static_metadata_slice_refcounts[4].base, 30,
g_static_metadata_bytes + 64),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[5].base, 12,
g_static_metadata_bytes + 94),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[7].base, 36,
g_static_metadata_bytes + 106),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[8].base, 65,
g_static_metadata_bytes + 142),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[13].base, 36,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[14].base, 65,
g_static_metadata_bytes + 190),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[15].base, 65,
g_static_metadata_bytes + 255),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[16].base, 28,
g_static_metadata_bytes + 320),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[17].base, 80,
g_static_metadata_bytes + 348),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[18].base, 80,
g_static_metadata_bytes + 428),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[9].base, 65,
g_static_metadata_bytes + 207),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[10].base, 28,
g_static_metadata_bytes + 272),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[11].base, 80,
g_static_metadata_bytes + 300),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 80,
g_static_metadata_bytes + 380),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[13].base, 7,
g_static_metadata_bytes + 460),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[14].base, 4,
g_static_metadata_bytes + 467),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[15].base, 11,
g_static_metadata_bytes + 471),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[16].base, 2,
g_static_metadata_bytes + 482),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[17].base, 8,
g_static_metadata_bytes + 484),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[18].base, 10,
g_static_metadata_bytes + 492),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[19].base, 7,
g_static_metadata_bytes + 508),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[20].base, 4,
g_static_metadata_bytes + 515),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[21].base, 11,
g_static_metadata_bytes + 519),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[22].base, 2,
g_static_metadata_bytes + 530),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[23].base, 8,
g_static_metadata_bytes + 532),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[24].base, 3,
g_static_metadata_bytes + 502),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[20].base, 3,
g_static_metadata_bytes + 509),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[21].base, 4,
g_static_metadata_bytes + 512),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[22].base, 5,
g_static_metadata_bytes + 516),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[23].base, 1,
g_static_metadata_bytes + 521),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[24].base, 11,
g_static_metadata_bytes + 522),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[25].base, 7,
g_static_metadata_bytes + 533),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[26].base, 4,
g_static_metadata_bytes + 540),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[25].base, 4,
g_static_metadata_bytes + 543),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[26].base, 1,
g_static_metadata_bytes + 547),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[27].base, 11,
g_static_metadata_bytes + 548),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[28].base, 4,
g_static_metadata_bytes + 559),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[29].base, 5,
g_static_metadata_bytes + 563),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[27].base, 5,
g_static_metadata_bytes + 544),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[28].base, 7,
g_static_metadata_bytes + 549),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[29].base, 3,
g_static_metadata_bytes + 556),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[30].base, 3,
g_static_metadata_bytes + 568),
g_static_metadata_bytes + 559),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[31].base, 3,
g_static_metadata_bytes + 571),
g_static_metadata_bytes + 562),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[32].base, 3,
g_static_metadata_bytes + 574),
g_static_metadata_bytes + 565),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[33].base, 3,
g_static_metadata_bytes + 577),
g_static_metadata_bytes + 568),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[34].base, 3,
g_static_metadata_bytes + 580),
g_static_metadata_bytes + 571),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[35].base, 3,
g_static_metadata_bytes + 583),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[36].base, 3,
g_static_metadata_bytes + 586),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[37].base, 14,
g_static_metadata_bytes + 589),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[38].base, 13,
g_static_metadata_bytes + 603),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[39].base, 15,
g_static_metadata_bytes + 616),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[40].base, 13,
g_static_metadata_bytes + 631),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[41].base, 6,
g_static_metadata_bytes + 644),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[42].base, 27,
g_static_metadata_bytes + 650),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[43].base, 3,
g_static_metadata_bytes + 677),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[44].base, 5,
g_static_metadata_bytes + 680),
g_static_metadata_bytes + 574),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[36].base, 14,
g_static_metadata_bytes + 577),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[37].base, 13,
g_static_metadata_bytes + 591),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[38].base, 15,
g_static_metadata_bytes + 604),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[39].base, 13,
g_static_metadata_bytes + 619),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[40].base, 6,
g_static_metadata_bytes + 632),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[41].base, 27,
g_static_metadata_bytes + 638),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[42].base, 3,
g_static_metadata_bytes + 665),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[43].base, 5,
g_static_metadata_bytes + 668),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[44].base, 13,
g_static_metadata_bytes + 673),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[45].base, 13,
g_static_metadata_bytes + 685),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[46].base, 13,
g_static_metadata_bytes + 698),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[47].base, 19,
g_static_metadata_bytes + 711),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[48].base, 16,
g_static_metadata_bytes + 730),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[49].base, 14,
g_static_metadata_bytes + 746),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[50].base, 16,
g_static_metadata_bytes + 760),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[51].base, 13,
g_static_metadata_bytes + 776),
g_static_metadata_bytes + 686),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[46].base, 19,
g_static_metadata_bytes + 699),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[47].base, 16,
g_static_metadata_bytes + 718),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[48].base, 14,
g_static_metadata_bytes + 734),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[49].base, 16,
g_static_metadata_bytes + 748),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[50].base, 13,
g_static_metadata_bytes + 764),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[51].base, 12,
g_static_metadata_bytes + 777),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[52].base, 6,
g_static_metadata_bytes + 789),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[53].base, 4,
@ -333,21 +331,19 @@ const StaticMetadataSlice
g_static_metadata_bytes + 1068),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[82].base, 8,
g_static_metadata_bytes + 1084),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[83].base, 16,
StaticMetadataSlice(&g_static_metadata_slice_refcounts[83].base, 4,
g_static_metadata_bytes + 1092),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[84].base, 4,
g_static_metadata_bytes + 1108),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[85].base, 3,
g_static_metadata_bytes + 1112),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[86].base, 11,
g_static_metadata_bytes + 1115),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[87].base, 16,
StaticMetadataSlice(&g_static_metadata_slice_refcounts[84].base, 3,
g_static_metadata_bytes + 1096),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[85].base, 11,
g_static_metadata_bytes + 1099),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[86].base, 16,
g_static_metadata_bytes + 1110),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[87].base, 13,
g_static_metadata_bytes + 1126),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[88].base, 13,
g_static_metadata_bytes + 1142),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[89].base, 12,
g_static_metadata_bytes + 1155),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[90].base, 21,
g_static_metadata_bytes + 1167),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[88].base, 12,
g_static_metadata_bytes + 1139),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[89].base, 21,
g_static_metadata_bytes + 1151),
};
} // namespace grpc_core

@ -38,137 +38,137 @@
static_assert(
std::is_trivially_destructible<grpc_core::StaticMetadataSlice>::value,
"StaticMetadataSlice must be trivially destructible.");
#define GRPC_STATIC_MDSTR_COUNT 91
/* ":path" */
#define GRPC_MDSTR_PATH (::grpc_core::g_static_metadata_slice_table[0])
/* ":method" */
#define GRPC_MDSTR_METHOD (::grpc_core::g_static_metadata_slice_table[1])
/* ":status" */
#define GRPC_MDSTR_STATUS (::grpc_core::g_static_metadata_slice_table[2])
/* ":authority" */
#define GRPC_MDSTR_AUTHORITY (::grpc_core::g_static_metadata_slice_table[3])
/* ":scheme" */
#define GRPC_MDSTR_SCHEME (::grpc_core::g_static_metadata_slice_table[4])
#define GRPC_STATIC_MDSTR_COUNT 90
/* "grpc-encoding" */
#define GRPC_MDSTR_GRPC_ENCODING (::grpc_core::g_static_metadata_slice_table[5])
#define GRPC_MDSTR_GRPC_ENCODING (::grpc_core::g_static_metadata_slice_table[0])
/* "grpc-accept-encoding" */
#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING \
(::grpc_core::g_static_metadata_slice_table[6])
/* "content-type" */
#define GRPC_MDSTR_CONTENT_TYPE (::grpc_core::g_static_metadata_slice_table[7])
(::grpc_core::g_static_metadata_slice_table[1])
/* "content-encoding" */
#define GRPC_MDSTR_CONTENT_ENCODING \
(::grpc_core::g_static_metadata_slice_table[8])
(::grpc_core::g_static_metadata_slice_table[2])
/* "accept-encoding" */
#define GRPC_MDSTR_ACCEPT_ENCODING \
(::grpc_core::g_static_metadata_slice_table[9])
(::grpc_core::g_static_metadata_slice_table[3])
/* "grpc-internal-encoding-request" */
#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST \
(::grpc_core::g_static_metadata_slice_table[10])
(::grpc_core::g_static_metadata_slice_table[4])
/* "grpc-timeout" */
#define GRPC_MDSTR_GRPC_TIMEOUT (::grpc_core::g_static_metadata_slice_table[11])
#define GRPC_MDSTR_GRPC_TIMEOUT (::grpc_core::g_static_metadata_slice_table[5])
/* "" */
#define GRPC_MDSTR_EMPTY (::grpc_core::g_static_metadata_slice_table[12])
#define GRPC_MDSTR_EMPTY (::grpc_core::g_static_metadata_slice_table[6])
/* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */
#define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \
(::grpc_core::g_static_metadata_slice_table[13])
(::grpc_core::g_static_metadata_slice_table[7])
/* "/envoy.service.load_stats.v2.LoadReportingService/StreamLoadStats" */
#define GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_LOAD_STATS_DOT_V2_DOT_LOADREPORTINGSERVICE_SLASH_STREAMLOADSTATS \
(::grpc_core::g_static_metadata_slice_table[14])
(::grpc_core::g_static_metadata_slice_table[8])
/* "/envoy.service.load_stats.v3.LoadReportingService/StreamLoadStats" */
#define GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_LOAD_STATS_DOT_V3_DOT_LOADREPORTINGSERVICE_SLASH_STREAMLOADSTATS \
(::grpc_core::g_static_metadata_slice_table[15])
(::grpc_core::g_static_metadata_slice_table[9])
/* "/grpc.health.v1.Health/Watch" */
#define GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH \
(::grpc_core::g_static_metadata_slice_table[16])
(::grpc_core::g_static_metadata_slice_table[10])
/* "/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources"
*/
#define GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_DISCOVERY_DOT_V2_DOT_AGGREGATEDDISCOVERYSERVICE_SLASH_STREAMAGGREGATEDRESOURCES \
(::grpc_core::g_static_metadata_slice_table[17])
(::grpc_core::g_static_metadata_slice_table[11])
/* "/envoy.service.discovery.v3.AggregatedDiscoveryService/StreamAggregatedResources"
*/
#define GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_DISCOVERY_DOT_V3_DOT_AGGREGATEDDISCOVERYSERVICE_SLASH_STREAMAGGREGATEDRESOURCES \
(::grpc_core::g_static_metadata_slice_table[18])
(::grpc_core::g_static_metadata_slice_table[12])
/* "deflate" */
#define GRPC_MDSTR_DEFLATE (::grpc_core::g_static_metadata_slice_table[19])
#define GRPC_MDSTR_DEFLATE (::grpc_core::g_static_metadata_slice_table[13])
/* "gzip" */
#define GRPC_MDSTR_GZIP (::grpc_core::g_static_metadata_slice_table[20])
#define GRPC_MDSTR_GZIP (::grpc_core::g_static_metadata_slice_table[14])
/* "stream/gzip" */
#define GRPC_MDSTR_STREAM_SLASH_GZIP \
(::grpc_core::g_static_metadata_slice_table[21])
(::grpc_core::g_static_metadata_slice_table[15])
/* "te" */
#define GRPC_MDSTR_TE (::grpc_core::g_static_metadata_slice_table[22])
#define GRPC_MDSTR_TE (::grpc_core::g_static_metadata_slice_table[16])
/* "trailers" */
#define GRPC_MDSTR_TRAILERS (::grpc_core::g_static_metadata_slice_table[23])
#define GRPC_MDSTR_TRAILERS (::grpc_core::g_static_metadata_slice_table[17])
/* ":authority" */
#define GRPC_MDSTR_AUTHORITY (::grpc_core::g_static_metadata_slice_table[18])
/* ":method" */
#define GRPC_MDSTR_METHOD (::grpc_core::g_static_metadata_slice_table[19])
/* "GET" */
#define GRPC_MDSTR_GET (::grpc_core::g_static_metadata_slice_table[24])
#define GRPC_MDSTR_GET (::grpc_core::g_static_metadata_slice_table[20])
/* "POST" */
#define GRPC_MDSTR_POST (::grpc_core::g_static_metadata_slice_table[25])
#define GRPC_MDSTR_POST (::grpc_core::g_static_metadata_slice_table[21])
/* ":path" */
#define GRPC_MDSTR_PATH (::grpc_core::g_static_metadata_slice_table[22])
/* "/" */
#define GRPC_MDSTR_SLASH (::grpc_core::g_static_metadata_slice_table[26])
#define GRPC_MDSTR_SLASH (::grpc_core::g_static_metadata_slice_table[23])
/* "/index.html" */
#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML \
(::grpc_core::g_static_metadata_slice_table[27])
(::grpc_core::g_static_metadata_slice_table[24])
/* ":scheme" */
#define GRPC_MDSTR_SCHEME (::grpc_core::g_static_metadata_slice_table[25])
/* "http" */
#define GRPC_MDSTR_HTTP (::grpc_core::g_static_metadata_slice_table[28])
#define GRPC_MDSTR_HTTP (::grpc_core::g_static_metadata_slice_table[26])
/* "https" */
#define GRPC_MDSTR_HTTPS (::grpc_core::g_static_metadata_slice_table[29])
#define GRPC_MDSTR_HTTPS (::grpc_core::g_static_metadata_slice_table[27])
/* ":status" */
#define GRPC_MDSTR_STATUS (::grpc_core::g_static_metadata_slice_table[28])
/* "200" */
#define GRPC_MDSTR_200 (::grpc_core::g_static_metadata_slice_table[30])
#define GRPC_MDSTR_200 (::grpc_core::g_static_metadata_slice_table[29])
/* "204" */
#define GRPC_MDSTR_204 (::grpc_core::g_static_metadata_slice_table[31])
#define GRPC_MDSTR_204 (::grpc_core::g_static_metadata_slice_table[30])
/* "206" */
#define GRPC_MDSTR_206 (::grpc_core::g_static_metadata_slice_table[32])
#define GRPC_MDSTR_206 (::grpc_core::g_static_metadata_slice_table[31])
/* "304" */
#define GRPC_MDSTR_304 (::grpc_core::g_static_metadata_slice_table[33])
#define GRPC_MDSTR_304 (::grpc_core::g_static_metadata_slice_table[32])
/* "400" */
#define GRPC_MDSTR_400 (::grpc_core::g_static_metadata_slice_table[34])
#define GRPC_MDSTR_400 (::grpc_core::g_static_metadata_slice_table[33])
/* "404" */
#define GRPC_MDSTR_404 (::grpc_core::g_static_metadata_slice_table[35])
#define GRPC_MDSTR_404 (::grpc_core::g_static_metadata_slice_table[34])
/* "500" */
#define GRPC_MDSTR_500 (::grpc_core::g_static_metadata_slice_table[36])
#define GRPC_MDSTR_500 (::grpc_core::g_static_metadata_slice_table[35])
/* "accept-charset" */
#define GRPC_MDSTR_ACCEPT_CHARSET \
(::grpc_core::g_static_metadata_slice_table[37])
(::grpc_core::g_static_metadata_slice_table[36])
/* "gzip, deflate" */
#define GRPC_MDSTR_GZIP_COMMA_DEFLATE \
(::grpc_core::g_static_metadata_slice_table[38])
(::grpc_core::g_static_metadata_slice_table[37])
/* "accept-language" */
#define GRPC_MDSTR_ACCEPT_LANGUAGE \
(::grpc_core::g_static_metadata_slice_table[39])
(::grpc_core::g_static_metadata_slice_table[38])
/* "accept-ranges" */
#define GRPC_MDSTR_ACCEPT_RANGES \
(::grpc_core::g_static_metadata_slice_table[40])
(::grpc_core::g_static_metadata_slice_table[39])
/* "accept" */
#define GRPC_MDSTR_ACCEPT (::grpc_core::g_static_metadata_slice_table[41])
#define GRPC_MDSTR_ACCEPT (::grpc_core::g_static_metadata_slice_table[40])
/* "access-control-allow-origin" */
#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN \
(::grpc_core::g_static_metadata_slice_table[42])
(::grpc_core::g_static_metadata_slice_table[41])
/* "age" */
#define GRPC_MDSTR_AGE (::grpc_core::g_static_metadata_slice_table[43])
#define GRPC_MDSTR_AGE (::grpc_core::g_static_metadata_slice_table[42])
/* "allow" */
#define GRPC_MDSTR_ALLOW (::grpc_core::g_static_metadata_slice_table[44])
#define GRPC_MDSTR_ALLOW (::grpc_core::g_static_metadata_slice_table[43])
/* "authorization" */
#define GRPC_MDSTR_AUTHORIZATION \
(::grpc_core::g_static_metadata_slice_table[45])
(::grpc_core::g_static_metadata_slice_table[44])
/* "cache-control" */
#define GRPC_MDSTR_CACHE_CONTROL \
(::grpc_core::g_static_metadata_slice_table[46])
(::grpc_core::g_static_metadata_slice_table[45])
/* "content-disposition" */
#define GRPC_MDSTR_CONTENT_DISPOSITION \
(::grpc_core::g_static_metadata_slice_table[47])
(::grpc_core::g_static_metadata_slice_table[46])
/* "content-language" */
#define GRPC_MDSTR_CONTENT_LANGUAGE \
(::grpc_core::g_static_metadata_slice_table[48])
(::grpc_core::g_static_metadata_slice_table[47])
/* "content-length" */
#define GRPC_MDSTR_CONTENT_LENGTH \
(::grpc_core::g_static_metadata_slice_table[49])
(::grpc_core::g_static_metadata_slice_table[48])
/* "content-location" */
#define GRPC_MDSTR_CONTENT_LOCATION \
(::grpc_core::g_static_metadata_slice_table[50])
(::grpc_core::g_static_metadata_slice_table[49])
/* "content-range" */
#define GRPC_MDSTR_CONTENT_RANGE \
(::grpc_core::g_static_metadata_slice_table[51])
(::grpc_core::g_static_metadata_slice_table[50])
/* "content-type" */
#define GRPC_MDSTR_CONTENT_TYPE (::grpc_core::g_static_metadata_slice_table[51])
/* "cookie" */
#define GRPC_MDSTR_COOKIE (::grpc_core::g_static_metadata_slice_table[52])
/* "date" */
@ -240,27 +240,24 @@ static_assert(
(::grpc_core::g_static_metadata_slice_table[81])
/* "identity" */
#define GRPC_MDSTR_IDENTITY (::grpc_core::g_static_metadata_slice_table[82])
/* "application/grpc" */
#define GRPC_MDSTR_APPLICATION_SLASH_GRPC \
(::grpc_core::g_static_metadata_slice_table[83])
/* "grpc" */
#define GRPC_MDSTR_GRPC (::grpc_core::g_static_metadata_slice_table[84])
#define GRPC_MDSTR_GRPC (::grpc_core::g_static_metadata_slice_table[83])
/* "PUT" */
#define GRPC_MDSTR_PUT (::grpc_core::g_static_metadata_slice_table[85])
#define GRPC_MDSTR_PUT (::grpc_core::g_static_metadata_slice_table[84])
/* "lb-cost-bin" */
#define GRPC_MDSTR_LB_COST_BIN (::grpc_core::g_static_metadata_slice_table[86])
#define GRPC_MDSTR_LB_COST_BIN (::grpc_core::g_static_metadata_slice_table[85])
/* "identity,deflate" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE \
(::grpc_core::g_static_metadata_slice_table[87])
(::grpc_core::g_static_metadata_slice_table[86])
/* "identity,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_GZIP \
(::grpc_core::g_static_metadata_slice_table[88])
(::grpc_core::g_static_metadata_slice_table[87])
/* "deflate,gzip" */
#define GRPC_MDSTR_DEFLATE_COMMA_GZIP \
(::grpc_core::g_static_metadata_slice_table[89])
(::grpc_core::g_static_metadata_slice_table[88])
/* "identity,deflate,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
(::grpc_core::g_static_metadata_slice_table[90])
(::grpc_core::g_static_metadata_slice_table[89])
namespace grpc_core {
extern StaticSliceRefcount

@ -75,8 +75,6 @@
- status/close recv (depending on client/server) */
#define MAX_CONCURRENT_BATCHES 6
#define MAX_SEND_EXTRA_METADATA_COUNT 3
// Used to create arena for the first call.
#define ESTIMATED_MDELEM_COUNT 16
@ -219,10 +217,6 @@ struct grpc_call {
/* Contexts for various subsystems (security, tracing, ...). */
grpc_call_context_element context[GRPC_CONTEXT_COUNT] = {};
/* for the client, extra metadata is initial metadata; for the
server, it's trailing metadata */
grpc_linked_mdelem send_extra_metadata[MAX_SEND_EXTRA_METADATA_COUNT];
int send_extra_metadata_count;
grpc_millis send_deadline;
grpc_core::ManualConstructor<grpc_core::SliceBufferByteStream> sending_stream;
@ -342,7 +336,7 @@ size_t grpc_call_get_initial_size_estimate() {
sizeof(grpc_linked_mdelem) * ESTIMATED_MDELEM_COUNT;
}
grpc_error_handle grpc_call_create(const grpc_call_create_args* args,
grpc_error_handle grpc_call_create(grpc_call_create_args* args,
grpc_call** out_call) {
GPR_TIMER_SCOPE("grpc_call_create", 0);
@ -373,24 +367,17 @@ grpc_error_handle grpc_call_create(const grpc_call_create_args* args,
call->final_op.client.status = nullptr;
call->final_op.client.error_string = nullptr;
GRPC_STATS_INC_CLIENT_CALLS_CREATED();
GPR_ASSERT(args->add_initial_metadata_count <
MAX_SEND_EXTRA_METADATA_COUNT);
for (size_t i = 0; i < args->add_initial_metadata_count; i++) {
call->send_extra_metadata[i].md = args->add_initial_metadata[i];
if (grpc_slice_eq_static_interned(
GRPC_MDKEY(args->add_initial_metadata[i]), GRPC_MDSTR_PATH)) {
path = grpc_slice_ref_internal(
GRPC_MDVALUE(args->add_initial_metadata[i]));
}
path = grpc_slice_ref_internal(args->path->c_slice());
call->send_initial_metadata.Set(grpc_core::HttpPathMetadata(),
std::move(*args->path));
if (args->authority.has_value()) {
call->send_initial_metadata.Set(grpc_core::HttpAuthorityMetadata(),
std::move(*args->authority));
}
call->send_extra_metadata_count =
static_cast<int>(args->add_initial_metadata_count);
} else {
GRPC_STATS_INC_SERVER_CALLS_CREATED();
call->final_op.server.cancelled = nullptr;
call->final_op.server.core_server = args->server;
GPR_ASSERT(args->add_initial_metadata_count == 0);
call->send_extra_metadata_count = 0;
}
grpc_millis send_deadline = args->send_deadline;
@ -551,9 +538,6 @@ static void destroy_call(void* call, grpc_error_handle /*error*/) {
if (pc != nullptr) {
pc->~parent_call();
}
for (int i = 0; i < c->send_extra_metadata_count; i++) {
GRPC_MDELEM_UNREF(c->send_extra_metadata[i].md);
}
if (c->cq) {
GRPC_CQ_INTERNAL_UNREF(c->cq, "bind");
}
@ -915,8 +899,16 @@ static int prepare_application_metadata(grpc_call* call, int count,
// HTTP2 hpack encoding has a maximum limit.
return 0;
}
batch->Append(grpc_core::StringViewFromSlice(md->key),
grpc_core::Slice(grpc_slice_ref_internal(md->value)));
batch->Append(
grpc_core::StringViewFromSlice(md->key),
grpc_core::Slice(grpc_slice_ref_internal(md->value)),
[md](absl::string_view error, const grpc_core::Slice& value) {
gpr_log(
GPR_DEBUG, "Append error: %s",
absl::StrCat("key=", grpc_core::StringViewFromSlice(md->key),
" error=", error, " value=", value.as_string_view())
.c_str());
});
}
return 1;
@ -1663,16 +1655,6 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
}
stream_op->send_initial_metadata = true;
call->sent_initial_metadata = true;
if (call->is_client) {
// TODO(ctiller): this will turn into explicit Set() calls once we
// migrate :path, :authority.
for (int i = 0; i < call->send_extra_metadata_count; i++) {
GRPC_LOG_IF_ERROR("prepare_client_metadata",
call->send_initial_metadata.LinkTail(
&call->send_extra_metadata[i]));
}
call->send_extra_metadata_count = 0;
}
if (!prepare_application_metadata(
call, static_cast<int>(op->data.send_initial_metadata.count),
op->data.send_initial_metadata.metadata, 0, &compression_md,

@ -46,8 +46,8 @@ typedef struct grpc_call_create_args {
const void* server_transport_data;
grpc_mdelem* add_initial_metadata;
size_t add_initial_metadata_count;
absl::optional<grpc_core::Slice> path;
absl::optional<grpc_core::Slice> authority;
grpc_millis send_deadline;
} grpc_call_create_args;
@ -55,7 +55,7 @@ typedef struct grpc_call_create_args {
/* Create a new call based on \a args.
Regardless of success or failure, always returns a valid new call into *call
*/
grpc_error_handle grpc_call_create(const grpc_call_create_args* args,
grpc_error_handle grpc_call_create(grpc_call_create_args* args,
grpc_call** call);
void grpc_call_set_completion_queue(grpc_call* call, grpc_completion_queue* cq);

@ -343,19 +343,11 @@ void grpc_channel_reset_connect_backoff(grpc_channel* channel) {
static grpc_call* grpc_channel_create_call_internal(
grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
grpc_completion_queue* cq, grpc_pollset_set* pollset_set_alternative,
grpc_mdelem path_mdelem, grpc_mdelem authority_mdelem,
grpc_core::Slice path, absl::optional<grpc_core::Slice> authority,
grpc_millis deadline) {
grpc_mdelem send_metadata[2];
size_t num_metadata = 0;
GPR_ASSERT(channel->is_client);
GPR_ASSERT(!(cq != nullptr && pollset_set_alternative != nullptr));
send_metadata[num_metadata++] = path_mdelem;
if (!GRPC_MDISNULL(authority_mdelem)) {
send_metadata[num_metadata++] = authority_mdelem;
}
grpc_call_create_args args;
args.channel = channel;
args.server = nullptr;
@ -364,8 +356,8 @@ static grpc_call* grpc_channel_create_call_internal(
args.cq = cq;
args.pollset_set_alternative = pollset_set_alternative;
args.server_transport_data = nullptr;
args.add_initial_metadata = send_metadata;
args.add_initial_metadata_count = num_metadata;
args.path = std::move(path);
args.authority = std::move(authority);
args.send_deadline = deadline;
grpc_call* call;
@ -384,9 +376,10 @@ grpc_call* grpc_channel_create_call(grpc_channel* channel,
grpc_core::ExecCtx exec_ctx;
grpc_call* call = grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, completion_queue, nullptr,
grpc_mdelem_create(GRPC_MDSTR_PATH, method, nullptr),
host != nullptr ? grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, *host, nullptr)
: GRPC_MDNULL,
grpc_core::Slice(grpc_slice_ref_internal(method)),
host != nullptr
? absl::optional<grpc_core::Slice>(grpc_slice_ref_internal(*host))
: absl::nullopt,
grpc_timespec_to_millis_round_up(deadline));
return call;
@ -399,34 +392,31 @@ grpc_call* grpc_channel_create_pollset_set_call(
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, nullptr, pollset_set,
grpc_mdelem_create(GRPC_MDSTR_PATH, method, nullptr),
host != nullptr ? grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, *host, nullptr)
: GRPC_MDNULL,
grpc_core::Slice(method),
host != nullptr
? absl::optional<grpc_core::Slice>(grpc_slice_ref_internal(*host))
: absl::nullopt,
deadline);
}
namespace grpc_core {
RegisteredCall::RegisteredCall(const char* method_arg, const char* host_arg)
: path(method_arg != nullptr && method_arg[0] != 0
? grpc_mdelem_from_slices(
GRPC_MDSTR_PATH, grpc_slice_from_copied_string(method_arg))
: GRPC_MDNULL),
authority(
host_arg != nullptr && host_arg[0] != 0
? grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
grpc_slice_from_copied_string(host_arg))
: GRPC_MDNULL) {}
RegisteredCall::RegisteredCall(const char* method_arg, const char* host_arg) {
path = Slice::FromCopiedString(method_arg);
if (host_arg != nullptr && host_arg[0] != 0) {
authority = Slice::FromCopiedString(host_arg);
}
}
RegisteredCall::RegisteredCall(const RegisteredCall& other)
: path(GRPC_MDELEM_REF(other.path)),
authority(GRPC_MDELEM_REF(other.authority)) {}
RegisteredCall::~RegisteredCall() {
GRPC_MDELEM_UNREF(path);
GRPC_MDELEM_UNREF(authority);
: path(other.path.Ref()) {
if (other.authority.has_value()) {
authority = other.authority->Ref();
}
}
RegisteredCall::~RegisteredCall() {}
} // namespace grpc_core
void* grpc_channel_register_call(grpc_channel* channel, const char* method,
@ -473,7 +463,10 @@ grpc_call* grpc_channel_create_registered_call(
grpc_core::ExecCtx exec_ctx;
grpc_call* call = grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, completion_queue, nullptr,
GRPC_MDELEM_REF(rc->path), GRPC_MDELEM_REF(rc->authority),
rc->path.Ref(),
rc->authority.has_value()
? absl::optional<grpc_core::Slice>(rc->authority->Ref())
: absl::nullopt,
grpc_timespec_to_millis_round_up(deadline));
return call;

@ -74,8 +74,8 @@ void grpc_channel_update_call_size_estimate(grpc_channel* channel, size_t size);
namespace grpc_core {
struct RegisteredCall {
grpc_mdelem path;
grpc_mdelem authority;
Slice path;
absl::optional<Slice> authority;
explicit RegisteredCall(const char* method_arg, const char* host_arg);
RegisteredCall(const RegisteredCall& other);

@ -1124,8 +1124,6 @@ void Server::ChannelData::AcceptStream(void* arg, grpc_transport* /*transport*/,
args.cq = nullptr;
args.pollset_set_alternative = nullptr;
args.server_transport_data = transport_server_data;
args.add_initial_metadata = nullptr;
args.add_initial_metadata_count = 0;
args.send_deadline = GRPC_MILLIS_INF_FUTURE;
grpc_call* call;
grpc_error_handle error = grpc_call_create(&args, &call);
@ -1200,12 +1198,6 @@ Server::CallData::CallData(grpc_call_element* elem,
Server::CallData::~CallData() {
GPR_ASSERT(state_.load(std::memory_order_relaxed) != CallState::PENDING);
GRPC_ERROR_UNREF(recv_initial_metadata_error_);
if (host_.has_value()) {
grpc_slice_unref_internal(*host_);
}
if (path_.has_value()) {
grpc_slice_unref_internal(*path_);
}
grpc_metadata_array_destroy(&initial_metadata_);
grpc_byte_buffer_destroy(payload_);
}
@ -1258,8 +1250,9 @@ void Server::CallData::Publish(size_t cq_idx, RequestedCall* rc) {
case RequestedCall::Type::BATCH_CALL:
GPR_ASSERT(host_.has_value());
GPR_ASSERT(path_.has_value());
rc->data.batch.details->host = grpc_slice_ref_internal(*host_);
rc->data.batch.details->method = grpc_slice_ref_internal(*path_);
rc->data.batch.details->host = grpc_slice_ref_internal(host_->c_slice());
rc->data.batch.details->method =
grpc_slice_ref_internal(path_->c_slice());
rc->data.batch.details->deadline =
grpc_millis_to_timespec(deadline_, GPR_CLOCK_MONOTONIC);
rc->data.batch.details->flags = recv_initial_metadata_flags_;
@ -1320,7 +1313,7 @@ void Server::CallData::StartNewRpc(grpc_call_element* elem) {
GRPC_SRM_PAYLOAD_NONE;
if (path_.has_value() && host_.has_value()) {
ChannelRegisteredMethod* rm =
chand->GetRegisteredMethod(*host_, *path_,
chand->GetRegisteredMethod(host_->c_slice(), path_->c_slice(),
(recv_initial_metadata_flags_ &
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST));
if (rm != nullptr) {
@ -1352,6 +1345,8 @@ void Server::CallData::RecvInitialMetadataBatchComplete(
grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
auto* calld = static_cast<Server::CallData*>(elem->call_data);
if (error != GRPC_ERROR_NONE) {
gpr_log(GPR_DEBUG, "Failed call creation: %s",
grpc_error_std_string(error).c_str());
calld->FailCallCreation();
return;
}
@ -1385,17 +1380,8 @@ void Server::CallData::RecvInitialMetadataReady(void* arg,
grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
CallData* calld = static_cast<CallData*>(elem->call_data);
if (error == GRPC_ERROR_NONE) {
GPR_DEBUG_ASSERT(
calld->recv_initial_metadata_->legacy_index()->named.path != nullptr);
GPR_DEBUG_ASSERT(
calld->recv_initial_metadata_->legacy_index()->named.authority !=
nullptr);
calld->path_.emplace(grpc_slice_ref_internal(GRPC_MDVALUE(
calld->recv_initial_metadata_->legacy_index()->named.path->md)));
calld->host_.emplace(grpc_slice_ref_internal(GRPC_MDVALUE(
calld->recv_initial_metadata_->legacy_index()->named.authority->md)));
calld->recv_initial_metadata_->Remove(GRPC_BATCH_PATH);
calld->recv_initial_metadata_->Remove(GRPC_BATCH_AUTHORITY);
calld->path_ = calld->recv_initial_metadata_->Take(HttpPathMetadata());
calld->host_ = calld->recv_initial_metadata_->Take(HttpAuthorityMetadata());
} else {
(void)GRPC_ERROR_REF(error);
}

@ -293,8 +293,8 @@ class Server : public InternallyRefCounted<Server>,
std::atomic<CallState> state_{CallState::NOT_STARTED};
absl::optional<grpc_slice> path_;
absl::optional<grpc_slice> host_;
absl::optional<Slice> path_;
absl::optional<Slice> host_;
grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE;
grpc_completion_queue* cq_new_ = nullptr;

@ -87,9 +87,10 @@ struct GrpcTimeoutMetadata {
using ValueType = grpc_millis;
using MementoType = grpc_millis;
static absl::string_view key() { return "grpc-timeout"; }
static MementoType ParseMemento(Slice value) {
static MementoType ParseMemento(Slice value, MetadataParseErrorFn on_error) {
grpc_millis timeout;
if (GPR_UNLIKELY(!grpc_http2_decode_timeout(value.c_slice(), &timeout))) {
on_error("invalid value", value);
timeout = GRPC_MILLIS_INF_FUTURE;
}
return timeout;
@ -119,10 +120,12 @@ struct TeMetadata {
};
using MementoType = ValueType;
static absl::string_view key() { return "te"; }
static MementoType ParseMemento(Slice value) {
static MementoType ParseMemento(Slice value, MetadataParseErrorFn on_error) {
auto out = kInvalid;
if (value == "trailers") {
out = kTrailers;
} else {
on_error("invalid value", value);
}
return out;
}
@ -141,10 +144,167 @@ struct TeMetadata {
}
};
// content-type metadata trait.
struct ContentTypeMetadata {
// gRPC says that content-type can be application/grpc[;something]
// Core has only ever verified the prefix.
// IF we want to start verifying more, we can expand this type.
enum ValueType {
kApplicationGrpc,
kEmpty,
kInvalid,
};
using MementoType = ValueType;
static absl::string_view key() { return "content-type"; }
static MementoType ParseMemento(Slice value, MetadataParseErrorFn on_error) {
auto out = kInvalid;
auto value_string = value.as_string_view();
if (value_string == "application/grpc") {
out = kApplicationGrpc;
} else if (absl::StartsWith(value_string, "application/grpc;")) {
out = kApplicationGrpc;
} else if (absl::StartsWith(value_string, "application/grpc+")) {
out = kApplicationGrpc;
} else if (value_string.empty()) {
out = kEmpty;
} else {
on_error("invalid value", value);
}
return out;
}
static ValueType MementoToValue(MementoType content_type) {
return content_type;
}
static StaticSlice Encode(ValueType x) {
switch (x) {
case kEmpty:
return StaticSlice::FromStaticString("");
case kApplicationGrpc:
return StaticSlice::FromStaticString("application/grpc");
case kInvalid:
abort();
}
GPR_UNREACHABLE_CODE(
return StaticSlice::FromStaticString("unrepresentable value"));
}
static const char* DisplayValue(MementoType content_type) {
switch (content_type) {
case ValueType::kApplicationGrpc:
return "application/grpc";
case ValueType::kEmpty:
return "";
default:
return "<discarded-invalid-value>";
}
}
};
// scheme metadata trait.
struct HttpSchemeMetadata {
enum ValueType {
kHttp,
kHttps,
kInvalid,
};
using MementoType = ValueType;
static absl::string_view key() { return ":scheme"; }
static MementoType ParseMemento(Slice value, MetadataParseErrorFn on_error) {
return Parse(value.as_string_view(), on_error);
}
static ValueType Parse(absl::string_view value,
MetadataParseErrorFn on_error) {
if (value == "http") {
return kHttp;
} else if (value == "https") {
return kHttps;
}
on_error("invalid value", Slice::FromCopiedBuffer(value));
return kInvalid;
}
static ValueType MementoToValue(MementoType content_type) {
return content_type;
}
static StaticSlice Encode(ValueType x) {
switch (x) {
case kHttp:
return StaticSlice::FromStaticString("http");
case kHttps:
return StaticSlice::FromStaticString("https");
default:
abort();
}
}
static const char* DisplayValue(MementoType content_type) {
switch (content_type) {
case kHttp:
return "http";
case kHttps:
return "https";
default:
return "<discarded-invalid-value>";
}
}
};
// method metadata trait.
struct HttpMethodMetadata {
enum ValueType {
kPost,
kPut,
kGet,
kInvalid,
};
using MementoType = ValueType;
static absl::string_view key() { return ":method"; }
static MementoType ParseMemento(Slice value, MetadataParseErrorFn on_error) {
auto out = kInvalid;
auto value_string = value.as_string_view();
if (value_string == "POST") {
out = kPost;
} else if (value_string == "PUT") {
out = kPut;
} else if (value_string == "GET") {
out = kGet;
} else {
on_error("invalid value", value);
}
return out;
}
static ValueType MementoToValue(MementoType content_type) {
return content_type;
}
static StaticSlice Encode(ValueType x) {
switch (x) {
case kPost:
return StaticSlice::FromStaticString("POST");
case kPut:
return StaticSlice::FromStaticString("PUT");
case kGet:
return StaticSlice::FromStaticString("GET");
default:
abort();
}
}
static const char* DisplayValue(MementoType content_type) {
switch (content_type) {
case kPost:
return "POST";
case kPut:
return "PUT";
case kGet:
return "GET";
default:
return "<discarded-invalid-value>";
}
}
};
struct SimpleSliceBasedMetadata {
using ValueType = Slice;
using MementoType = Slice;
static MementoType ParseMemento(Slice value) { return value.TakeOwned(); }
static MementoType ParseMemento(Slice value, MetadataParseErrorFn) {
return value.TakeOwned();
}
static ValueType MementoToValue(MementoType value) { return value; }
static Slice Encode(const ValueType& x) { return x.Ref(); }
static absl::string_view DisplayValue(const MementoType& value) {
@ -187,6 +347,16 @@ struct GrpcTagsBinMetadata : public SimpleSliceBasedMetadata {
static absl::string_view key() { return "grpc-tags-bin"; }
};
// :authority metadata trait.
struct HttpAuthorityMetadata : public SimpleSliceBasedMetadata {
static absl::string_view key() { return ":authority"; }
};
// :path metadata trait.
struct HttpPathMetadata : public SimpleSliceBasedMetadata {
static absl::string_view key() { return ":path"; }
};
// We separate SimpleIntBasedMetadata into two pieces: one that does not depend
// on the invalid value, and one that does. This allows the compiler to easily
// see the functions that are shared, and helps reduce code bloat here.
@ -202,9 +372,10 @@ struct SimpleIntBasedMetadataBase {
template <typename Int, Int kInvalidValue>
struct SimpleIntBasedMetadata : public SimpleIntBasedMetadataBase<Int> {
static constexpr Int invalid_value() { return kInvalidValue; }
static Int ParseMemento(Slice value) {
static Int ParseMemento(Slice value, MetadataParseErrorFn on_error) {
Int out;
if (!absl::SimpleAtoi(value.as_string_view(), &out)) {
on_error("not an integer", value);
out = kInvalidValue;
}
return out;
@ -229,6 +400,12 @@ struct GrpcRetryPushbackMsMetadata
static absl::string_view key() { return "grpc-retry-pushback-ms"; }
};
// :status metadata trait.
// TODO(ctiller): consider moving to uint16_t
struct HttpStatusMetadata : public SimpleIntBasedMetadata<uint32_t, 0> {
static absl::string_view key() { return ":status"; }
};
namespace metadata_detail {
// Helper type - maps a string name to a trait.
@ -264,9 +441,11 @@ struct NameLookup<> {
template <typename ParseMementoFn, typename MementoToValueFn>
struct ParseValue {
template <ParseMementoFn parse_memento, MementoToValueFn memento_to_value>
static GPR_ATTRIBUTE_NOINLINE auto Parse(Slice* value)
-> decltype(memento_to_value(parse_memento(std::move(*value)))) {
return memento_to_value(parse_memento(std::move(*value)));
static GPR_ATTRIBUTE_NOINLINE auto Parse(Slice* value,
MetadataParseErrorFn on_error)
-> decltype(memento_to_value(parse_memento(std::move(*value),
on_error))) {
return memento_to_value(parse_memento(std::move(*value), on_error));
}
};
@ -276,8 +455,10 @@ struct ParseValue {
template <typename Container>
class ParseHelper {
public:
ParseHelper(Slice value, size_t transport_size)
: value_(std::move(value)), transport_size_(transport_size) {}
ParseHelper(Slice value, MetadataParseErrorFn on_error, size_t transport_size)
: value_(std::move(value)),
on_error_(on_error),
transport_size_(transport_size) {}
template <typename Trait>
GPR_ATTRIBUTE_NOINLINE ParsedMetadata<Container> Found(Trait trait) {
@ -296,12 +477,13 @@ class ParseHelper {
}
private:
template <typename T, T (*parse_memento)(Slice)>
template <typename T, T (*parse_memento)(Slice, MetadataParseErrorFn)>
GPR_ATTRIBUTE_NOINLINE T ParseValueToMemento() {
return parse_memento(std::move(value_));
return parse_memento(std::move(value_), on_error_);
}
Slice value_;
MetadataParseErrorFn on_error_;
const size_t transport_size_;
};
@ -311,8 +493,8 @@ class ParseHelper {
template <typename Container>
class AppendHelper {
public:
AppendHelper(Container* container, Slice value)
: container_(container), value_(std::move(value)) {}
AppendHelper(Container* container, Slice value, MetadataParseErrorFn on_error)
: container_(container), value_(std::move(value)), on_error_(on_error) {}
template <typename Trait>
GPR_ATTRIBUTE_NOINLINE void Found(Trait trait) {
@ -320,7 +502,7 @@ class AppendHelper {
trait, ParseValue<decltype(Trait::ParseMemento),
decltype(Trait::MementoToValue)>::
template Parse<Trait::ParseMemento, Trait::MementoToValue>(
&value_));
&value_, on_error_));
}
GPR_ATTRIBUTE_NOINLINE void NotFound(absl::string_view key) {
@ -336,6 +518,7 @@ class AppendHelper {
private:
Container* const container_;
Slice value_;
MetadataParseErrorFn on_error_;
};
} // namespace metadata_detail
@ -380,7 +563,9 @@ MetadataValueAsSlice(typename Which::ValueType value) {
// static absl::string_view key() { return "grpc-xyz"; }
// // Parse a memento from a slice
// // Takes ownership of value
// static MementoType ParseMemento(Slice value) { ... }
// // Calls fn in the case of an error that should be reported to the user
// static MementoType ParseMemento(Slice value, MementoParseErrorFn fn) { ...
// }
// // Convert a memento to a value
// static ValueType MementoToValue(MementoType memento) { ... }
// // Convert a value to its canonical text wire format (the format that
@ -436,10 +621,10 @@ class MetadataMap {
// transitions.
template <typename Encoder>
void Encode(Encoder* encoder) const {
table_.ForEach(EncodeWrapper<Encoder>{encoder});
for (auto* l = list_.head; l; l = l->next) {
encoder->Encode(l->md);
}
table_.ForEach(EncodeWrapper<Encoder>{encoder});
}
// Get the pointer to the value of some known metadata.
@ -503,9 +688,10 @@ class MetadataMap {
// TODO(ctiller): key should probably be an absl::string_view.
// Once we don't care about interning anymore, make that change!
static ParsedMetadata<MetadataMap> Parse(absl::string_view key, Slice value,
uint32_t transport_size) {
uint32_t transport_size,
MetadataParseErrorFn on_error) {
metadata_detail::ParseHelper<MetadataMap> helper(value.TakeOwned(),
transport_size);
on_error, transport_size);
return metadata_detail::NameLookup<Traits...>::Lookup(key, &helper);
}
@ -516,8 +702,10 @@ class MetadataMap {
}
// Append a key/value pair - takes ownership of value
void Append(absl::string_view key, Slice value) {
metadata_detail::AppendHelper<MetadataMap> helper(this, value.TakeOwned());
void Append(absl::string_view key, Slice value,
MetadataParseErrorFn on_error) {
metadata_detail::AppendHelper<MetadataMap> helper(this, value.TakeOwned(),
on_error);
metadata_detail::NameLookup<Traits...>::Lookup(key, &helper);
}
@ -653,6 +841,22 @@ class MetadataMap {
}
};
// Encoder to compute TransportSize
class TransportSizeEncoder {
public:
void Encode(grpc_mdelem elem) { size_ += GRPC_MDELEM_LENGTH(elem); }
template <typename Which>
void Encode(Which, const typename Which::ValueType& value) {
size_ += Which::key().length() + Which::Encode(value).length() + 32;
}
size_t size() const { return size_; }
private:
uint32_t size_ = 0;
};
void AssertValidCallouts();
grpc_error_handle LinkCallout(grpc_linked_mdelem* storage,
grpc_metadata_batch_callouts_index idx)
@ -1010,12 +1214,9 @@ void MetadataMap<Traits...>::Clear() {
template <typename... Traits>
size_t MetadataMap<Traits...>::TransportSize() const {
size_t size = 0;
for (grpc_linked_mdelem* elem = list_.head; elem != nullptr;
elem = elem->next) {
size += GRPC_MDELEM_LENGTH(elem->md);
}
return size;
TransportSizeEncoder enc;
Encode(&enc);
return enc.size();
}
template <typename... Traits>
@ -1037,11 +1238,17 @@ bool MetadataMap<Traits...>::ReplaceIfExists(grpc_slice key, grpc_slice value) {
} // namespace grpc_core
using grpc_metadata_batch = grpc_core::MetadataMap<
// Colon prefixed headers first
grpc_core::HttpPathMetadata, grpc_core::HttpAuthorityMetadata,
grpc_core::HttpMethodMetadata, grpc_core::HttpStatusMetadata,
grpc_core::HttpSchemeMetadata,
// Non-colon prefixed headers begin here
grpc_core::ContentTypeMetadata, grpc_core::TeMetadata,
grpc_core::GrpcStatusMetadata, grpc_core::GrpcTimeoutMetadata,
grpc_core::GrpcPreviousRpcAttemptsMetadata,
grpc_core::GrpcRetryPushbackMsMetadata, grpc_core::TeMetadata,
grpc_core::UserAgentMetadata, grpc_core::GrpcMessageMetadata,
grpc_core::HostMetadata, grpc_core::XEndpointLoadMetricsBinMetadata,
grpc_core::GrpcRetryPushbackMsMetadata, grpc_core::UserAgentMetadata,
grpc_core::GrpcMessageMetadata, grpc_core::HostMetadata,
grpc_core::XEndpointLoadMetricsBinMetadata,
grpc_core::GrpcServerStatsBinMetadata, grpc_core::GrpcTraceBinMetadata,
grpc_core::GrpcTagsBinMetadata>;

@ -30,6 +30,9 @@
namespace grpc_core {
using MetadataParseErrorFn =
absl::FunctionRef<void(absl::string_view error, const Slice& value)>;
namespace metadata_detail {
// Helper to determine whether a traits metadata is inlinable inside a memento,
@ -171,16 +174,18 @@ class ParsedMetadata {
// HTTP2 defined storage size of this metadatum.
uint32_t transport_size() const { return transport_size_; }
// Create a new parsed metadata with the same key but a different value.
ParsedMetadata WithNewValue(Slice value) const {
ParsedMetadata WithNewValue(Slice value,
MetadataParseErrorFn on_error) const {
ParsedMetadata result;
result.vtable_ = vtable_;
result.value_ = value_;
result.transport_size_ =
TransportSize(vtable_->key_length(value_), value.length());
vtable_->with_new_value(&value, &result);
TransportSize(vtable_->key(value_).length(), value.length());
vtable_->with_new_value(&value, on_error, &result);
return result;
}
std::string DebugString() const { return vtable_->debug_string(value_); }
absl::string_view key() const { return vtable_->key(value_); }
// TODO(ctiller): move to transport
static uint32_t TransportSize(uint32_t key_size, uint32_t value_size) {
@ -197,11 +202,11 @@ class ParsedMetadata {
grpc_error_handle (*const set)(const Buffer& value,
MetadataContainer* container);
// result is a bitwise copy of the originating ParsedMetadata.
void (*const with_new_value)(Slice* new_value, ParsedMetadata* result);
void (*const with_new_value)(Slice* new_value,
MetadataParseErrorFn on_error,
ParsedMetadata* result);
std::string (*const debug_string)(const Buffer& value);
// TODO(ctiller): when we delete mdelem, make this a simple integer constant
// on the vtable
size_t (*const key_length)(const Buffer& value);
absl::string_view (*const key)(const Buffer& value);
};
static const VTable* EmptyVTable();
@ -214,17 +219,18 @@ class ParsedMetadata {
template <bool kIsBinaryHeader>
static const VTable* MdelemVtable();
template <Slice (*ParseMemento)(Slice)>
template <Slice (*ParseMemento)(Slice, MetadataParseErrorFn)>
GPR_ATTRIBUTE_NOINLINE static void WithNewValueSetSlice(
Slice* slice, ParsedMetadata* result) {
result->value_.slice = ParseMemento(std::move(*slice)).TakeCSlice();
Slice* slice, MetadataParseErrorFn on_error, ParsedMetadata* result) {
result->value_.slice =
ParseMemento(std::move(*slice), on_error).TakeCSlice();
}
template <typename T, T (*ParseMemento)(Slice)>
template <typename T, T (*ParseMemento)(Slice, MetadataParseErrorFn)>
GPR_ATTRIBUTE_NOINLINE static void WithNewValueSetTrivial(
Slice* slice, ParsedMetadata* result) {
Slice* slice, MetadataParseErrorFn on_error, ParsedMetadata* result) {
result->value_.trivial =
static_cast<uint64_t>(ParseMemento(std::move(*slice)));
static_cast<uint64_t>(ParseMemento(std::move(*slice), on_error));
}
const VTable* vtable_;
@ -244,11 +250,11 @@ ParsedMetadata<MetadataContainer>::EmptyVTable() {
// set
[](const Buffer&, MetadataContainer*) { return GRPC_ERROR_NONE; },
// with_new_value
[](Slice*, ParsedMetadata*) {},
[](Slice*, MetadataParseErrorFn, ParsedMetadata*) {},
// debug_string
[](const Buffer&) -> std::string { return "empty"; },
// key_length
[](const Buffer&) -> size_t { return 0; },
// key
[](const Buffer&) -> absl::string_view { return ""; },
};
return &vtable;
}
@ -277,8 +283,8 @@ ParsedMetadata<MetadataContainer>::TrivialTraitVTable() {
metadata_detail::FieldFromTrivial<typename Which::MementoType>,
Which::DisplayValue);
},
// key_length
[](const Buffer&) { return Which::key().size(); },
// key
[](const Buffer&) { return Which::key(); },
};
return &vtable;
}
@ -300,9 +306,9 @@ ParsedMetadata<MetadataContainer>::NonTrivialTraitVTable() {
return GRPC_ERROR_NONE;
},
// with_new_value
[](Slice* value, ParsedMetadata* result) {
result->value_.pointer = new
typename Which::MementoType(Which::ParseMemento(std::move(*value)));
[](Slice* value, MetadataParseErrorFn on_error, ParsedMetadata* result) {
result->value_.pointer = new typename Which::MementoType(
Which::ParseMemento(std::move(*value), on_error));
},
// debug_string
[](const Buffer& value) {
@ -311,8 +317,8 @@ ParsedMetadata<MetadataContainer>::NonTrivialTraitVTable() {
metadata_detail::FieldFromPointer<typename Which::MementoType>,
Which::DisplayValue);
},
// key_length
[](const Buffer&) { return Which::key().size(); },
// key
[](const Buffer&) { return Which::key(); },
};
return &vtable;
}
@ -339,8 +345,8 @@ ParsedMetadata<MetadataContainer>::SliceTraitVTable() {
Which::key(), value, metadata_detail::SliceFromBuffer,
Which::DisplayValue);
},
// key_length
[](const Buffer&) { return Which::key().size(); },
// key
[](const Buffer&) { return Which::key(); },
};
return &vtable;
}
@ -365,7 +371,7 @@ ParsedMetadata<MetadataContainer>::MdelemVtable() {
return err;
},
// with_new_value
[](Slice* value_slice, ParsedMetadata* result) {
[](Slice* value_slice, MetadataParseErrorFn, ParsedMetadata* result) {
result->value_.mdelem = grpc_mdelem_from_slices(
static_cast<const ManagedMemorySlice&>(
grpc_slice_ref_internal(GRPC_MDKEY(result->value_.mdelem))),
@ -377,9 +383,9 @@ ParsedMetadata<MetadataContainer>::MdelemVtable() {
StringViewFromSlice(GRPC_MDKEY(value.mdelem)),
StringViewFromSlice(GRPC_MDVALUE(value.mdelem)));
},
// key_length
// key
[](const Buffer& value) {
return GRPC_SLICE_LENGTH(GRPC_MDKEY(value.mdelem));
return StringViewFromSlice(GRPC_MDKEY(value.mdelem));
}};
return &vtable;
}

@ -33,491 +33,485 @@
namespace grpc_core {
StaticMetadata g_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[3].base, 10,
g_static_metadata_bytes + 19),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[18].base, 10,
g_static_metadata_bytes + 492),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
0),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 7,
g_static_metadata_bytes + 5),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[24].base, 3,
g_static_metadata_bytes + 540),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[19].base, 7,
g_static_metadata_bytes + 502),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[20].base, 3,
g_static_metadata_bytes + 509),
1),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 7,
g_static_metadata_bytes + 5),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[25].base, 4,
g_static_metadata_bytes + 543),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[19].base, 7,
g_static_metadata_bytes + 502),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[21].base, 4,
g_static_metadata_bytes + 512),
2),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[0].base, 5,
g_static_metadata_bytes + 0),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[26].base, 1,
g_static_metadata_bytes + 547),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[22].base, 5,
g_static_metadata_bytes + 516),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[23].base, 1,
g_static_metadata_bytes + 521),
3),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[0].base, 5,
g_static_metadata_bytes + 0),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[27].base, 11,
g_static_metadata_bytes + 548),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[22].base, 5,
g_static_metadata_bytes + 516),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[24].base, 11,
g_static_metadata_bytes + 522),
4),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[4].base, 7,
g_static_metadata_bytes + 29),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[28].base, 4,
g_static_metadata_bytes + 559),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[25].base, 7,
g_static_metadata_bytes + 533),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[26].base, 4,
g_static_metadata_bytes + 540),
5),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[4].base, 7,
g_static_metadata_bytes + 29),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[29].base, 5,
g_static_metadata_bytes + 563),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[25].base, 7,
g_static_metadata_bytes + 533),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[27].base, 5,
g_static_metadata_bytes + 544),
6),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 7,
g_static_metadata_bytes + 12),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[30].base, 3,
g_static_metadata_bytes + 568),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[28].base, 7,
g_static_metadata_bytes + 549),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[29].base, 3,
g_static_metadata_bytes + 556),
7),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 7,
g_static_metadata_bytes + 12),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[31].base, 3,
g_static_metadata_bytes + 571),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[28].base, 7,
g_static_metadata_bytes + 549),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[30].base, 3,
g_static_metadata_bytes + 559),
8),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 7,
g_static_metadata_bytes + 12),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[32].base, 3,
g_static_metadata_bytes + 574),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[28].base, 7,
g_static_metadata_bytes + 549),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[31].base, 3,
g_static_metadata_bytes + 562),
9),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 7,
g_static_metadata_bytes + 12),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[33].base, 3,
g_static_metadata_bytes + 577),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[28].base, 7,
g_static_metadata_bytes + 549),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[32].base, 3,
g_static_metadata_bytes + 565),
10),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 7,
g_static_metadata_bytes + 12),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[34].base, 3,
g_static_metadata_bytes + 580),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[28].base, 7,
g_static_metadata_bytes + 549),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[33].base, 3,
g_static_metadata_bytes + 568),
11),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 7,
g_static_metadata_bytes + 12),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[35].base, 3,
g_static_metadata_bytes + 583),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[28].base, 7,
g_static_metadata_bytes + 549),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[34].base, 3,
g_static_metadata_bytes + 571),
12),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 7,
g_static_metadata_bytes + 12),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[36].base, 3,
g_static_metadata_bytes + 586),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[28].base, 7,
g_static_metadata_bytes + 549),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[35].base, 3,
g_static_metadata_bytes + 574),
13),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[37].base, 14,
g_static_metadata_bytes + 589),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[36].base, 14,
g_static_metadata_bytes + 577),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
14),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[9].base, 15,
g_static_metadata_bytes + 97),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[38].base, 13,
g_static_metadata_bytes + 603),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[3].base, 15,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[37].base, 13,
g_static_metadata_bytes + 591),
15),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[39].base, 15,
g_static_metadata_bytes + 616),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[38].base, 15,
g_static_metadata_bytes + 604),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
16),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[40].base, 13,
g_static_metadata_bytes + 631),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[39].base, 13,
g_static_metadata_bytes + 619),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
17),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[41].base, 6,
g_static_metadata_bytes + 644),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[40].base, 6,
g_static_metadata_bytes + 632),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
18),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[42].base, 27,
g_static_metadata_bytes + 650),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[41].base, 27,
g_static_metadata_bytes + 638),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
19),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[43].base, 3,
g_static_metadata_bytes + 677),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[42].base, 3,
g_static_metadata_bytes + 665),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
20),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[44].base, 5,
g_static_metadata_bytes + 680),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[43].base, 5,
g_static_metadata_bytes + 668),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
21),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[45].base, 13,
g_static_metadata_bytes + 685),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[44].base, 13,
g_static_metadata_bytes + 673),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
22),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[46].base, 13,
g_static_metadata_bytes + 698),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[45].base, 13,
g_static_metadata_bytes + 686),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
23),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[47].base, 19,
g_static_metadata_bytes + 711),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[46].base, 19,
g_static_metadata_bytes + 699),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
24),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[8].base, 16,
g_static_metadata_bytes + 81),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 16,
g_static_metadata_bytes + 33),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
25),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[48].base, 16,
g_static_metadata_bytes + 730),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[47].base, 16,
g_static_metadata_bytes + 718),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
26),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[49].base, 14,
g_static_metadata_bytes + 746),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[48].base, 14,
g_static_metadata_bytes + 734),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
27),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[50].base, 16,
g_static_metadata_bytes + 760),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[49].base, 16,
g_static_metadata_bytes + 748),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
28),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[51].base, 13,
g_static_metadata_bytes + 776),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[50].base, 13,
g_static_metadata_bytes + 764),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
29),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[7].base, 12,
g_static_metadata_bytes + 69),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[51].base, 12,
g_static_metadata_bytes + 777),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
30),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[52].base, 6,
g_static_metadata_bytes + 789),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
31),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[53].base, 4,
g_static_metadata_bytes + 795),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
32),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[54].base, 4,
g_static_metadata_bytes + 799),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
33),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[55].base, 6,
g_static_metadata_bytes + 803),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
34),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[56].base, 7,
g_static_metadata_bytes + 809),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
35),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[57].base, 4,
g_static_metadata_bytes + 816),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
36),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[58].base, 4,
g_static_metadata_bytes + 820),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
37),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[59].base, 8,
g_static_metadata_bytes + 824),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
38),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[60].base, 17,
g_static_metadata_bytes + 832),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
39),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[61].base, 13,
g_static_metadata_bytes + 849),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
40),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[62].base, 8,
g_static_metadata_bytes + 862),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
41),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[63].base, 19,
g_static_metadata_bytes + 870),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
42),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[64].base, 13,
g_static_metadata_bytes + 889),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
43),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[65].base, 4,
g_static_metadata_bytes + 902),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
44),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[66].base, 8,
g_static_metadata_bytes + 906),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
45),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[67].base, 12,
g_static_metadata_bytes + 914),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
46),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[68].base, 18,
g_static_metadata_bytes + 926),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
47),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[69].base, 19,
g_static_metadata_bytes + 944),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
48),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[70].base, 5,
g_static_metadata_bytes + 963),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
49),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[71].base, 7,
g_static_metadata_bytes + 968),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
50),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[72].base, 7,
g_static_metadata_bytes + 975),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
51),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[73].base, 11,
g_static_metadata_bytes + 982),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
52),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[74].base, 6,
g_static_metadata_bytes + 993),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
53),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[75].base, 10,
g_static_metadata_bytes + 999),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
54),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[76].base, 25,
g_static_metadata_bytes + 1009),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
55),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[77].base, 17,
g_static_metadata_bytes + 1034),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
56),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[78].base, 10,
g_static_metadata_bytes + 1051),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
57),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[79].base, 4,
g_static_metadata_bytes + 1061),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
58),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[80].base, 3,
g_static_metadata_bytes + 1065),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
59),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[81].base, 16,
g_static_metadata_bytes + 1068),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
60),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[5].base, 13,
g_static_metadata_bytes + 36),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[0].base, 13,
g_static_metadata_bytes + 0),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[82].base, 8,
g_static_metadata_bytes + 1084),
61),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[5].base, 13,
g_static_metadata_bytes + 36),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[20].base, 4,
g_static_metadata_bytes + 515),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[0].base, 13,
g_static_metadata_bytes + 0),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[14].base, 4,
g_static_metadata_bytes + 467),
62),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[5].base, 13,
g_static_metadata_bytes + 36),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[19].base, 7,
g_static_metadata_bytes + 508),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[0].base, 13,
g_static_metadata_bytes + 0),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[13].base, 7,
g_static_metadata_bytes + 460),
63),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[7].base, 12,
g_static_metadata_bytes + 69),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[83].base, 16,
StaticMetadataSlice(&g_static_metadata_slice_refcounts[25].base, 7,
g_static_metadata_bytes + 533),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[83].base, 4,
g_static_metadata_bytes + 1092),
64),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[4].base, 7,
g_static_metadata_bytes + 29),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[84].base, 4,
g_static_metadata_bytes + 1108),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[19].base, 7,
g_static_metadata_bytes + 502),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[84].base, 3,
g_static_metadata_bytes + 1096),
65),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 7,
g_static_metadata_bytes + 5),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[85].base, 3,
g_static_metadata_bytes + 1112),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[3].base, 15,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
66),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[9].base, 15,
g_static_metadata_bytes + 97),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
67),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[8].base, 16,
g_static_metadata_bytes + 81),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 16,
g_static_metadata_bytes + 33),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[82].base, 8,
g_static_metadata_bytes + 1084),
67),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[2].base, 16,
g_static_metadata_bytes + 33),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[14].base, 4,
g_static_metadata_bytes + 467),
68),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[8].base, 16,
g_static_metadata_bytes + 81),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[20].base, 4,
g_static_metadata_bytes + 515),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[85].base, 11,
g_static_metadata_bytes + 1099),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 0,
g_static_metadata_bytes + 106),
69),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[86].base, 11,
g_static_metadata_bytes + 1115),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[12].base, 0,
g_static_metadata_bytes + 154),
70),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 20,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 20,
g_static_metadata_bytes + 13),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[82].base, 8,
g_static_metadata_bytes + 1084),
70),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 20,
g_static_metadata_bytes + 13),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[13].base, 7,
g_static_metadata_bytes + 460),
71),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 20,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[19].base, 7,
g_static_metadata_bytes + 508),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 20,
g_static_metadata_bytes + 13),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[86].base, 16,
g_static_metadata_bytes + 1110),
72),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 20,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[87].base, 16,
g_static_metadata_bytes + 1126),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 20,
g_static_metadata_bytes + 13),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[14].base, 4,
g_static_metadata_bytes + 467),
73),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 20,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[20].base, 4,
g_static_metadata_bytes + 515),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 20,
g_static_metadata_bytes + 13),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[87].base, 13,
g_static_metadata_bytes + 1126),
74),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 20,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[88].base, 13,
g_static_metadata_bytes + 1142),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 20,
g_static_metadata_bytes + 13),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[88].base, 12,
g_static_metadata_bytes + 1139),
75),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 20,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[89].base, 12,
g_static_metadata_bytes + 1155),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[1].base, 20,
g_static_metadata_bytes + 13),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[89].base, 21,
g_static_metadata_bytes + 1151),
76),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[6].base, 20,
StaticMetadataSlice(&g_static_metadata_slice_refcounts[3].base, 15,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[90].base, 21,
g_static_metadata_bytes + 1167),
77),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[9].base, 15,
g_static_metadata_bytes + 97),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[82].base, 8,
g_static_metadata_bytes + 1084),
77),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[3].base, 15,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[14].base, 4,
g_static_metadata_bytes + 467),
78),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[9].base, 15,
g_static_metadata_bytes + 97),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[20].base, 4,
g_static_metadata_bytes + 515),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[3].base, 15,
g_static_metadata_bytes + 49),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[87].base, 13,
g_static_metadata_bytes + 1126),
79),
StaticMetadata(
StaticMetadataSlice(&g_static_metadata_slice_refcounts[9].base, 15,
g_static_metadata_bytes + 97),
StaticMetadataSlice(&g_static_metadata_slice_refcounts[88].base, 13,
g_static_metadata_bytes + 1142),
80),
};
/* Warning: the core static metadata currently operates under the soft
@ -849,112 +843,107 @@ grpc_mdelem g_static_mdelem_manifested[GRPC_STATIC_MDELEM_COUNT] = {
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[63].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC:
"content-type": "application/grpc" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[64].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_SCHEME_GRPC:
":scheme": "grpc" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[65].data(),
&g_static_mdelem_table[64].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_METHOD_PUT:
":method": "PUT" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[66].data(),
&g_static_mdelem_table[65].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_ACCEPT_ENCODING_EMPTY:
"accept-encoding": "" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[67].data(),
&g_static_mdelem_table[66].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_CONTENT_ENCODING_IDENTITY:
"content-encoding": "identity" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[68].data(),
&g_static_mdelem_table[67].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_CONTENT_ENCODING_GZIP:
"content-encoding": "gzip" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[69].data(),
&g_static_mdelem_table[68].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_LB_COST_BIN_EMPTY:
"lb-cost-bin": "" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[70].data(),
&g_static_mdelem_table[69].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY:
"grpc-accept-encoding": "identity" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[71].data(),
&g_static_mdelem_table[70].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE:
"grpc-accept-encoding": "deflate" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[72].data(),
&g_static_mdelem_table[71].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE:
"grpc-accept-encoding": "identity,deflate" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[73].data(),
&g_static_mdelem_table[72].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP:
"grpc-accept-encoding": "gzip" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[74].data(),
&g_static_mdelem_table[73].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP:
"grpc-accept-encoding": "identity,gzip" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[75].data(),
&g_static_mdelem_table[74].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP:
"grpc-accept-encoding": "deflate,gzip" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[76].data(),
&g_static_mdelem_table[75].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP:
"grpc-accept-encoding": "identity,deflate,gzip" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[77].data(),
&g_static_mdelem_table[76].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY:
"accept-encoding": "identity" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[78].data(),
&g_static_mdelem_table[77].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_ACCEPT_ENCODING_GZIP:
"accept-encoding": "gzip" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[79].data(),
&g_static_mdelem_table[78].data(),
GRPC_MDELEM_STORAGE_STATIC),
/* GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP:
"accept-encoding": "identity,gzip" */
GRPC_MAKE_MDELEM(
&g_static_mdelem_table[80].data(),
&g_static_mdelem_table[79].data(),
GRPC_MDELEM_STORAGE_STATIC)
// clang-format on
};
} // namespace grpc_core
uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4};
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4};
static const int8_t elems_r[] = {
15, 10, -8, 0, 2, 15, 2, 20, 12, 5, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, -39, 0, -41, -42, -43, -44, -45, -46,
-47, -48, -49, -50, -51, -52, -52, 0, 36, 35, 34, 33, 32, 31, 30,
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
14, 13, 12, 11, 10, 9, 8, 7, 0, 0, 0, 0, -2, 0};
10, -2, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, -10, -32, -1, 0, -39, 0, 0, -46, -11, 0, -70, 0,
0, 0, 0, 0, 0, 0, -43, 0, -46, -47, -48, -49, -50, -51, -52,
-53, -54, -54, 0, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23,
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8,
7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, -7, 0};
static uint32_t elems_phash(uint32_t i) {
i -= 26;
uint32_t x = i % 89;
uint32_t y = i / 89;
i -= 13;
uint32_t x = i % 88;
uint32_t y = i / 88;
uint32_t h = x;
if (y < GPR_ARRAY_SIZE(elems_r)) {
uint32_t delta = static_cast<uint32_t>(elems_r[y]);
@ -964,25 +953,25 @@ static uint32_t elems_phash(uint32_t i) {
}
static const uint16_t elem_keys[] = {
212, 213, 214, 215, 216, 217, 218, 565, 566, 831, 115, 116,
392, 393, 740, 26, 27, 839, 474, 475, 649, 3379, 748, 3561,
3652, 3743, 3834, 3925, 4016, 4107, 4198, 4289, 4380, 4471, 4562, 857,
4653, 4744, 4835, 4926, 5017, 5108, 5199, 5290, 5381, 5472, 5563, 5654,
5745, 5836, 5927, 6018, 6109, 6200, 6291, 6382, 6473, 6564, 6655, 6746,
6837, 6928, 7019, 7110, 7201, 7292, 7383, 7838, 448, 0, 628, 176,
0, 285, 0, 633, 634, 635, 636, 901, 0, 537, 0, 0,
810, 907, 0, 0, 0, 0, 0, 720};
103, 104, 2549, 2550, 2551, 2552, 2553, 2554, 2555, 284, 13, 14,
194, 1730, 1731, 2003, 2004, 2276, 2277, 1626, 1794, 2333, 3246, 3426,
3516, 3606, 3696, 3786, 3876, 3966, 4056, 4146, 307, 4236, 4326, 4416,
4506, 4596, 4686, 4776, 4866, 4956, 5046, 5136, 5226, 5316, 5406, 5496,
5586, 5676, 5766, 5856, 5946, 6036, 6126, 6216, 6306, 6396, 6486, 6576,
6666, 6756, 6846, 6936, 7026, 7116, 7206, 7296, 7656, 172, 0, 0,
0, 176, 177, 178, 179, 352, 0, 82, 262, 0, 357, 186,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276};
static const uint8_t elem_idxs[] = {
7, 8, 9, 10, 11, 12, 13, 72, 74, 67, 1, 2, 5, 6, 25, 3,
4, 79, 63, 62, 30, 14, 69, 16, 17, 18, 19, 20, 21, 22, 23, 24,
26, 27, 28, 15, 29, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
58, 59, 60, 70, 65, 255, 71, 66, 255, 0, 255, 73, 75, 76, 77, 78,
255, 61, 255, 255, 68, 80, 255, 255, 255, 255, 255, 64};
71, 73, 7, 8, 9, 10, 11, 12, 13, 78, 63, 62, 68, 1, 2, 3,
4, 5, 6, 0, 65, 64, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24,
15, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
57, 58, 59, 60, 69, 70, 255, 255, 255, 72, 74, 75, 76, 77, 255, 61,
67, 255, 79, 25, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 66};
grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b) {
if (a == -1 || b == -1) return GRPC_MDNULL;
uint32_t k = static_cast<uint32_t>(a * 91 + b);
uint32_t k = static_cast<uint32_t>(a * 90 + b);
uint32_t h = elems_phash(k);
return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k &&
elem_idxs[h] != 255
@ -992,7 +981,7 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b) {
: GRPC_MDNULL;
}
const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 71, 72, 73,
74, 75, 76, 77};
const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 70, 71, 72,
73, 74, 75, 76};
const uint8_t grpc_static_accept_stream_encoding_metadata[4] = {0, 78, 79, 80};
const uint8_t grpc_static_accept_stream_encoding_metadata[4] = {0, 77, 78, 79};

@ -34,7 +34,7 @@
#include "src/core/lib/slice/static_slice.h"
#include "src/core/lib/transport/metadata.h"
#define GRPC_STATIC_MDELEM_COUNT 81
#define GRPC_STATIC_MDELEM_COUNT 80
namespace grpc_core {
extern StaticMetadata g_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
@ -201,66 +201,57 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
/* "grpc-encoding": "deflate" */
#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \
(::grpc_core::g_static_mdelem_manifested[63])
/* "content-type": "application/grpc" */
#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \
(::grpc_core::g_static_mdelem_manifested[64])
/* ":scheme": "grpc" */
#define GRPC_MDELEM_SCHEME_GRPC (::grpc_core::g_static_mdelem_manifested[65])
#define GRPC_MDELEM_SCHEME_GRPC (::grpc_core::g_static_mdelem_manifested[64])
/* ":method": "PUT" */
#define GRPC_MDELEM_METHOD_PUT (::grpc_core::g_static_mdelem_manifested[66])
#define GRPC_MDELEM_METHOD_PUT (::grpc_core::g_static_mdelem_manifested[65])
/* "accept-encoding": "" */
#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \
(::grpc_core::g_static_mdelem_manifested[67])
(::grpc_core::g_static_mdelem_manifested[66])
/* "content-encoding": "identity" */
#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \
(::grpc_core::g_static_mdelem_manifested[68])
(::grpc_core::g_static_mdelem_manifested[67])
/* "content-encoding": "gzip" */
#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \
(::grpc_core::g_static_mdelem_manifested[69])
(::grpc_core::g_static_mdelem_manifested[68])
/* "lb-cost-bin": "" */
#define GRPC_MDELEM_LB_COST_BIN_EMPTY \
(::grpc_core::g_static_mdelem_manifested[70])
(::grpc_core::g_static_mdelem_manifested[69])
/* "grpc-accept-encoding": "identity" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \
(::grpc_core::g_static_mdelem_manifested[71])
(::grpc_core::g_static_mdelem_manifested[70])
/* "grpc-accept-encoding": "deflate" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \
(::grpc_core::g_static_mdelem_manifested[72])
(::grpc_core::g_static_mdelem_manifested[71])
/* "grpc-accept-encoding": "identity,deflate" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \
(::grpc_core::g_static_mdelem_manifested[73])
(::grpc_core::g_static_mdelem_manifested[72])
/* "grpc-accept-encoding": "gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \
(::grpc_core::g_static_mdelem_manifested[74])
(::grpc_core::g_static_mdelem_manifested[73])
/* "grpc-accept-encoding": "identity,gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \
(::grpc_core::g_static_mdelem_manifested[75])
(::grpc_core::g_static_mdelem_manifested[74])
/* "grpc-accept-encoding": "deflate,gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \
(::grpc_core::g_static_mdelem_manifested[76])
(::grpc_core::g_static_mdelem_manifested[75])
/* "grpc-accept-encoding": "identity,deflate,gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
(::grpc_core::g_static_mdelem_manifested[77])
(::grpc_core::g_static_mdelem_manifested[76])
/* "accept-encoding": "identity" */
#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \
(::grpc_core::g_static_mdelem_manifested[78])
(::grpc_core::g_static_mdelem_manifested[77])
/* "accept-encoding": "gzip" */
#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \
(::grpc_core::g_static_mdelem_manifested[79])
(::grpc_core::g_static_mdelem_manifested[78])
/* "accept-encoding": "identity,gzip" */
#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \
(::grpc_core::g_static_mdelem_manifested[80])
(::grpc_core::g_static_mdelem_manifested[79])
grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b);
typedef enum {
GRPC_BATCH_PATH,
GRPC_BATCH_METHOD,
GRPC_BATCH_STATUS,
GRPC_BATCH_AUTHORITY,
GRPC_BATCH_SCHEME,
GRPC_BATCH_GRPC_ENCODING,
GRPC_BATCH_GRPC_ACCEPT_ENCODING,
GRPC_BATCH_CONTENT_TYPE,
GRPC_BATCH_CONTENT_ENCODING,
GRPC_BATCH_ACCEPT_ENCODING,
GRPC_BATCH_GRPC_INTERNAL_ENCODING_REQUEST,
@ -270,14 +261,8 @@ typedef enum {
typedef union {
struct grpc_linked_mdelem* array[GRPC_BATCH_CALLOUTS_COUNT];
struct {
struct grpc_linked_mdelem* path;
struct grpc_linked_mdelem* method;
struct grpc_linked_mdelem* status;
struct grpc_linked_mdelem* authority;
struct grpc_linked_mdelem* scheme;
struct grpc_linked_mdelem* grpc_encoding;
struct grpc_linked_mdelem* grpc_accept_encoding;
struct grpc_linked_mdelem* content_type;
struct grpc_linked_mdelem* content_encoding;
struct grpc_linked_mdelem* accept_encoding;
struct grpc_linked_mdelem* grpc_internal_encoding_request;

@ -717,11 +717,11 @@ alts_handshaker_client* alts_grpc_handshaker_client_create(
channel, nullptr, GRPC_PROPAGATE_DEFAULTS, interested_parties,
grpc_slice_from_static_string(ALTS_SERVICE_METHOD), &slice,
GRPC_MILLIS_INF_FUTURE, nullptr);
grpc_slice_unref_internal(slice);
GRPC_CLOSURE_INIT(&client->on_handshaker_service_resp_recv, grpc_cb, client,
grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&client->on_status_received, on_status_received, client,
grpc_schedule_on_exec_ctx);
grpc_slice_unref_internal(slice);
return &client->base;
}

@ -199,7 +199,7 @@ void OpenCensusCallTracer::OpenCensusCallAttemptTracer::RecordEnd(
OpenCensusCallTracer::OpenCensusCallTracer(const grpc_call_element_args* args)
: call_context_(args->context),
path_(grpc_slice_ref_internal(args->path)),
method_(GetMethod(&path_)),
method_(GetMethod(path_)),
arena_(args->arena) {}
OpenCensusCallTracer::~OpenCensusCallTracer() {
@ -211,7 +211,6 @@ OpenCensusCallTracer::~OpenCensusCallTracer() {
{RpcClientTransparentRetriesPerCall(), transparent_retries_},
{RpcClientRetryDelayPerCall(), ToDoubleMilliseconds(retry_delay_)}},
tags);
grpc_slice_unref_internal(path_);
}
void OpenCensusCallTracer::GenerateContext() {

@ -126,15 +126,12 @@ uint64_t GetOutgoingDataSize(const grpc_call_final_info* final_info);
// Returns a string representation of the StatusCode enum.
absl::string_view StatusCodeToString(grpc_status_code code);
inline absl::string_view GetMethod(const grpc_slice* path) {
if (GRPC_SLICE_IS_EMPTY(*path)) {
inline absl::string_view GetMethod(const grpc_core::Slice& path) {
if (path.empty()) {
return "";
}
// Check for leading '/' and trim it if present.
return absl::StripPrefix(absl::string_view(reinterpret_cast<const char*>(
GRPC_SLICE_START_PTR(*path)),
GRPC_SLICE_LENGTH(*path)),
"/");
return absl::StripPrefix(path.as_string_view(), "/");
}
} // namespace grpc

@ -84,7 +84,7 @@ class OpenCensusCallTracer : public grpc_core::CallTracer {
private:
const grpc_call_context_element* call_context_;
// Client method.
grpc_slice path_;
grpc_core::Slice path_;
absl::string_view method_;
CensusContext context_;
grpc_core::Arena* arena_;

@ -38,16 +38,16 @@ namespace {
// server metadata elements
struct ServerMetadataElements {
grpc_slice path;
grpc_core::Slice path;
grpc_core::Slice tracing_slice;
grpc_core::Slice census_proto;
};
void FilterInitialMetadata(grpc_metadata_batch* b,
ServerMetadataElements* sml) {
if (b->legacy_index()->named.path != nullptr) {
sml->path = grpc_slice_ref_internal(
GRPC_MDVALUE(b->legacy_index()->named.path->md));
const auto* path = b->get_pointer(grpc_core::HttpPathMetadata());
if (path != nullptr) {
sml->path = path->Ref();
}
auto grpc_trace_bin = b->Take(grpc_core::GrpcTraceBinMetadata());
if (grpc_trace_bin.has_value()) {
@ -88,14 +88,12 @@ void CensusServerCallData::OnDoneRecvInitialMetadataCb(
grpc_metadata_batch* initial_metadata = calld->recv_initial_metadata_;
GPR_ASSERT(initial_metadata != nullptr);
ServerMetadataElements sml;
sml.path = grpc_empty_slice();
FilterInitialMetadata(initial_metadata, &sml);
calld->path_ = grpc_slice_ref_internal(sml.path);
calld->method_ = GetMethod(&calld->path_);
calld->path_ = std::move(sml.path);
calld->method_ = GetMethod(calld->path_);
calld->qualified_method_ = absl::StrCat("Recv.", calld->method_);
GenerateServerContext(sml.tracing_slice.as_string_view(),
calld->qualified_method_, &calld->context_);
grpc_slice_unref_internal(sml.path);
grpc_census_call_set_context(
calld->gc_, reinterpret_cast<census_context*>(&calld->context_));
}
@ -166,7 +164,6 @@ void CensusServerCallData::Destroy(grpc_call_element* /*elem*/,
{RpcServerReceivedMessagesPerRpc(), recv_message_count_}},
{{ServerMethodTagKey(), method_},
{ServerStatusTagKey(), StatusCodeToString(final_info->final_status)}});
grpc_slice_unref_internal(path_);
context_.EndSpan();
}

@ -51,7 +51,6 @@ class CensusServerCallData : public CallData {
recv_message_count_(0),
sent_message_count_(0) {
memset(&census_bin_, 0, sizeof(grpc_linked_mdelem));
memset(&path_, 0, sizeof(grpc_slice));
memset(&on_done_recv_initial_metadata_, 0, sizeof(grpc_closure));
memset(&on_done_recv_message_, 0, sizeof(grpc_closure));
}
@ -75,7 +74,7 @@ class CensusServerCallData : public CallData {
// server method
absl::string_view method_;
std::string qualified_method_;
grpc_slice path_;
grpc_core::Slice path_;
// Pointer to the grpc_call element
grpc_call* gc_;
// Authorization context for the call.

@ -1,12 +1,6 @@
# hpack fuzzing dictionary
"\x05:path"
"\x07:method"
"\x07:status"
"\x0A:authority"
"\x07:scheme"
"\x0Dgrpc-encoding"
"\x14grpc-accept-encoding"
"\x0Ccontent-type"
"\x10content-encoding"
"\x0Faccept-encoding"
"\x1Egrpc-internal-encoding-request"
@ -23,12 +17,17 @@
"\x0Bstream/gzip"
"\x02te"
"\x08trailers"
"\x0A:authority"
"\x07:method"
"\x03GET"
"\x04POST"
"\x05:path"
"\x01/"
"\x0B/index.html"
"\x07:scheme"
"\x04http"
"\x05https"
"\x07:status"
"\x03200"
"\x03204"
"\x03206"
@ -51,6 +50,7 @@
"\x0Econtent-length"
"\x10content-location"
"\x0Dcontent-range"
"\x0Ccontent-type"
"\x06cookie"
"\x04date"
"\x04etag"
@ -82,7 +82,6 @@
"\x03via"
"\x10www-authenticate"
"\x08identity"
"\x10application/grpc"
"\x04grpc"
"\x03PUT"
"\x0Blb-cost-bin"
@ -154,7 +153,6 @@
"\x00\x0Dgrpc-encoding\x08identity"
"\x00\x0Dgrpc-encoding\x04gzip"
"\x00\x0Dgrpc-encoding\x07deflate"
"\x00\x0Ccontent-type\x10application/grpc"
"\x00\x07:scheme\x04grpc"
"\x00\x07:method\x03PUT"
"\x00\x0Faccept-encoding\x00"

@ -266,11 +266,10 @@ static void server_start_transport_stream_op_batch(
if (data->call == g_server_call_stack) {
if (op->send_initial_metadata) {
auto* batch = op->payload->send_initial_metadata.send_initial_metadata;
if (batch->legacy_index()->named.status != nullptr) {
auto* status = batch->get_pointer(grpc_core::HttpStatusMetadata());
if (status != nullptr) {
/* Replace the HTTP status with 404 */
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"Substitute", batch->Substitute(batch->legacy_index()->named.status,
GRPC_MDELEM_STATUS_404)));
*status = 404;
}
}
}

@ -166,7 +166,8 @@ static void test_retry_exceeds_buffer_size_in_delay(
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
grpc_slice status_details = grpc_slice_from_static_string("xyz");
grpc_slice status_details1 = grpc_slice_from_static_string("message1");
grpc_slice status_details2 = grpc_slice_from_static_string("message2");
// Client sends initial metadata and starts the recv ops.
memset(ops, 0, sizeof(ops));
@ -215,7 +216,7 @@ static void test_retry_exceeds_buffer_size_in_delay(
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
op->data.send_status_from_server.status_details = &status_details;
op->data.send_status_from_server.status_details = &status_details1;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
@ -269,7 +270,7 @@ static void test_retry_exceeds_buffer_size_in_delay(
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
op->data.send_status_from_server.status_details = &status_details;
op->data.send_status_from_server.status_details = &status_details2;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
@ -282,7 +283,7 @@ static void test_retry_exceeds_buffer_size_in_delay(
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "message2"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 0);

@ -163,7 +163,8 @@ static void test_retry_server_pushback_delay(grpc_end2end_test_config config) {
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
grpc_slice status_details = grpc_slice_from_static_string("xyz");
grpc_slice status_details1 = grpc_slice_from_static_string("message1");
grpc_slice status_details2 = grpc_slice_from_static_string("message2");
memset(ops, 0, sizeof(ops));
op = ops;
@ -215,7 +216,7 @@ static void test_retry_server_pushback_delay(grpc_end2end_test_config config) {
op->data.send_status_from_server.trailing_metadata_count = 1;
op->data.send_status_from_server.trailing_metadata = &pushback_md;
op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
op->data.send_status_from_server.status_details = &status_details;
op->data.send_status_from_server.status_details = &status_details1;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
@ -270,7 +271,7 @@ static void test_retry_server_pushback_delay(grpc_end2end_test_config config) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
op->data.send_status_from_server.status_details = &status_details;
op->data.send_status_from_server.status_details = &status_details2;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
@ -284,7 +285,7 @@ static void test_retry_server_pushback_delay(grpc_end2end_test_config config) {
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "message2"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 0);

@ -132,14 +132,42 @@ void MockCallback(void* arg, grpc_error_handle error) {
}
}
std::string MetadataString(const Metadata& a) {
return absl::StrCat(
"{",
absl::StrJoin(
a, ", ",
[](std::string* out, const std::pair<std::string, std::string>& kv) {
out->append(
absl::StrCat("\"", kv.first, "\": \"", kv.second, "\""));
}),
"}");
}
bool MetadataEquivalent(Metadata a, Metadata b) {
std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end());
return a == b;
}
// Matches with transactions having the desired flag, method_ref,
// initial_metadata, and message_data.
MATCHER_P4(TransactionMatches, flag, method_ref, initial_metadata, message_data,
"") {
if (arg.GetFlags() != flag) return false;
if (flag & kFlagPrefix) {
if (arg.GetMethodRef() != method_ref) return false;
if (arg.GetPrefixMetadata() != initial_metadata) return false;
if (arg.GetMethodRef() != method_ref) {
printf("METHOD REF NOT EQ: %s %s\n",
std::string(arg.GetMethodRef()).c_str(),
std::string(method_ref).c_str());
return false;
}
if (!MetadataEquivalent(arg.GetPrefixMetadata(), initial_metadata)) {
printf("METADATA NOT EQUIVALENT: %s %s\n",
MetadataString(arg.GetPrefixMetadata()).c_str(),
MetadataString(initial_metadata).c_str());
return false;
}
}
if (flag & kFlagMessageData) {
if (arg.GetMessageData() != message_data) return false;
@ -181,33 +209,24 @@ void VerifyMetadataEqual(const Metadata& md,
const grpc_metadata_batch& grpc_md) {
MetadataEncoder encoder;
grpc_md.Encode(&encoder);
EXPECT_EQ(encoder.metadata(), md);
EXPECT_TRUE(MetadataEquivalent(encoder.metadata(), md));
}
// RAII helper classes for constructing gRPC metadata and receiving callbacks.
struct MakeSendInitialMetadata {
MakeSendInitialMetadata(const Metadata& initial_metadata,
const std::string& method_ref,
grpc_transport_stream_op_batch* op)
: storage(initial_metadata.size()) {
size_t i = 0;
grpc_transport_stream_op_batch* op) {
for (const auto& md : initial_metadata) {
const std::string& key = md.first;
const std::string& value = md.second;
EXPECT_EQ(grpc_metadata_batch_add_tail(
&grpc_initial_metadata, &storage[i],
grpc_mdelem_from_slices(grpc_slice_from_cpp_string(key),
grpc_slice_from_cpp_string(value))),
GRPC_ERROR_NONE);
i++;
grpc_initial_metadata.Append(
key, grpc_core::Slice::FromCopiedString(value),
[](absl::string_view, const grpc_core::Slice&) { abort(); });
}
if (!method_ref.empty()) {
EXPECT_EQ(
grpc_metadata_batch_add_tail(
&grpc_initial_metadata, &method_ref_storage,
grpc_mdelem_from_slices(GRPC_MDSTR_PATH,
grpc_slice_from_cpp_string(method_ref))),
GRPC_ERROR_NONE);
grpc_initial_metadata.Set(grpc_core::HttpPathMetadata(),
grpc_core::Slice::FromCopiedString(method_ref));
}
op->send_initial_metadata = true;
op->payload->send_initial_metadata.send_initial_metadata =
@ -215,8 +234,6 @@ struct MakeSendInitialMetadata {
}
~MakeSendInitialMetadata() {}
std::vector<grpc_linked_mdelem> storage;
grpc_linked_mdelem method_ref_storage;
grpc_core::ScopedArenaPtr arena =
grpc_core::MakeScopedArena(1024, g_memory_allocator);
grpc_metadata_batch grpc_initial_metadata{arena.get()};

@ -122,8 +122,9 @@ class ParseTest : public ::testing::TestWithParam<Test> {
}
template <typename T, typename V>
void Encode(T, const V&) {
abort(); // not implemented
void Encode(T, const V& v) {
out_.append(
absl::StrCat(T::key(), ": ", T::Encode(v).as_string_view(), "\n"));
}
private:
@ -169,24 +170,24 @@ INSTANTIATE_TEST_SUITE_P(
/* D.3.1 */
{"8286 8441 0f77 7777 2e65 7861 6d70 6c65"
"2e63 6f6d",
":method: GET\n"
":scheme: http\n"
":path: /\n"
":authority: www.example.com\n"},
":authority: www.example.com\n"
":method: GET\n"
":scheme: http\n"},
/* D.3.2 */
{"8286 84be 5808 6e6f 2d63 6163 6865",
":method: GET\n"
":scheme: http\n"
":path: /\n"
":authority: www.example.com\n"
":method: GET\n"
":scheme: http\n"
"cache-control: no-cache\n"},
/* D.3.3 */
{"8287 85bf 400a 6375 7374 6f6d 2d6b 6579"
"0c63 7573 746f 6d2d 7661 6c75 65",
":method: GET\n"
":scheme: https\n"
":path: /index.html\n"
":authority: www.example.com\n"
":method: GET\n"
":scheme: https\n"
"custom-key: custom-value\n"},
}},
Test{{},
@ -194,24 +195,24 @@ INSTANTIATE_TEST_SUITE_P(
/* D.4.1 */
{"8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4"
"ff",
":method: GET\n"
":scheme: http\n"
":path: /\n"
":authority: www.example.com\n"},
":authority: www.example.com\n"
":method: GET\n"
":scheme: http\n"},
/* D.4.2 */
{"8286 84be 5886 a8eb 1064 9cbf",
":method: GET\n"
":scheme: http\n"
":path: /\n"
":authority: www.example.com\n"
":method: GET\n"
":scheme: http\n"
"cache-control: no-cache\n"},
/* D.4.3 */
{"8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925"
"a849 e95b b8e8 b4bf",
":method: GET\n"
":scheme: https\n"
":path: /index.html\n"
":authority: www.example.com\n"
":method: GET\n"
":scheme: https\n"
"custom-key: custom-value\n"},
}},
Test{{256},

@ -32,7 +32,9 @@ struct CharTrait {
static char test_value() { return 'a'; }
static size_t test_memento_transport_size() { return 34; }
static char MementoToValue(char memento) { return memento; }
static char ParseMemento(Slice slice) { return slice[0]; }
static char ParseMemento(Slice slice, MetadataParseErrorFn) {
return slice[0];
}
static std::string DisplayValue(char value) { return std::string(1, value); }
};
@ -43,7 +45,7 @@ struct Int32Trait {
static int32_t test_value() { return -1; }
static size_t test_memento_transport_size() { return 478; }
static int32_t MementoToValue(int32_t memento) { return memento; }
static int32_t ParseMemento(Slice slice) {
static int32_t ParseMemento(Slice slice, MetadataParseErrorFn) {
int32_t out;
GPR_ASSERT(absl::SimpleAtoi(slice.as_string_view(), &out));
return out;
@ -60,7 +62,7 @@ struct Int64Trait {
static int64_t test_value() { return -83481847284179298; }
static size_t test_memento_transport_size() { return 87; }
static int64_t MementoToValue(int64_t memento) { return -memento; }
static int64_t ParseMemento(Slice slice) {
static int64_t ParseMemento(Slice slice, MetadataParseErrorFn) {
int64_t out;
GPR_ASSERT(absl::SimpleAtoi(slice.as_string_view(), &out));
return out;
@ -77,7 +79,7 @@ struct IntptrTrait {
static intptr_t test_value() { return test_memento() / 2; }
static size_t test_memento_transport_size() { return 800; }
static intptr_t MementoToValue(intptr_t memento) { return memento / 2; }
static intptr_t ParseMemento(Slice slice) {
static intptr_t ParseMemento(Slice slice, MetadataParseErrorFn) {
intptr_t out;
GPR_ASSERT(absl::SimpleAtoi(slice.as_string_view(), &out));
return out;
@ -96,7 +98,7 @@ struct StringTrait {
static std::string MementoToValue(std::string memento) {
return "hi " + memento;
}
static std::string ParseMemento(Slice slice) {
static std::string ParseMemento(Slice slice, MetadataParseErrorFn) {
auto view = slice.as_string_view();
return std::string(view.begin(), view.end());
}

@ -34,7 +34,11 @@ class EvaluateArgsTestUtil {
void AddPairToMetadata(const char* key, const char* value) {
metadata_.Append(
key, Slice(grpc_slice_intern(grpc_slice_from_static_string(value))));
key, Slice(grpc_slice_intern(grpc_slice_from_static_string(value))),
[](absl::string_view, const Slice&) {
// We should never ever see an error here.
abort();
});
}
void SetLocalEndpoint(absl::string_view local_uri) {

@ -25,6 +25,7 @@
#include <benchmark/benchmark.h>
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@ -262,30 +263,26 @@ class RepresentativeClientInitialMetadata {
public:
static constexpr bool kEnableTrueBinary = true;
static void Prepare(grpc_metadata_batch* b) {
GPR_ASSERT(GRPC_LOG_IF_ERROR("addmd", b->Append(GRPC_MDELEM_SCHEME_HTTP)));
GPR_ASSERT(GRPC_LOG_IF_ERROR("addmd", b->Append(GRPC_MDELEM_METHOD_POST)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd",
b->Append(grpc_mdelem_from_slices(
GRPC_MDSTR_PATH,
grpc_slice_intern(grpc_slice_from_static_string("/foo/bar"))))));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd", b->Append(grpc_mdelem_from_slices(
GRPC_MDSTR_AUTHORITY,
grpc_slice_intern(grpc_slice_from_static_string(
"foo.test.google.fr:1234"))))));
b->Set(grpc_core::HttpSchemeMetadata(),
grpc_core::HttpSchemeMetadata::kHttp);
b->Set(grpc_core::HttpMethodMetadata(),
grpc_core::HttpMethodMetadata::kPost);
b->Set(
grpc_core::HttpPathMetadata(),
grpc_core::Slice(grpc_core::StaticSlice::FromStaticString("/foo/bar")));
b->Set(grpc_core::HttpAuthorityMetadata(),
grpc_core::Slice(grpc_core::StaticSlice::FromStaticString(
"foo.test.google.fr:1234")));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd",
b->Append(
GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP)));
b->Set(grpc_core::TeMetadata(), grpc_core::TeMetadata::kTrailers);
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd", b->Append(GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd", b->Append(grpc_mdelem_from_slices(
GRPC_MDSTR_USER_AGENT,
grpc_slice_intern(grpc_slice_from_static_string(
"grpc-c/3.0.0-dev (linux; chttp2; green)"))))));
b->Set(grpc_core::ContentTypeMetadata(),
grpc_core::ContentTypeMetadata::kApplicationGrpc);
b->Set(grpc_core::UserAgentMetadata(),
grpc_core::Slice(grpc_core::StaticSlice::FromStaticString(
"grpc-c/3.0.0-dev (linux; chttp2; green)")));
}
};
@ -296,18 +293,16 @@ class MoreRepresentativeClientInitialMetadata {
public:
static constexpr bool kEnableTrueBinary = true;
static void Prepare(grpc_metadata_batch* b) {
GPR_ASSERT(GRPC_LOG_IF_ERROR("addmd", b->Append(GRPC_MDELEM_SCHEME_HTTP)));
GPR_ASSERT(GRPC_LOG_IF_ERROR("addmd", b->Append(GRPC_MDELEM_METHOD_POST)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd",
b->Append(grpc_mdelem_from_slices(
GRPC_MDSTR_PATH, grpc_slice_intern(grpc_slice_from_static_string(
"/grpc.test.FooService/BarMethod"))))));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd", b->Append(grpc_mdelem_from_slices(
GRPC_MDSTR_AUTHORITY,
grpc_slice_intern(grpc_slice_from_static_string(
"foo.test.google.fr:1234"))))));
b->Set(grpc_core::HttpSchemeMetadata(),
grpc_core::HttpSchemeMetadata::kHttp);
b->Set(grpc_core::HttpMethodMetadata(),
grpc_core::HttpMethodMetadata::kPost);
b->Set(grpc_core::HttpPathMetadata(),
grpc_core::Slice(grpc_core::StaticSlice::FromStaticString(
"/grpc.test.FooService/BarMethod")));
b->Set(grpc_core::HttpAuthorityMetadata(),
grpc_core::Slice(grpc_core::StaticSlice::FromStaticString(
"foo.test.google.fr:1234")));
b->Set(grpc_core::GrpcTraceBinMetadata(),
grpc_core::Slice(grpc_core::StaticSlice::FromStaticString(
"\x00\x01\x02\x03\x04\x05\x06\x07\x08"
@ -327,13 +322,11 @@ class MoreRepresentativeClientInitialMetadata {
b->Append(
GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP)));
b->Set(grpc_core::TeMetadata(), grpc_core::TeMetadata::kTrailers);
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd", b->Append(GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd", b->Append(grpc_mdelem_from_slices(
GRPC_MDSTR_USER_AGENT,
grpc_slice_intern(grpc_slice_from_static_string(
"grpc-c/3.0.0-dev (linux; chttp2; green)"))))));
b->Set(grpc_core::ContentTypeMetadata(),
grpc_core::ContentTypeMetadata::kApplicationGrpc);
b->Set(grpc_core::UserAgentMetadata(),
grpc_core::Slice(grpc_core::StaticSlice::FromStaticString(
"grpc-c/3.0.0-dev (linux; chttp2; green)")));
}
};
@ -341,9 +334,9 @@ class RepresentativeServerInitialMetadata {
public:
static constexpr bool kEnableTrueBinary = true;
static void Prepare(grpc_metadata_batch* b) {
GPR_ASSERT(GRPC_LOG_IF_ERROR("addmd", b->Append(GRPC_MDELEM_STATUS_200)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd", b->Append(GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)));
b->Set(grpc_core::HttpStatusMetadata(), 200);
b->Set(grpc_core::ContentTypeMetadata(),
grpc_core::ContentTypeMetadata::kApplicationGrpc);
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd",
b->Append(
@ -468,9 +461,9 @@ BENCHMARK(BM_HpackParserInitDestroy);
template <class Fixture>
static void BM_HpackParserParseHeader(benchmark::State& state) {
TrackCounters track_counters;
grpc_core::ExecCtx exec_ctx;
std::vector<grpc_slice> init_slices = Fixture::GetInitSlices();
std::vector<grpc_slice> benchmark_slices = Fixture::GetBenchmarkSlices();
grpc_core::ExecCtx exec_ctx;
grpc_core::HPackParser p;
const int kArenaSize = 4096 * 4096;
auto* arena = grpc_core::Arena::Create(kArenaSize, g_memory_allocator);
@ -481,14 +474,16 @@ static void BM_HpackParserParseHeader(benchmark::State& state) {
grpc_core::HPackParser::Priority::None,
grpc_core::HPackParser::LogInfo{
1, grpc_core::HPackParser::LogInfo::kHeaders, false});
for (auto slice : init_slices) {
GPR_ASSERT(GRPC_ERROR_NONE == p.Parse(slice, false));
}
auto parse_vec = [&p](const std::vector<grpc_slice>& slices) {
for (size_t i = 0; i < slices.size(); ++i) {
auto error = p.Parse(slices[i], i == slices.size() - 1);
GPR_ASSERT(error == GRPC_ERROR_NONE);
}
};
parse_vec(init_slices);
while (state.KeepRunning()) {
b->Clear();
for (auto slice : benchmark_slices) {
GPR_ASSERT(GRPC_ERROR_NONE == p.Parse(slice, false));
}
parse_vec(benchmark_slices);
grpc_core::ExecCtx::Get()->Flush();
// Recreate arena every 4k iterations to avoid oom
if (0 == (state.iterations() & 0xfff)) {
@ -514,6 +509,57 @@ static void BM_HpackParserParseHeader(benchmark::State& state) {
namespace hpack_parser_fixtures {
template <class EncoderFixture>
class FromEncoderFixture {
public:
static std::vector<grpc_slice> GetInitSlices() { return Generate(0); }
static std::vector<grpc_slice> GetBenchmarkSlices() { return Generate(1); }
private:
static std::vector<grpc_slice> Generate(int iteration) {
grpc_core::ExecCtx exec_ctx;
auto arena = grpc_core::MakeScopedArena(1024, g_memory_allocator);
grpc_metadata_batch b(arena.get());
EncoderFixture::Prepare(&b);
grpc_core::HPackCompressor c;
grpc_transport_one_way_stats stats;
std::vector<grpc_slice> out;
stats = {};
bool done = false;
int i = 0;
while (!done) {
grpc_slice_buffer outbuf;
grpc_slice_buffer_init(&outbuf);
c.EncodeHeaders(
grpc_core::HPackCompressor::EncodeHeaderOptions{
static_cast<uint32_t>(i),
false,
EncoderFixture::kEnableTrueBinary,
1024 * 1024,
&stats,
},
b, &outbuf);
if (i == iteration) {
for (size_t s = 0; s < outbuf.count; s++) {
out.push_back(grpc_slice_ref_internal(outbuf.slices[s]));
}
done = true;
}
grpc_slice_buffer_reset_and_unref_internal(&outbuf);
grpc_core::ExecCtx::Get()->Flush();
grpc_slice_buffer_destroy_internal(&outbuf);
i++;
}
// Remove the HTTP header.
GPR_ASSERT(!out.empty());
GPR_ASSERT(GRPC_SLICE_LENGTH(out[0]) > 9);
out[0] = grpc_slice_sub_no_ref(out[0], 9, GRPC_SLICE_LENGTH(out[0]));
return out;
}
};
class EmptyBatch {
public:
static std::vector<grpc_slice> GetInitSlices() { return {}; }
@ -549,7 +595,7 @@ class KeyIndexedSingleStaticElem {
{0x40, 0x07, ':', 's', 't', 'a', 't', 'u', 's', 0x03, '2', '0', '0'})};
}
static std::vector<grpc_slice> GetBenchmarkSlices() {
return {MakeSlice({0x7e, 0x03, 'd', 'e', 'f'})};
return {MakeSlice({0x7e, 0x03, '4', '0', '4'})};
}
};
@ -671,135 +717,14 @@ class NonIndexedBinaryElem<100, false> {
}
};
class RepresentativeClientInitialMetadata {
public:
static std::vector<grpc_slice> GetInitSlices() {
return {grpc_slice_from_static_string(
// generated with:
// ```
// tools/codegen/core/gen_header_frame.py --compression inc --no_framing
// < test/core/bad_client/tests/simple_request.headers
// ```
"@\x05:path\x08/foo/bar"
"@\x07:scheme\x04http"
"@\x07:method\x04POST"
"@\x0a:authority\x09localhost"
"@\x0c"
"content-type\x10"
"application/grpc"
"@\x14grpc-accept-encoding\x15identity,deflate,gzip"
"@\x02te\x08trailers"
"@\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)")};
}
static std::vector<grpc_slice> GetBenchmarkSlices() {
// generated with:
// ```
// tools/codegen/core/gen_header_frame.py --compression pre --no_framing
// --hex < test/core/bad_client/tests/simple_request.headers
// ```
return {MakeSlice({0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0, 0xbf, 0xbe})};
}
};
// This fixture reflects how initial metadata are sent by a production client,
// with non-indexed :path and binary headers. The metadata here are the same as
// the corresponding encoder benchmark above.
class MoreRepresentativeClientInitialMetadata {
public:
static std::vector<grpc_slice> GetInitSlices() {
return {MakeSlice(
{0x40, 0x07, ':', 's', 'c', 'h', 'e', 'm', 'e', 0x04, 'h', 't',
't', 'p', 0x40, 0x07, ':', 'm', 'e', 't', 'h', 'o', 'd', 0x04,
'P', 'O', 'S', 'T', 0x40, 0x05, ':', 'p', 'a', 't', 'h', 0x1f,
'/', 'g', 'r', 'p', 'c', '.', 't', 'e', 's', 't', '.', 'F',
'o', 'o', 'S', 'e', 'r', 'v', 'i', 'c', 'e', '/', 'B', 'a',
'r', 'M', 'e', 't', 'h', 'o', 'd', 0x40, 0x0a, ':', 'a', 'u',
't', 'h', 'o', 'r', 'i', 't', 'y', 0x09, 'l', 'o', 'c', 'a',
'l', 'h', 'o', 's', 't', 0x40, 0x0e, 'g', 'r', 'p', 'c', '-',
't', 'r', 'a', 'c', 'e', '-', 'b', 'i', 'n', 0x31, 0x00, 0x01,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x40,
0x0d, 'g', 'r', 'p', 'c', '-', 't', 'a', 'g', 's', '-', 'b',
'i', 'n', 0x14, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x40,
0x0c, 'c', 'o', 'n', 't', 'e', 'n', 't', '-', 't', 'y', 'p',
'e', 0x10, 'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o',
'n', '/', 'g', 'r', 'p', 'c', 0x40, 0x14, 'g', 'r', 'p', 'c',
'-', 'a', 'c', 'c', 'e', 'p', 't', '-', 'e', 'n', 'c', 'o',
'd', 'i', 'n', 'g', 0x15, 'i', 'd', 'e', 'n', 't', 'i', 't',
'y', ',', 'd', 'e', 'f', 'l', 'a', 't', 'e', ',', 'g', 'z',
'i', 'p', 0x40, 0x02, 't', 'e', 0x08, 't', 'r', 'a', 'i', 'l',
'e', 'r', 's', 0x40, 0x0a, 'u', 's', 'e', 'r', '-', 'a', 'g',
'e', 'n', 't', 0x22, 'b', 'a', 'd', '-', 'c', 'l', 'i', 'e',
'n', 't', ' ', 'g', 'r', 'p', 'c', '-', 'c', '/', '0', '.',
'1', '2', '.', '0', '.', '0', ' ', '(', 'l', 'i', 'n', 'u',
'x', ')'})};
}
static std::vector<grpc_slice> GetBenchmarkSlices() {
return {MakeSlice({
0xc7, 0xc6, 0xc5, 0xc4, 0x7f, 0x04, 0x31, 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
})};
}
};
class RepresentativeServerInitialMetadata {
public:
static std::vector<grpc_slice> GetInitSlices() {
return {grpc_slice_from_static_string(
// generated with:
// ```
// tools/codegen/core/gen_header_frame.py --compression inc --no_framing
// <
// test/cpp/microbenchmarks/representative_server_initial_metadata.headers
// ```
"@\x07:status\x03"
"200"
"@\x0c"
"content-type\x10"
"application/grpc"
"@\x14grpc-accept-encoding\x15identity,deflate,gzip")};
}
static std::vector<grpc_slice> GetBenchmarkSlices() {
// generated with:
// ```
// tools/codegen/core/gen_header_frame.py --compression pre --no_framing
// --hex <
// test/cpp/microbenchmarks/representative_server_initial_metadata.headers
// ```
return {MakeSlice({0xc0, 0xbf, 0xbe})};
}
};
class RepresentativeServerTrailingMetadata {
public:
static std::vector<grpc_slice> GetInitSlices() {
return {grpc_slice_from_static_string(
// generated with:
// ```
// tools/codegen/core/gen_header_frame.py --compression inc --no_framing
// <
// test/cpp/microbenchmarks/representative_server_trailing_metadata.headers
// ```
"@\x0bgrpc-status\x01"
"0"
"@\x0cgrpc-message\x00")};
}
static std::vector<grpc_slice> GetBenchmarkSlices() {
// generated with:
// ```
// tools/codegen/core/gen_header_frame.py --compression pre --no_framing
// --hex <
// test/cpp/microbenchmarks/representative_server_trailing_metadata.headers
// ```
return {MakeSlice({0xbf, 0xbe})};
}
};
using RepresentativeClientInitialMetadata = FromEncoderFixture<
hpack_encoder_fixtures::RepresentativeClientInitialMetadata>;
using RepresentativeServerInitialMetadata = FromEncoderFixture<
hpack_encoder_fixtures::RepresentativeServerInitialMetadata>;
using RepresentativeServerTrailingMetadata = FromEncoderFixture<
hpack_encoder_fixtures::RepresentativeServerTrailingMetadata>;
using MoreRepresentativeClientInitialMetadata = FromEncoderFixture<
hpack_encoder_fixtures::MoreRepresentativeClientInitialMetadata>;
// Send the same deadline repeatedly
class SameDeadline {

@ -294,30 +294,26 @@ BENCHMARK(BM_StreamCreateDestroy);
class RepresentativeClientInitialMetadata {
public:
static void Prepare(grpc_metadata_batch* b) {
GPR_ASSERT(GRPC_LOG_IF_ERROR("addmd", b->Append(GRPC_MDELEM_SCHEME_HTTP)));
GPR_ASSERT(GRPC_LOG_IF_ERROR("addmd", b->Append(GRPC_MDELEM_METHOD_POST)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd",
b->Append(grpc_mdelem_from_slices(
GRPC_MDSTR_PATH, grpc_slice_intern(grpc_slice_from_static_string(
"/foo/bar/bm_chttp2_transport"))))));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd", b->Append(grpc_mdelem_from_slices(
GRPC_MDSTR_AUTHORITY,
grpc_slice_intern(grpc_slice_from_static_string(
"foo.test.google.fr:1234"))))));
b->Set(grpc_core::HttpSchemeMetadata(),
grpc_core::HttpSchemeMetadata::kHttp);
b->Set(grpc_core::HttpMethodMetadata(),
grpc_core::HttpMethodMetadata::kPost);
b->Set(grpc_core::HttpPathMetadata(),
grpc_core::Slice(grpc_core::StaticSlice::FromStaticString(
"/foo/bar/bm_chttp2_transport")));
b->Set(grpc_core::HttpAuthorityMetadata(),
grpc_core::Slice(grpc_core::StaticSlice::FromStaticString(
"foo.test.google.fr:1234")));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd",
b->Append(
GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP)));
b->Set(grpc_core::TeMetadata(), grpc_core::TeMetadata::kTrailers);
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd", b->Append(GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"addmd", b->Append(grpc_mdelem_from_slices(
GRPC_MDSTR_USER_AGENT,
grpc_slice_intern(grpc_slice_from_static_string(
"grpc-c/3.0.0-dev (linux; chttp2; green)"))))));
b->Set(grpc_core::ContentTypeMetadata(),
grpc_core::ContentTypeMetadata::kApplicationGrpc);
b->Set(grpc_core::UserAgentMetadata(),
grpc_core::Slice(grpc_core::StaticSlice::FromStaticString(
"grpc-c/3.0.0-dev (linux; chttp2; green)")));
}
};

@ -1,4 +0,0 @@
:status: 200
content-type: application/grpc
grpc-accept-encoding: identity,deflate,gzip

@ -36,10 +36,8 @@ import perfection
CONFIG = [
# metadata strings
'grpc-internal-encoding-request',
':path',
'grpc-encoding',
'grpc-accept-encoding',
':authority',
'grpc-timeout',
'',
# well known method names
@ -123,7 +121,6 @@ CONFIG = [
('grpc-encoding', 'identity'),
('grpc-encoding', 'gzip'),
('grpc-encoding', 'deflate'),
('content-type', 'application/grpc'),
(':scheme', 'grpc'),
(':method', 'PUT'),
('accept-encoding', ''),
@ -135,14 +132,8 @@ CONFIG = [
# All entries here are ignored when counting non-default initial metadata that
# prevents the chttp2 server from sending a Trailers-Only response.
METADATA_BATCH_CALLOUTS = [
':path',
':method',
':status',
':authority',
':scheme',
'grpc-encoding',
'grpc-accept-encoding',
'content-type',
'content-encoding',
'accept-encoding',
'grpc-internal-encoding-request',

Loading…
Cancel
Save