Remove metadata context from the channel stack

pull/4188/head
Craig Tiller 9 years ago
parent f6e40fd2aa
commit ebdef9d674
  1. 3
      BUILD
  2. 1
      build.yaml
  3. 2
      gRPC.podspec
  4. 3
      src/core/channel/client_channel.c
  5. 6
      src/core/channel/client_uchannel.c
  6. 3
      src/core/channel/client_uchannel.h
  7. 62
      src/core/channel/compress_filter.c
  8. 150
      src/core/channel/http_client_filter.c
  9. 104
      src/core/channel/http_server_filter.c
  10. 15
      src/core/channel/subchannel_call_holder.c
  11. 4
      src/core/channel/subchannel_call_holder.h
  12. 34
      src/core/client_config/subchannel.c
  13. 7
      src/core/client_config/subchannel.h
  14. 50
      src/core/compression/algorithm.c
  15. 53
      src/core/compression/algorithm_metadata.h
  16. 47
      src/core/surface/call.c
  17. 141
      src/core/surface/channel.c
  18. 6
      src/core/surface/channel.h
  19. 12
      src/core/surface/lame_client.c
  20. 13
      src/core/surface/server.c
  21. 97
      src/core/transport/metadata.c
  22. 21
      src/core/transport/metadata.h
  23. 23
      src/core/transport/static_metadata.c
  24. 275
      src/core/transport/static_metadata.h
  25. 4
      test/core/channel/channel_stack_test.c
  26. 4
      test/core/end2end/fixtures/h2_uchannel.c
  27. 1
      test/core/transport/chttp2/hpack_parser_test.c
  28. 6
      test/core/transport/metadata_test.c
  29. 7
      tools/codegen/core/gen_static_metadata.py
  30. 1
      tools/doxygen/Doxyfile.core.internal
  31. 4
      tools/run_tests/run_tests.py
  32. 4
      tools/run_tests/sources_and_headers.json
  33. 1
      vsprojects/vcxproj/grpc/grpc.vcxproj
  34. 3
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  35. 1
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  36. 3
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters

@ -178,6 +178,7 @@ cc_library(
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
"src/core/debug/trace.h",
"src/core/httpcli/format_request.h",
@ -470,6 +471,7 @@ cc_library(
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
"src/core/debug/trace.h",
"src/core/httpcli/format_request.h",
@ -1269,6 +1271,7 @@ objc_library(
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
"src/core/debug/trace.h",
"src/core/httpcli/format_request.h",

@ -134,6 +134,7 @@ filegroups:
- src/core/client_config/subchannel_factory_decorators/add_channel_arg.h
- src/core/client_config/subchannel_factory_decorators/merge_channel_args.h
- src/core/client_config/uri_parser.h
- src/core/compression/algorithm_metadata.h
- src/core/compression/message_compress.h
- src/core/debug/trace.h
- src/core/httpcli/format_request.h

@ -182,6 +182,7 @@ Pod::Spec.new do |s|
'src/core/client_config/subchannel_factory_decorators/add_channel_arg.h',
'src/core/client_config/subchannel_factory_decorators/merge_channel_args.h',
'src/core/client_config/uri_parser.h',
'src/core/compression/algorithm_metadata.h',
'src/core/compression/message_compress.h',
'src/core/debug/trace.h',
'src/core/httpcli/format_request.h',
@ -480,6 +481,7 @@ Pod::Spec.new do |s|
'src/core/client_config/subchannel_factory_decorators/add_channel_arg.h',
'src/core/client_config/subchannel_factory_decorators/merge_channel_args.h',
'src/core/client_config/uri_parser.h',
'src/core/compression/algorithm_metadata.h',
'src/core/compression/message_compress.h',
'src/core/debug/trace.h',
'src/core/httpcli/format_request.h',

@ -364,7 +364,8 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
/* Constructor for call_data */
static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_call_element_args *args) {
grpc_subchannel_call_holder_init(elem->call_data, cc_pick_subchannel, elem);
grpc_subchannel_call_holder_init(elem->call_data, cc_pick_subchannel, elem,
args->metadata_context);
}
/* Destructor for call_data */

@ -140,7 +140,7 @@ static int cuc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *arg,
static void cuc_init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_call_element_args *args) {
grpc_subchannel_call_holder_init(elem->call_data, cuc_pick_subchannel,
elem->channel_data);
elem->channel_data, args->metadata_context);
}
/* Destructor for call_data */
@ -244,11 +244,11 @@ void grpc_client_uchannel_del_interested_party(grpc_exec_ctx *exec_ctx,
}
grpc_channel *grpc_client_uchannel_create(grpc_subchannel *subchannel,
grpc_channel_args *args) {
grpc_channel_args *args,
grpc_mdctx *mdctx) {
grpc_channel *channel = NULL;
#define MAX_FILTERS 3
const grpc_channel_filter *filters[MAX_FILTERS];
grpc_mdctx *mdctx = grpc_subchannel_get_mdctx(subchannel);
grpc_channel *master = grpc_subchannel_get_master(subchannel);
char *target = grpc_channel_get_target(master);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

@ -62,7 +62,8 @@ void grpc_client_uchannel_del_interested_party(grpc_exec_ctx *exec_ctx,
grpc_pollset *pollset);
grpc_channel *grpc_client_uchannel_create(grpc_subchannel *subchannel,
grpc_channel_args *args);
grpc_channel_args *args,
grpc_mdctx *mdctx);
void grpc_client_uchannel_set_subchannel(grpc_channel *uchannel,
grpc_subchannel *subchannel);

@ -42,6 +42,7 @@
#include "src/core/channel/compress_filter.h"
#include "src/core/channel/channel_args.h"
#include "src/core/profiling/timers.h"
#include "src/core/compression/algorithm_metadata.h"
#include "src/core/compression/message_compress.h"
#include "src/core/support/string.h"
#include "src/core/transport/static_metadata.h"
@ -65,6 +66,8 @@ typedef struct call_data {
grpc_closure *post_send;
grpc_closure send_done;
grpc_closure got_slice;
grpc_mdctx *mdctx;
} call_data;
typedef struct channel_data {
@ -72,6 +75,8 @@ typedef struct channel_data {
grpc_compression_algorithm default_compression_algorithm;
/** Compression options for the channel */
grpc_compression_options compression_options;
/** Supported compression algorithms */
gpr_uint32 supported_compression_algorithms;
} channel_data;
/** For each \a md element from the incoming metadata, filter out the entry for
@ -82,7 +87,7 @@ static grpc_mdelem *compression_md_filter(void *user_data, grpc_mdelem *md) {
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
if (md->key == GRPC_MDSTR_GRPC_ENCODING) {
if (md->key == GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST) {
const char *md_c_str = grpc_mdstr_as_c_string(md->value);
if (!grpc_compression_algorithm_parse(md_c_str, strlen(md_c_str),
&calld->compression_algorithm)) {
@ -138,14 +143,13 @@ static void process_send_initial_metadata(
/* hint compression algorithm */
grpc_metadata_batch_add_tail(
initial_metadata, &calld->compression_algorithm_storage,
GRPC_MDELEM_REF(
channeld
->mdelem_compression_algorithms[calld->compression_algorithm]));
grpc_compression_encoding_mdelem(calld->compression_algorithm));
/* convey supported compression algorithms */
grpc_metadata_batch_add_tail(
initial_metadata, &calld->accept_encoding_storage,
GRPC_MDELEM_REF(channeld->mdelem_accept_encoding));
GRPC_MDELEM_REF(grpc_accept_encoding_mdelem_from_compression_algorithms(
calld->mdctx, channeld->supported_compression_algorithms)));
}
static void continue_send_message(grpc_exec_ctx *exec_ctx,
@ -239,6 +243,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
/* initialize members */
gpr_slice_buffer_init(&calld->slices);
calld->has_compression_algorithm = 0;
calld->mdctx = args->metadata_context;
grpc_closure_init(&calld->got_slice, got_slice, elem);
grpc_closure_init(&calld->send_done, send_done, elem);
}
@ -257,10 +262,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element_args *args) {
channel_data *channeld = elem->channel_data;
grpc_compression_algorithm algo_idx;
const char *supported_algorithms_names[GRPC_COMPRESS_ALGORITHMS_COUNT - 1];
size_t supported_algorithms_idx = 0;
char *accept_encoding_str;
size_t accept_encoding_str_len;
grpc_compression_options_init(&channeld->compression_options);
channeld->compression_options.enabled_algorithms_bitset =
@ -275,61 +276,22 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
channeld->compression_options.default_compression_algorithm =
channeld->default_compression_algorithm;
channeld->mdstr_request_compression_algorithm_key = grpc_mdstr_from_string(
args->metadata_context, GRPC_COMPRESS_REQUEST_ALGORITHM_KEY);
channeld->mdstr_outgoing_compression_algorithm_key =
grpc_mdstr_from_string(args->metadata_context, "grpc-encoding");
channeld->mdstr_compression_capabilities_key =
grpc_mdstr_from_string(args->metadata_context, "grpc-accept-encoding");
channeld->supported_compression_algorithms = 0;
for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
char *algorithm_name;
/* skip disabled algorithms */
if (grpc_compression_options_is_algorithm_enabled(
&channeld->compression_options, algo_idx) == 0) {
continue;
}
GPR_ASSERT(grpc_compression_algorithm_name(algo_idx, &algorithm_name) != 0);
channeld->mdelem_compression_algorithms[algo_idx] =
grpc_mdelem_from_metadata_strings(
args->metadata_context,
GRPC_MDSTR_REF(channeld->mdstr_outgoing_compression_algorithm_key),
grpc_mdstr_from_string(args->metadata_context, algorithm_name));
if (algo_idx > 0) {
supported_algorithms_names[supported_algorithms_idx++] = algorithm_name;
}
channeld->supported_compression_algorithms |= 1u << algo_idx;
}
/* TODO(dgq): gpr_strjoin_sep could be made to work with statically allocated
* arrays, as to avoid the heap allocs */
accept_encoding_str =
gpr_strjoin_sep(supported_algorithms_names, supported_algorithms_idx, ",",
&accept_encoding_str_len);
channeld->mdelem_accept_encoding = grpc_mdelem_from_metadata_strings(
args->metadata_context,
GRPC_MDSTR_REF(channeld->mdstr_compression_capabilities_key),
grpc_mdstr_from_string(args->metadata_context, accept_encoding_str));
gpr_free(accept_encoding_str);
GPR_ASSERT(!args->is_last);
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
channel_data *channeld = elem->channel_data;
grpc_compression_algorithm algo_idx;
GRPC_MDSTR_UNREF(channeld->mdstr_request_compression_algorithm_key);
GRPC_MDSTR_UNREF(channeld->mdstr_outgoing_compression_algorithm_key);
GRPC_MDSTR_UNREF(channeld->mdstr_compression_capabilities_key);
for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
GRPC_MDELEM_UNREF(channeld->mdelem_compression_algorithms[algo_idx]);
}
GRPC_MDELEM_UNREF(channeld->mdelem_accept_encoding);
}
const grpc_channel_filter grpc_compress_filter = {

@ -37,6 +37,7 @@
#include <grpc/support/string_util.h>
#include "src/core/support/string.h"
#include "src/core/profiling/timers.h"
#include "src/core/transport/static_metadata.h"
typedef struct call_data {
grpc_linked_mdelem method;
@ -54,17 +55,11 @@ typedef struct call_data {
up-call on transport_op, and remember to call our on_done_recv member
after handling it. */
grpc_closure hc_on_recv;
grpc_mdctx *mdctx;
} call_data;
typedef struct channel_data {
grpc_mdelem *te_trailers;
grpc_mdelem *method;
grpc_mdelem *scheme;
grpc_mdelem *content_type;
grpc_mdelem *status;
/** complete user agent mdelem */
grpc_mdelem *user_agent;
} channel_data;
typedef struct channel_data { grpc_mdelem *static_scheme; } channel_data;
typedef struct {
grpc_call_element *elem;
@ -73,14 +68,12 @@ typedef struct {
static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) {
client_recv_filter_args *a = user_data;
grpc_call_element *elem = a->elem;
channel_data *channeld = elem->channel_data;
if (md == channeld->status) {
if (md == GRPC_MDELEM_STATUS_200) {
return NULL;
} else if (md->key == channeld->status->key) {
grpc_call_element_send_cancel(a->exec_ctx, elem);
} else if (md->key == GRPC_MDSTR_STATUS) {
grpc_call_element_send_cancel(a->exec_ctx, a->elem);
return NULL;
} else if (md->key == channeld->content_type->key) {
} else if (md->key == GRPC_MDSTR_CONTENT_TYPE) {
return NULL;
}
return md;
@ -98,14 +91,12 @@ static void hc_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, int success) {
}
static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
grpc_call_element *elem = user_data;
channel_data *channeld = elem->channel_data;
/* eat the things we'd like to set ourselves */
if (md->key == channeld->method->key) return NULL;
if (md->key == channeld->scheme->key) return NULL;
if (md->key == channeld->te_trailers->key) return NULL;
if (md->key == channeld->content_type->key) return NULL;
if (md->key == channeld->user_agent->key) return NULL;
if (md->key == GRPC_MDSTR_METHOD) return NULL;
if (md->key == GRPC_MDSTR_SCHEME) return NULL;
if (md->key == GRPC_MDSTR_TE) return NULL;
if (md->key == GRPC_MDSTR_CONTENT_TYPE) return NULL;
if (md->key == GRPC_MDSTR_USER_AGENT) return NULL;
return md;
}
@ -120,16 +111,18 @@ static void hc_mutate_op(grpc_call_element *elem,
/* Send : prefixed headers, which have to be before any application
layer headers. */
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
GRPC_MDELEM_REF(channeld->method));
GRPC_MDELEM_METHOD_POST);
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme,
GRPC_MDELEM_REF(channeld->scheme));
channeld->static_scheme);
grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers,
GRPC_MDELEM_REF(channeld->te_trailers));
grpc_metadata_batch_add_tail(op->send_initial_metadata,
&calld->content_type,
GRPC_MDELEM_REF(channeld->content_type));
grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->user_agent,
GRPC_MDELEM_REF(channeld->user_agent));
GRPC_MDELEM_TE_TRAILERS);
grpc_metadata_batch_add_tail(
op->send_initial_metadata, &calld->content_type,
GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC);
grpc_metadata_batch_add_tail(
op->send_initial_metadata, &calld->user_agent,
GRPC_MDELEM_REF(grpc_mdelem_from_cache(calld->mdctx,
GRPC_MDELEM_CACHED_USER_AGENT)));
}
if (op->recv_initial_metadata != NULL) {
@ -155,6 +148,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_call_element_args *args) {
call_data *calld = elem->call_data;
calld->on_done_recv = NULL;
calld->mdctx = args->metadata_context;
grpc_closure_init(&calld->hc_on_recv, hc_on_recv, elem);
}
@ -162,109 +156,39 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem) {}
static const char *scheme_from_args(const grpc_channel_args *args) {
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};
if (args != NULL) {
for (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) {
return args->args[i].value.string;
for (j = 0; j < GPR_ARRAY_SIZE(valid_schemes); j++) {
if (0 == strcmp(grpc_mdstr_as_c_string(valid_schemes[j]->value),
args->args[i].value.string)) {
return valid_schemes[j];
}
}
}
}
}
return "http";
}
static grpc_mdstr *user_agent_from_args(grpc_mdctx *mdctx,
const grpc_channel_args *args) {
gpr_strvec v;
size_t i;
int is_first = 1;
char *tmp;
grpc_mdstr *result;
gpr_strvec_init(&v);
for (i = 0; args && i < args->num_args; i++) {
if (0 == strcmp(args->args[i].key, GRPC_ARG_PRIMARY_USER_AGENT_STRING)) {
if (args->args[i].type != GRPC_ARG_STRING) {
gpr_log(GPR_ERROR, "Channel argument '%s' should be a string",
GRPC_ARG_PRIMARY_USER_AGENT_STRING);
} else {
if (!is_first) gpr_strvec_add(&v, gpr_strdup(" "));
is_first = 0;
gpr_strvec_add(&v, gpr_strdup(args->args[i].value.string));
}
}
}
gpr_asprintf(&tmp, "%sgrpc-c/%s (%s)", is_first ? "" : " ",
grpc_version_string(), GPR_PLATFORM_STRING);
is_first = 0;
gpr_strvec_add(&v, tmp);
for (i = 0; args && i < args->num_args; i++) {
if (0 == strcmp(args->args[i].key, GRPC_ARG_SECONDARY_USER_AGENT_STRING)) {
if (args->args[i].type != GRPC_ARG_STRING) {
gpr_log(GPR_ERROR, "Channel argument '%s' should be a string",
GRPC_ARG_SECONDARY_USER_AGENT_STRING);
} else {
if (!is_first) gpr_strvec_add(&v, gpr_strdup(" "));
is_first = 0;
gpr_strvec_add(&v, gpr_strdup(args->args[i].value.string));
}
}
}
tmp = gpr_strvec_flatten(&v, NULL);
gpr_strvec_destroy(&v);
result = grpc_mdstr_from_string(mdctx, tmp);
gpr_free(tmp);
return result;
return GRPC_MDELEM_SCHEME_HTTP;
}
/* Constructor for channel_data */
static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
/* grab pointers to our data from the channel element */
channel_data *channeld = elem->channel_data;
/* The first and the last filters tend to be implemented differently to
handle the case that there's no 'next' filter to call on the up or down
path */
channel_data *chand = elem->channel_data;
GPR_ASSERT(!args->is_last);
/* initialize members */
channeld->te_trailers =
grpc_mdelem_from_strings(args->metadata_context, "te", "trailers");
channeld->method =
grpc_mdelem_from_strings(args->metadata_context, ":method", "POST");
channeld->scheme = grpc_mdelem_from_strings(
args->metadata_context, ":scheme", scheme_from_args(args->channel_args));
channeld->content_type = grpc_mdelem_from_strings(
args->metadata_context, "content-type", "application/grpc");
channeld->status =
grpc_mdelem_from_strings(args->metadata_context, ":status", "200");
channeld->user_agent = grpc_mdelem_from_metadata_strings(
args->metadata_context,
grpc_mdstr_from_string(args->metadata_context, "user-agent"),
user_agent_from_args(args->metadata_context, args->channel_args));
chand->static_scheme = scheme_from_args(args->channel_args);
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
/* grab pointers to our data from the channel element */
channel_data *channeld = elem->channel_data;
GRPC_MDELEM_UNREF(channeld->te_trailers);
GRPC_MDELEM_UNREF(channeld->method);
GRPC_MDELEM_UNREF(channeld->scheme);
GRPC_MDELEM_UNREF(channeld->content_type);
GRPC_MDELEM_UNREF(channeld->status);
GRPC_MDELEM_UNREF(channeld->user_agent);
}
const grpc_channel_filter grpc_http_client_filter = {

@ -37,6 +37,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/profiling/timers.h"
#include "src/core/transport/static_metadata.h"
typedef struct call_data {
gpr_uint8 seen_path;
@ -55,24 +56,10 @@ typedef struct call_data {
up-call on transport_op, and remember to call our on_done_recv member
after handling it. */
grpc_closure hs_on_recv;
grpc_mdctx *mdctx;
} call_data;
typedef struct channel_data {
grpc_mdelem *te_trailers;
grpc_mdelem *method_post;
grpc_mdelem *http_scheme;
grpc_mdelem *https_scheme;
/* TODO(klempner): Remove this once we stop using it */
grpc_mdelem *grpc_scheme;
grpc_mdelem *content_type;
grpc_mdelem *status_ok;
grpc_mdelem *status_not_found;
grpc_mdstr *path_key;
grpc_mdstr *authority_key;
grpc_mdstr *host_key;
grpc_mdctx *mdctx;
} channel_data;
typedef struct channel_data { gpr_uint8 unused; } channel_data;
typedef struct {
grpc_call_element *elem;
@ -82,25 +69,24 @@ typedef struct {
static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
server_filter_args *a = user_data;
grpc_call_element *elem = a->elem;
channel_data *channeld = elem->channel_data;
call_data *calld = elem->call_data;
/* Check if it is one of the headers we care about. */
if (md == channeld->te_trailers || md == channeld->method_post ||
md == channeld->http_scheme || md == channeld->https_scheme ||
md == channeld->grpc_scheme || md == channeld->content_type) {
if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST ||
md == GRPC_MDELEM_SCHEME_HTTP || md == GRPC_MDELEM_SCHEME_HTTPS ||
md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
/* swallow it */
if (md == channeld->method_post) {
if (md == GRPC_MDELEM_METHOD_POST) {
calld->seen_post = 1;
} else if (md->key == channeld->http_scheme->key) {
} else if (md->key == GRPC_MDSTR_SCHEME) {
calld->seen_scheme = 1;
} else if (md == channeld->te_trailers) {
} else if (md == GRPC_MDELEM_TE_TRAILERS) {
calld->seen_te_trailers = 1;
}
/* TODO(klempner): Track that we've seen all the headers we should
require */
return NULL;
} else if (md->key == channeld->content_type->key) {
} else if (md->key == GRPC_MDSTR_CONTENT_TYPE) {
if (strncmp(grpc_mdstr_as_c_string(md->value), "application/grpc+", 17) ==
0) {
/* Although the C implementation doesn't (currently) generate them,
@ -112,12 +98,11 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
/* TODO(klempner): We're currently allowing this, but we shouldn't
see it without a proxy so log for now. */
gpr_log(GPR_INFO, "Unexpected content-type %s",
channeld->content_type->key);
grpc_mdstr_as_c_string(md->value));
}
return NULL;
} else if (md->key == channeld->te_trailers->key ||
md->key == channeld->method_post->key ||
md->key == channeld->http_scheme->key) {
} else if (md->key == GRPC_MDSTR_TE || md->key == GRPC_MDSTR_METHOD ||
md->key == GRPC_MDSTR_SCHEME) {
gpr_log(GPR_ERROR, "Invalid %s: header: '%s'",
grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value));
/* swallow it and error everything out. */
@ -125,22 +110,21 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
on the wire here. */
grpc_call_element_send_cancel(a->exec_ctx, elem);
return NULL;
} else if (md->key == channeld->path_key) {
} else if (md->key == GRPC_MDSTR_PATH) {
if (calld->seen_path) {
gpr_log(GPR_ERROR, "Received :path twice");
return NULL;
}
calld->seen_path = 1;
return md;
} else if (md->key == channeld->authority_key) {
} else if (md->key == GRPC_MDSTR_AUTHORITY) {
calld->seen_authority = 1;
return md;
} else if (md->key == channeld->host_key) {
} else if (md->key == GRPC_MDSTR_HOST) {
/* translate host to :authority since :authority may be
omitted */
grpc_mdelem *authority = grpc_mdelem_from_metadata_strings(
channeld->mdctx, GRPC_MDSTR_REF(channeld->authority_key),
GRPC_MDSTR_REF(md->value));
calld->mdctx, GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
GRPC_MDELEM_UNREF(md);
calld->seen_authority = 1;
return authority;
@ -191,15 +175,14 @@ static void hs_mutate_op(grpc_call_element *elem,
grpc_transport_stream_op *op) {
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
if (op->send_initial_metadata != NULL && !calld->sent_status) {
calld->sent_status = 1;
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->status,
GRPC_MDELEM_REF(channeld->status_ok));
grpc_metadata_batch_add_tail(op->send_initial_metadata,
&calld->content_type,
GRPC_MDELEM_REF(channeld->content_type));
GRPC_MDELEM_STATUS_200);
grpc_metadata_batch_add_tail(
op->send_initial_metadata, &calld->content_type,
GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC);
}
if (op->recv_initial_metadata) {
@ -228,6 +211,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
/* initialize members */
memset(calld, 0, sizeof(*calld));
grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem);
calld->mdctx = args->metadata_context;
}
/* Destructor for call_data */
@ -238,56 +222,12 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
/* grab pointers to our data from the channel element */
channel_data *channeld = elem->channel_data;
/* The first and the last filters tend to be implemented differently to
handle the case that there's no 'next' filter to call on the up or down
path */
GPR_ASSERT(!args->is_last);
/* initialize members */
channeld->te_trailers =
grpc_mdelem_from_strings(args->metadata_context, "te", "trailers");
channeld->status_ok =
grpc_mdelem_from_strings(args->metadata_context, ":status", "200");
channeld->status_not_found =
grpc_mdelem_from_strings(args->metadata_context, ":status", "404");
channeld->method_post =
grpc_mdelem_from_strings(args->metadata_context, ":method", "POST");
channeld->http_scheme =
grpc_mdelem_from_strings(args->metadata_context, ":scheme", "http");
channeld->https_scheme =
grpc_mdelem_from_strings(args->metadata_context, ":scheme", "https");
channeld->grpc_scheme =
grpc_mdelem_from_strings(args->metadata_context, ":scheme", "grpc");
channeld->path_key = grpc_mdstr_from_string(args->metadata_context, ":path");
channeld->authority_key =
grpc_mdstr_from_string(args->metadata_context, ":authority");
channeld->host_key = grpc_mdstr_from_string(args->metadata_context, "host");
channeld->content_type = grpc_mdelem_from_strings(
args->metadata_context, "content-type", "application/grpc");
channeld->mdctx = args->metadata_context;
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
/* grab pointers to our data from the channel element */
channel_data *channeld = elem->channel_data;
GRPC_MDELEM_UNREF(channeld->te_trailers);
GRPC_MDELEM_UNREF(channeld->status_ok);
GRPC_MDELEM_UNREF(channeld->status_not_found);
GRPC_MDELEM_UNREF(channeld->method_post);
GRPC_MDELEM_UNREF(channeld->http_scheme);
GRPC_MDELEM_UNREF(channeld->https_scheme);
GRPC_MDELEM_UNREF(channeld->grpc_scheme);
GRPC_MDELEM_UNREF(channeld->content_type);
GRPC_MDSTR_UNREF(channeld->path_key);
GRPC_MDSTR_UNREF(channeld->authority_key);
GRPC_MDSTR_UNREF(channeld->host_key);
}
const grpc_channel_filter grpc_http_server_filter = {

@ -58,7 +58,7 @@ static void retry_waiting_locked(grpc_exec_ctx *exec_ctx,
void grpc_subchannel_call_holder_init(
grpc_subchannel_call_holder *holder,
grpc_subchannel_call_holder_pick_subchannel pick_subchannel,
void *pick_subchannel_arg) {
void *pick_subchannel_arg, grpc_mdctx *mdctx) {
gpr_atm_rel_store(&holder->subchannel_call, 0);
holder->pick_subchannel = pick_subchannel;
holder->pick_subchannel_arg = pick_subchannel_arg;
@ -68,6 +68,7 @@ void grpc_subchannel_call_holder_init(
holder->waiting_ops_count = 0;
holder->waiting_ops_capacity = 0;
holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
holder->mdctx = mdctx;
}
void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx,
@ -156,9 +157,9 @@ retry:
holder->subchannel != NULL) {
holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_CREATING_CALL;
grpc_closure_init(&holder->next_step, call_ready, holder);
if (grpc_subchannel_create_call(exec_ctx, holder->subchannel,
holder->pollset, &holder->subchannel_call,
&holder->next_step)) {
if (grpc_subchannel_create_call(
exec_ctx, holder->subchannel, holder->pollset, holder->mdctx,
&holder->subchannel_call, &holder->next_step)) {
/* got one immediately - continue the op (and any waiting ops) */
holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
retry_waiting_locked(exec_ctx, holder);
@ -184,9 +185,9 @@ static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, int success) {
fail_locked(exec_ctx, holder);
} else {
grpc_closure_init(&holder->next_step, call_ready, holder);
if (grpc_subchannel_create_call(exec_ctx, holder->subchannel,
holder->pollset, &holder->subchannel_call,
&holder->next_step)) {
if (grpc_subchannel_create_call(
exec_ctx, holder->subchannel, holder->pollset, holder->mdctx,
&holder->subchannel_call, &holder->next_step)) {
holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
/* got one immediately - continue the op (and any waiting ops) */
retry_waiting_locked(exec_ctx, holder);

@ -68,6 +68,8 @@ typedef struct grpc_subchannel_call_holder {
grpc_subchannel_call_holder_pick_subchannel pick_subchannel;
void *pick_subchannel_arg;
grpc_mdctx *mdctx;
gpr_mu mu;
grpc_subchannel_call_holder_creation_phase creation_phase;
@ -84,7 +86,7 @@ typedef struct grpc_subchannel_call_holder {
void grpc_subchannel_call_holder_init(
grpc_subchannel_call_holder *holder,
grpc_subchannel_call_holder_pick_subchannel pick_subchannel,
void *pick_subchannel_arg);
void *pick_subchannel_arg, grpc_mdctx *mdctx);
void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call_holder *holder);

@ -73,6 +73,7 @@ typedef struct waiting_for_connect {
grpc_pollset *pollset;
gpr_atm *target;
grpc_subchannel *subchannel;
grpc_mdctx *mdctx;
grpc_closure continuation;
} waiting_for_connect;
@ -87,8 +88,6 @@ struct grpc_subchannel {
/** address to connect to */
struct sockaddr *addr;
size_t addr_len;
/** metadata context */
grpc_mdctx *mdctx;
/** master channel - the grpc_channel instance that ultimately owns
this channel_data via its channel stack.
We occasionally use this to bump the refcount on the master channel
@ -147,8 +146,8 @@ struct grpc_subchannel_call {
(((grpc_subchannel_call *)(callstack)) - 1)
static grpc_subchannel_call *create_call(grpc_exec_ctx *exec_ctx,
connection *con,
grpc_pollset *pollset);
connection *con, grpc_pollset *pollset,
grpc_mdctx *mdctx);
static void connectivity_state_changed_locked(grpc_exec_ctx *exec_ctx,
grpc_subchannel *c,
const char *reason);
@ -267,7 +266,6 @@ static void subchannel_destroy(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
gpr_free((void *)c->filters);
grpc_channel_args_destroy(c->args);
gpr_free(c->addr);
grpc_mdctx_unref(c->mdctx);
grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
grpc_connector_unref(exec_ctx, c->connector);
gpr_free(c);
@ -306,11 +304,9 @@ grpc_subchannel *grpc_subchannel_create(grpc_connector *connector,
memcpy(c->addr, args->addr, args->addr_len);
c->addr_len = args->addr_len;
c->args = grpc_channel_args_copy(args->args);
c->mdctx = args->mdctx;
c->master = args->master;
c->pollset_set = grpc_client_channel_get_connecting_pollset_set(parent_elem);
c->random = random_seed();
grpc_mdctx_ref(c->mdctx);
grpc_closure_init(&c->connected, subchannel_connected, c);
grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE,
"subchannel");
@ -398,8 +394,9 @@ static void continue_creating_call(grpc_exec_ctx *exec_ctx, void *arg,
int call_creation_finished_ok;
waiting_for_connect *w4c = arg;
grpc_subchannel_del_interested_party(exec_ctx, w4c->subchannel, w4c->pollset);
call_creation_finished_ok = grpc_subchannel_create_call(
exec_ctx, w4c->subchannel, w4c->pollset, w4c->target, w4c->notify);
call_creation_finished_ok =
grpc_subchannel_create_call(exec_ctx, w4c->subchannel, w4c->pollset,
w4c->mdctx, w4c->target, w4c->notify);
GPR_ASSERT(call_creation_finished_ok == 1);
w4c->notify->cb(exec_ctx, w4c->notify->cb_arg, iomgr_success);
GRPC_SUBCHANNEL_UNREF(exec_ctx, w4c->subchannel, "waiting_for_connect");
@ -407,8 +404,8 @@ static void continue_creating_call(grpc_exec_ctx *exec_ctx, void *arg,
}
int grpc_subchannel_create_call(grpc_exec_ctx *exec_ctx, grpc_subchannel *c,
grpc_pollset *pollset, gpr_atm *target,
grpc_closure *notify) {
grpc_pollset *pollset, grpc_mdctx *mdctx,
gpr_atm *target, grpc_closure *notify) {
connection *con;
grpc_subchannel_call *call;
GPR_TIMER_BEGIN("grpc_subchannel_create_call", 0);
@ -418,7 +415,7 @@ int grpc_subchannel_create_call(grpc_exec_ctx *exec_ctx, grpc_subchannel *c,
CONNECTION_REF_LOCKED(con, "call");
gpr_mu_unlock(&c->mu);
call = create_call(exec_ctx, con, pollset);
call = create_call(exec_ctx, con, pollset, mdctx);
if (!gpr_atm_rel_cas(target, 0, (gpr_atm)(gpr_uintptr)call)) {
GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "failed to set");
}
@ -431,6 +428,7 @@ int grpc_subchannel_create_call(grpc_exec_ctx *exec_ctx, grpc_subchannel *c,
w4c->pollset = pollset;
w4c->target = target;
w4c->subchannel = c;
w4c->mdctx = mdctx;
/* released when clearing w4c */
SUBCHANNEL_REF_LOCKED(c, "waiting_for_connect");
grpc_closure_init(&w4c->continuation, continue_creating_call, w4c);
@ -624,7 +622,7 @@ static void publish_transport(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
con->refs = 0;
con->subchannel = c;
grpc_channel_stack_init(exec_ctx, filters, num_filters, c->master, c->args,
c->mdctx, stk);
stk);
grpc_connected_channel_bind_transport(stk, c->connecting_result.transport);
gpr_free((void *)c->connecting_result.filters);
memset(&c->connecting_result, 0, sizeof(c->connecting_result));
@ -858,23 +856,19 @@ void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx,
}
static grpc_subchannel_call *create_call(grpc_exec_ctx *exec_ctx,
connection *con,
grpc_pollset *pollset) {
connection *con, grpc_pollset *pollset,
grpc_mdctx *mdctx) {
grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
grpc_subchannel_call *call =
gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call);
call->connection = con;
grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, call,
NULL, NULL, callstk);
NULL, NULL, mdctx, callstk);
grpc_call_stack_set_pollset(exec_ctx, callstk, pollset);
return call;
}
grpc_mdctx *grpc_subchannel_get_mdctx(grpc_subchannel *subchannel) {
return subchannel->mdctx;
}
grpc_channel *grpc_subchannel_get_master(grpc_subchannel *subchannel) {
return subchannel->master;
}

@ -84,8 +84,8 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx,
* asynchronously, invoking the \a notify callback upon completion. */
int grpc_subchannel_create_call(grpc_exec_ctx *exec_ctx,
grpc_subchannel *subchannel,
grpc_pollset *pollset, gpr_atm *target,
grpc_closure *notify);
grpc_pollset *pollset, grpc_mdctx *mdctx,
gpr_atm *target, grpc_closure *notify);
/** cancel \a call in the waiting state. */
void grpc_subchannel_cancel_create_call(grpc_exec_ctx *exec_ctx,
@ -157,9 +157,6 @@ struct grpc_subchannel_args {
grpc_subchannel *grpc_subchannel_create(grpc_connector *connector,
grpc_subchannel_args *args);
/** Return the metadata context associated with the subchannel */
grpc_mdctx *grpc_subchannel_get_mdctx(grpc_subchannel *subchannel);
/** Return the master channel associated with the subchannel */
grpc_channel *grpc_subchannel_get_master(grpc_subchannel *subchannel);

@ -37,7 +37,9 @@
#include <grpc/compression.h>
#include <grpc/support/useful.h>
#include "src/core/compression/algorithm_metadata.h"
#include "src/core/surface/api_trace.h"
#include "src/core/transport/static_metadata.h"
int grpc_compression_algorithm_parse(const char *name, size_t name_length,
grpc_compression_algorithm *algorithm) {
@ -72,17 +74,55 @@ int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
switch (algorithm) {
case GRPC_COMPRESS_NONE:
*name = "identity";
break;
return 1;
case GRPC_COMPRESS_DEFLATE:
*name = "deflate";
break;
return 1;
case GRPC_COMPRESS_GZIP:
*name = "gzip";
break;
default:
return 1;
case GRPC_COMPRESS_ALGORITHMS_COUNT:
return 0;
}
return 1;
return 0;
}
grpc_compression_algorithm grpc_compression_algorithm_from_mdstr(
grpc_mdstr *str) {
if (str == GRPC_MDSTR_IDENTITY) return GRPC_COMPRESS_NONE;
if (str == GRPC_MDSTR_DEFLATE) return GRPC_COMPRESS_DEFLATE;
if (str == GRPC_MDSTR_GZIP) return GRPC_COMPRESS_GZIP;
return GRPC_COMPRESS_ALGORITHMS_COUNT;
}
grpc_mdstr *grpc_compression_algorithm_mdstr(
grpc_compression_algorithm algorithm) {
switch (algorithm) {
case GRPC_COMPRESS_NONE:
return GRPC_MDSTR_IDENTITY;
case GRPC_COMPRESS_DEFLATE:
return GRPC_MDSTR_DEFLATE;
case GRPC_COMPRESS_GZIP:
return GRPC_MDSTR_GZIP;
case GRPC_COMPRESS_ALGORITHMS_COUNT:
return NULL;
}
return NULL;
}
grpc_mdelem *grpc_compression_encoding_mdelem(
grpc_compression_algorithm algorithm) {
switch (algorithm) {
case GRPC_COMPRESS_NONE:
return GRPC_MDELEM_GRPC_ENCODING_IDENTITY;
case GRPC_COMPRESS_DEFLATE:
return GRPC_MDELEM_GRPC_ENCODING_DEFLATE;
case GRPC_COMPRESS_GZIP:
return GRPC_MDELEM_GRPC_ENCODING_GZIP;
case GRPC_COMPRESS_ALGORITHMS_COUNT:
return NULL;
}
return NULL;
}
/* TODO(dgq): Add the ability to specify parameters to the individual

@ -0,0 +1,53 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_METADATA_H
#define GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_METADATA_H
#include <grpc/compression.h>
#include "src/core/transport/metadata.h"
/** Return compression algorithm based metadata value */
grpc_mdstr *grpc_compression_algorithm_mdstr(
grpc_compression_algorithm algorithm);
/** Return compression algorithm based metadata element (grpc-encoding: xxx) */
grpc_mdelem *grpc_compression_encoding_mdelem(
grpc_compression_algorithm algorithm);
/** Find compression algorithm based on passed in mdstr - returns
* GRPC_COMPRESS_ALGORITHM_COUNT on failure */
grpc_compression_algorithm grpc_compression_algorithm_from_mdstr(
grpc_mdstr *str);
#endif /* GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_METADATA_H */

@ -43,6 +43,7 @@
#include <grpc/support/useful.h>
#include "src/core/channel/channel_stack.h"
#include "src/core/compression/algorithm_metadata.h"
#include "src/core/iomgr/timer.h"
#include "src/core/profiling/timers.h"
#include "src/core/support/string.h"
@ -50,6 +51,7 @@
#include "src/core/surface/call.h"
#include "src/core/surface/channel.h"
#include "src/core/surface/completion_queue.h"
#include "src/core/transport/static_metadata.h"
/** The maximum number of concurrent batches possible.
Based upon the maximum number of individually queueable ops in the batch
@ -271,6 +273,7 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
/* initial refcount dropped by grpc_call_destroy */
grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call,
call->context, server_transport_data,
grpc_channel_get_metadata_context(channel),
CALL_STACK_FROM_CALL(call));
if (cq != NULL) {
GRPC_CQ_INTERNAL_REF(cq, "bind");
@ -788,8 +791,12 @@ static void destroy_status(void *ignored) {}
static gpr_uint32 decode_status(grpc_mdelem *md) {
gpr_uint32 status;
void *user_data = grpc_mdelem_get_user_data(md, destroy_status);
if (user_data) {
void *user_data;
if (md == GRPC_MDELEM_GRPC_STATUS_0) return 0;
if (md == GRPC_MDELEM_GRPC_STATUS_1) return 1;
if (md == GRPC_MDELEM_GRPC_STATUS_2) return 2;
user_data = grpc_mdelem_get_user_data(md, destroy_status);
if (user_data != NULL) {
status = ((gpr_uint32)(gpr_intptr)user_data) - STATUS_OFFSET;
} else {
if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value),
@ -803,38 +810,23 @@ static gpr_uint32 decode_status(grpc_mdelem *md) {
return status;
}
/* just as for status above, we need to offset: metadata userdata can't hold a
* zero (null), which in this case is used to signal no compression */
#define COMPRESS_OFFSET 1
static void destroy_compression(void *ignored) {}
static gpr_uint32 decode_compression(grpc_mdelem *md) {
grpc_compression_algorithm algorithm;
void *user_data = grpc_mdelem_get_user_data(md, destroy_compression);
if (user_data) {
algorithm =
((grpc_compression_algorithm)(gpr_intptr)user_data) - COMPRESS_OFFSET;
} else {
grpc_compression_algorithm algorithm =
grpc_compression_algorithm_from_mdstr(md->value);
if (algorithm == GRPC_COMPRESS_ALGORITHMS_COUNT) {
const char *md_c_str = grpc_mdstr_as_c_string(md->value);
if (!grpc_compression_algorithm_parse(md_c_str, strlen(md_c_str),
&algorithm)) {
gpr_log(GPR_ERROR, "Invalid compression algorithm: '%s'", md_c_str);
assert(0);
}
grpc_mdelem_set_user_data(
md, destroy_compression,
(void *)(gpr_intptr)(algorithm + COMPRESS_OFFSET));
gpr_log(GPR_ERROR, "Invalid compression algorithm: '%s'", md_c_str);
}
return algorithm;
}
static grpc_mdelem *recv_common_filter(grpc_call *call, grpc_mdelem *elem) {
if (elem->key == grpc_channel_get_status_string(call->channel)) {
if (elem->key == GRPC_MDSTR_GRPC_STATUS) {
GPR_TIMER_BEGIN("status", 0);
set_status_code(call, STATUS_FROM_WIRE, decode_status(elem));
GPR_TIMER_END("status", 0);
return NULL;
} else if (elem->key == grpc_channel_get_message_string(call->channel)) {
} else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) {
GPR_TIMER_BEGIN("status-details", 0);
set_status_details(call, STATUS_FROM_WIRE, GRPC_MDSTR_REF(elem->value));
GPR_TIMER_END("status-details", 0);
@ -867,14 +859,12 @@ static grpc_mdelem *recv_initial_filter(void *callp, grpc_mdelem *elem) {
elem = recv_common_filter(call, elem);
if (elem == NULL) {
return NULL;
} else if (elem->key ==
grpc_channel_get_compression_algorithm_string(call->channel)) {
} else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) {
GPR_TIMER_BEGIN("compression_algorithm", 0);
set_compression_algorithm(call, decode_compression(elem));
GPR_TIMER_END("compression_algorithm", 0);
return NULL;
} else if (elem->key == grpc_channel_get_encodings_accepted_by_peer_string(
call->channel)) {
} else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) {
GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
set_encodings_accepted_by_peer(call, elem);
GPR_TIMER_END("encodings_accepted_by_peer", 0);
@ -1240,8 +1230,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
call->channel, op->data.send_status_from_server.status);
if (op->data.send_status_from_server.status_details != NULL) {
call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings(
call->metadata_context,
GRPC_MDSTR_REF(grpc_channel_get_message_string(call->channel)),
call->metadata_context, GRPC_MDSTR_GRPC_MESSAGE,
grpc_mdstr_from_string(
call->metadata_context,
op->data.send_status_from_server.status_details));

@ -46,6 +46,7 @@
#include "src/core/surface/api_trace.h"
#include "src/core/surface/call.h"
#include "src/core/surface/init.h"
#include "src/core/transport/static_metadata.h"
/** Cache grpc-status: X mdelems for X = 0..NUM_CACHED_STATUS_ELEMS.
* Avoids needing to take a metadata context lock for sending status
@ -65,16 +66,7 @@ struct grpc_channel {
gpr_refcount refs;
gpr_uint32 max_message_length;
grpc_mdctx *metadata_context;
/** mdstr for the grpc-status key */
grpc_mdstr *grpc_status_string;
grpc_mdstr *grpc_compression_algorithm_string;
grpc_mdstr *grpc_encodings_accepted_by_peer_string;
grpc_mdstr *grpc_message_string;
grpc_mdstr *path_string;
grpc_mdstr *authority_string;
grpc_mdelem *default_authority;
/** mdelem for grpc-status: 0 thru grpc-status: 2 */
grpc_mdelem *grpc_status_elem[NUM_CACHED_STATUS_ELEMS];
gpr_mu registered_call_mu;
registered_call *registered_calls;
@ -90,6 +82,55 @@ struct grpc_channel {
/* the protobuf library will (by default) start warning at 100megs */
#define DEFAULT_MAX_MESSAGE_LENGTH (100 * 1024 * 1024)
static grpc_mdstr *user_agent_from_args(grpc_mdctx *mdctx,
const grpc_channel_args *args) {
gpr_strvec v;
size_t i;
int is_first = 1;
char *tmp;
grpc_mdstr *result;
gpr_strvec_init(&v);
for (i = 0; args && i < args->num_args; i++) {
if (0 == strcmp(args->args[i].key, GRPC_ARG_PRIMARY_USER_AGENT_STRING)) {
if (args->args[i].type != GRPC_ARG_STRING) {
gpr_log(GPR_ERROR, "Channel argument '%s' should be a string",
GRPC_ARG_PRIMARY_USER_AGENT_STRING);
} else {
if (!is_first) gpr_strvec_add(&v, gpr_strdup(" "));
is_first = 0;
gpr_strvec_add(&v, gpr_strdup(args->args[i].value.string));
}
}
}
gpr_asprintf(&tmp, "%sgrpc-c/%s (%s)", is_first ? "" : " ",
grpc_version_string(), GPR_PLATFORM_STRING);
is_first = 0;
gpr_strvec_add(&v, tmp);
for (i = 0; args && i < args->num_args; i++) {
if (0 == strcmp(args->args[i].key, GRPC_ARG_SECONDARY_USER_AGENT_STRING)) {
if (args->args[i].type != GRPC_ARG_STRING) {
gpr_log(GPR_ERROR, "Channel argument '%s' should be a string",
GRPC_ARG_SECONDARY_USER_AGENT_STRING);
} else {
if (!is_first) gpr_strvec_add(&v, gpr_strdup(" "));
is_first = 0;
gpr_strvec_add(&v, gpr_strdup(args->args[i].value.string));
}
}
}
tmp = gpr_strvec_flatten(&v, NULL);
gpr_strvec_destroy(&v);
result = grpc_mdstr_from_string(mdctx, tmp);
gpr_free(tmp);
return result;
}
grpc_channel *grpc_channel_create_from_filters(
grpc_exec_ctx *exec_ctx, const char *target,
const grpc_channel_filter **filters, size_t num_filters,
@ -105,24 +146,16 @@ grpc_channel *grpc_channel_create_from_filters(
/* decremented by grpc_channel_destroy */
gpr_ref_init(&channel->refs, 1);
channel->metadata_context = mdctx;
channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status");
channel->grpc_compression_algorithm_string =
grpc_mdstr_from_string(mdctx, "grpc-encoding");
channel->grpc_encodings_accepted_by_peer_string =
grpc_mdstr_from_string(mdctx, "grpc-accept-encoding");
channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message");
for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) {
char buf[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa((long)i, buf);
channel->grpc_status_elem[i] = grpc_mdelem_from_metadata_strings(
mdctx, GRPC_MDSTR_REF(channel->grpc_status_string),
grpc_mdstr_from_string(mdctx, buf));
}
channel->path_string = grpc_mdstr_from_string(mdctx, ":path");
channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority");
gpr_mu_init(&channel->registered_call_mu);
channel->registered_calls = NULL;
if (is_client) {
grpc_mdctx_set_mdelem_cache(
mdctx, GRPC_MDELEM_CACHED_USER_AGENT,
grpc_mdelem_from_metadata_strings(mdctx, GRPC_MDSTR_USER_AGENT,
user_agent_from_args(mdctx, args)));
}
channel->max_message_length = DEFAULT_MAX_MESSAGE_LENGTH;
if (args) {
for (i = 0; i < args->num_args; i++) {
@ -178,7 +211,6 @@ grpc_channel *grpc_channel_create_from_filters(
}
grpc_channel_stack_init(exec_ctx, filters, num_filters, channel, args,
channel->metadata_context,
CHANNEL_STACK_FROM_CHANNEL(channel));
return channel;
@ -228,11 +260,10 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
return grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, cq,
grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->path_string),
channel->metadata_context, GRPC_MDSTR_PATH,
grpc_mdstr_from_string(channel->metadata_context, method)),
host ? grpc_mdelem_from_metadata_strings(
channel->metadata_context,
GRPC_MDSTR_REF(channel->authority_string),
channel->metadata_context, GRPC_MDSTR_AUTHORITY,
grpc_mdstr_from_string(channel->metadata_context, host))
: NULL,
deadline);
@ -246,12 +277,11 @@ void *grpc_channel_register_call(grpc_channel *channel, const char *method,
4, (channel, method, host, reserved));
GPR_ASSERT(!reserved);
rc->path = grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->path_string),
channel->metadata_context, GRPC_MDSTR_PATH,
grpc_mdstr_from_string(channel->metadata_context, method));
rc->authority =
host ? grpc_mdelem_from_metadata_strings(
channel->metadata_context,
GRPC_MDSTR_REF(channel->authority_string),
channel->metadata_context, GRPC_MDSTR_AUTHORITY,
grpc_mdstr_from_string(channel->metadata_context, host))
: NULL;
gpr_mu_lock(&channel->registered_call_mu);
@ -293,17 +323,7 @@ void grpc_channel_internal_ref(grpc_channel *c) {
}
static void destroy_channel(grpc_exec_ctx *exec_ctx, grpc_channel *channel) {
size_t i;
grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CHANNEL(channel));
for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) {
GRPC_MDELEM_UNREF(channel->grpc_status_elem[i]);
}
GRPC_MDSTR_UNREF(channel->grpc_status_string);
GRPC_MDSTR_UNREF(channel->grpc_compression_algorithm_string);
GRPC_MDSTR_UNREF(channel->grpc_encodings_accepted_by_peer_string);
GRPC_MDSTR_UNREF(channel->grpc_message_string);
GRPC_MDSTR_UNREF(channel->path_string);
GRPC_MDSTR_UNREF(channel->authority_string);
while (channel->registered_calls) {
registered_call *rc = channel->registered_calls;
channel->registered_calls = rc->next;
@ -316,6 +336,7 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, grpc_channel *channel) {
if (channel->default_authority != NULL) {
GRPC_MDELEM_UNREF(channel->default_authority);
}
grpc_mdctx_drop_caches(channel->metadata_context);
grpc_mdctx_unref(channel->metadata_context);
gpr_mu_destroy(&channel->registered_call_mu);
gpr_free(channel->target);
@ -359,34 +380,20 @@ grpc_mdctx *grpc_channel_get_metadata_context(grpc_channel *channel) {
return channel->metadata_context;
}
grpc_mdstr *grpc_channel_get_status_string(grpc_channel *channel) {
return channel->grpc_status_string;
}
grpc_mdstr *grpc_channel_get_compression_algorithm_string(
grpc_channel *channel) {
return channel->grpc_compression_algorithm_string;
}
grpc_mdstr *grpc_channel_get_encodings_accepted_by_peer_string(
grpc_channel *channel) {
return channel->grpc_encodings_accepted_by_peer_string;
}
grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
if (i >= 0 && i < NUM_CACHED_STATUS_ELEMS) {
return GRPC_MDELEM_REF(channel->grpc_status_elem[i]);
} else {
char tmp[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(i, tmp);
return grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->grpc_status_string),
grpc_mdstr_from_string(channel->metadata_context, tmp));
char tmp[GPR_LTOA_MIN_BUFSIZE];
switch (i) {
case 0:
return GRPC_MDELEM_GRPC_STATUS_0;
case 1:
return GRPC_MDELEM_GRPC_STATUS_1;
case 2:
return GRPC_MDELEM_GRPC_STATUS_2;
}
}
grpc_mdstr *grpc_channel_get_message_string(grpc_channel *channel) {
return channel->grpc_message_string;
gpr_ltoa(i, tmp);
return grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_GRPC_STATUS,
grpc_mdstr_from_string(channel->metadata_context, tmp));
}
gpr_uint32 grpc_channel_get_max_message_length(grpc_channel *channel) {

@ -54,12 +54,6 @@ grpc_mdctx *grpc_channel_get_metadata_context(grpc_channel *channel);
The returned elem is owned by the caller. */
grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel,
int status_code);
grpc_mdstr *grpc_channel_get_status_string(grpc_channel *channel);
grpc_mdstr *grpc_channel_get_compression_algorithm_string(
grpc_channel *channel);
grpc_mdstr *grpc_channel_get_encodings_accepted_by_peer_string(
grpc_channel *channel);
grpc_mdstr *grpc_channel_get_message_string(grpc_channel *channel);
gpr_uint32 grpc_channel_get_max_message_length(grpc_channel *channel);
#ifdef GRPC_CHANNEL_REF_COUNT_DEBUG

@ -46,10 +46,10 @@
typedef struct {
grpc_linked_mdelem status;
grpc_linked_mdelem details;
grpc_mdctx *mdctx;
} call_data;
typedef struct {
grpc_mdctx *mdctx;
grpc_channel *master;
grpc_status_code error_code;
const char *error_message;
@ -60,8 +60,8 @@ static void fill_metadata(grpc_call_element *elem, grpc_metadata_batch *mdb) {
channel_data *chand = elem->channel_data;
char tmp[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(chand->error_code, tmp);
calld->status.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-status", tmp);
calld->details.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-message",
calld->status.md = grpc_mdelem_from_strings(calld->mdctx, "grpc-status", tmp);
calld->details.md = grpc_mdelem_from_strings(calld->mdctx, "grpc-message",
chand->error_message);
calld->status.prev = calld->details.next = NULL;
calld->status.next = &calld->details;
@ -104,7 +104,10 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx,
}
static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_call_element_args *args) {}
grpc_call_element_args *args) {
call_data *calld = elem->call_data;
calld->mdctx = args->metadata_context;
}
static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem) {}
@ -115,7 +118,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
channel_data *chand = elem->channel_data;
GPR_ASSERT(args->is_first);
GPR_ASSERT(args->is_last);
chand->mdctx = args->metadata_context;
chand->master = args->master;
}

@ -54,6 +54,7 @@
#include "src/core/surface/completion_queue.h"
#include "src/core/surface/init.h"
#include "src/core/transport/metadata.h"
#include "src/core/transport/static_metadata.h"
typedef struct listener {
void *arg;
@ -108,8 +109,6 @@ struct channel_data {
grpc_server *server;
grpc_connectivity_state connectivity_state;
grpc_channel *channel;
grpc_mdstr *path_key;
grpc_mdstr *authority_key;
/* linked list of all channels on a server */
channel_data *next;
channel_data *prev;
@ -558,12 +557,11 @@ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
grpc_call_element *elem = user_data;
channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data;
if (md->key == chand->path_key) {
if (md->key == GRPC_MDSTR_PATH) {
calld->path = GRPC_MDSTR_REF(md->value);
return NULL;
} else if (md->key == chand->authority_key) {
} else if (md->key == GRPC_MDSTR_AUTHORITY) {
calld->host = GRPC_MDSTR_REF(md->value);
return NULL;
}
@ -718,9 +716,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(!args->is_last);
chand->server = NULL;
chand->channel = NULL;
chand->path_key = grpc_mdstr_from_string(args->metadata_context, ":path");
chand->authority_key =
grpc_mdstr_from_string(args->metadata_context, ":authority");
chand->next = chand->prev = chand;
chand->registered_methods = NULL;
chand->connectivity_state = GRPC_CHANNEL_IDLE;
@ -750,8 +745,6 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
chand->next = chand->prev = chand;
maybe_finish_shutdown(exec_ctx, chand->server);
gpr_mu_unlock(&chand->server->mu_global);
GRPC_MDSTR_UNREF(chand->path_key);
GRPC_MDSTR_UNREF(chand->authority_key);
server_unref(exec_ctx, chand->server);
}
}

@ -37,12 +37,15 @@
#include <stddef.h>
#include <string.h>
#include <grpc/compression.h>
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include "src/core/profiling/timers.h"
#include "src/core/support/murmur_hash.h"
#include "src/core/support/string.h"
#include "src/core/transport/chttp2/bin_encoder.h"
#include "src/core/transport/static_metadata.h"
@ -157,6 +160,11 @@ struct grpc_mdctx {
size_t mdtab_count;
size_t mdtab_free;
size_t mdtab_capacity;
/* cache slots */
gpr_atm cache_slots[GRPC_MDELEM_CACHE_SLOT_COUNT];
/* compression algorithm mdelems: one per algorithm bitmask */
gpr_atm compression_algorithm_mdelem[1 << GRPC_COMPRESS_ALGORITHMS_COUNT];
};
static void internal_string_ref(internal_string *s DEBUG_ARGS);
@ -175,8 +183,10 @@ void grpc_mdctx_global_init(void) {
}
for (i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) {
grpc_mdelem *elem = &grpc_static_mdelem_table[i];
grpc_mdstr *key = &grpc_static_mdstr_table[2 * i + 0];
grpc_mdstr *value = &grpc_static_mdstr_table[2 * i + 1];
grpc_mdstr *key =
&grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 0]];
grpc_mdstr *value =
&grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 1]];
*(grpc_mdstr **)&elem->key = key;
*(grpc_mdstr **)&elem->value = value;
}
@ -304,6 +314,42 @@ grpc_mdctx *grpc_mdctx_create(void) {
(gpr_uint32)gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
}
static void drop_cached_elem(gpr_atm *slot) {
gpr_atm value = gpr_atm_no_barrier_load(slot);
gpr_atm_rel_store(slot, 0);
GRPC_MDELEM_UNREF((grpc_mdelem *)value);
}
void grpc_mdctx_drop_caches(grpc_mdctx *ctx) {
size_t i;
for (i = 0; i < GRPC_MDELEM_CACHE_SLOT_COUNT; i++) {
drop_cached_elem(&ctx->cache_slots[i]);
}
for (i = 0; i < GPR_ARRAY_SIZE(ctx->compression_algorithm_mdelem); i++) {
drop_cached_elem(&ctx->compression_algorithm_mdelem[i]);
}
}
static void set_cache(gpr_atm *slot, grpc_mdelem *elem) {
if (!gpr_atm_rel_cas(slot, 0, (gpr_atm)elem)) {
GRPC_MDELEM_UNREF(elem);
}
}
void grpc_mdctx_set_mdelem_cache(grpc_mdctx *ctx, grpc_mdelem_cache_slot slot,
grpc_mdelem *elem) {
set_cache(&ctx->cache_slots[slot], elem);
}
static grpc_mdelem *get_cache(gpr_atm *slot) {
return (grpc_mdelem *)gpr_atm_acq_load(slot);
}
grpc_mdelem *grpc_mdelem_from_cache(grpc_mdctx *ctx,
grpc_mdelem_cache_slot slot) {
return get_cache(&ctx->cache_slots[slot]);
}
static void discard_metadata(grpc_mdctx *ctx) {
size_t i;
internal_metadata *next, *cur;
@ -780,6 +826,7 @@ void *grpc_mdelem_get_user_data(grpc_mdelem *md, void (*destroy_func)(void *)) {
void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
void *user_data) {
internal_metadata *im = (internal_metadata *)md;
GPR_ASSERT(!is_mdelem_static(md));
GPR_ASSERT((user_data == NULL) == (destroy_func == NULL));
gpr_mu_lock(&im->mu_user_data);
if (gpr_atm_no_barrier_load(&im->destroy_user_data)) {
@ -838,6 +885,52 @@ int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s) {
return conforms_to(s, legal_header_bits);
}
static grpc_mdelem *make_accept_encoding_mdelem_for_compression_algorithms(
grpc_mdctx *mdctx, gpr_uint32 algorithms) {
gpr_strvec sv;
int i;
char *str;
grpc_mdelem *out;
gpr_strvec_init(&sv);
for (i = 0; algorithms != 0; i++, algorithms >>= 1) {
if (algorithms & 1) {
char *name;
GPR_ASSERT(grpc_compression_algorithm_name((grpc_compression_algorithm)i,
&name));
if (sv.count) {
gpr_strvec_add(&sv, gpr_strdup(","));
}
gpr_strvec_add(&sv, gpr_strdup(name));
}
}
str = gpr_strvec_flatten(&sv, NULL);
out =
grpc_mdelem_from_metadata_strings(mdctx, GRPC_MDSTR_GRPC_ACCEPT_ENCODING,
grpc_mdstr_from_string(mdctx, str));
gpr_strvec_destroy(&sv);
gpr_free(str);
return out;
}
grpc_mdelem *grpc_accept_encoding_mdelem_from_compression_algorithms(
grpc_mdctx *ctx, gpr_uint32 algorithms) {
grpc_mdelem *ret;
gpr_atm *slot;
GPR_ASSERT(algorithms < GPR_ARRAY_SIZE(ctx->compression_algorithm_mdelem));
slot = &ctx->compression_algorithm_mdelem[algorithms];
ret = get_cache(slot);
if (ret == NULL) {
set_cache(slot, make_accept_encoding_mdelem_for_compression_algorithms(
ctx, algorithms));
ret = get_cache(slot);
GPR_ASSERT(ret != NULL);
}
return ret;
}
int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s) {
/* TODO(ctiller): consider caching this */
return grpc_is_binary_header((const char *)GPR_SLICE_START_PTR(s->slice),

@ -93,6 +93,8 @@ grpc_mdctx *grpc_mdctx_create_with_seed(gpr_uint32 seed);
void grpc_mdctx_ref(grpc_mdctx *mdctx);
void grpc_mdctx_unref(grpc_mdctx *mdctx);
void grpc_mdctx_drop_caches(grpc_mdctx *mdctx);
/* Test only accessors to internal state - only for testing this code - do not
rely on it outside of metadata_test.c */
size_t grpc_mdctx_get_mdtab_capacity_test_only(grpc_mdctx *mdctx);
@ -161,6 +163,25 @@ int grpc_mdstr_is_legal_header(grpc_mdstr *s);
int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s);
int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s);
/* Gross layering hack (that we seem to need):
* metadata context keeps a cache of algorithm bitset to
* 'accept-encoding: algorithm1,algorithm2' in order to accelerate sending
* compression metadata */
grpc_mdelem *grpc_accept_encoding_mdelem_from_compression_algorithms(
grpc_mdctx *ctx, gpr_uint32 algorithm_mask);
/* Cache-slots
* A metadata context can cache (on behalf of its owner) some small set of
* metadata elements. */
typedef enum {
GRPC_MDELEM_CACHED_USER_AGENT = 0,
GRPC_MDELEM_CACHE_SLOT_COUNT
} grpc_mdelem_cache_slot;
void grpc_mdctx_set_mdelem_cache(grpc_mdctx *ctx, grpc_mdelem_cache_slot slot,
grpc_mdelem *elem);
grpc_mdelem *grpc_mdelem_from_cache(grpc_mdctx *ctx,
grpc_mdelem_cache_slot slot);
#define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
void grpc_mdctx_global_init(void);

@ -47,18 +47,21 @@ grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
const gpr_uint8 grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT *
2] = {
9, 29, 8, 29, 10, 29, 10, 42, 11, 29, 12, 29, 13, 29, 14, 29, 15, 29, 16,
29, 17, 29, 18, 29, 19, 29, 20, 29, 21, 29, 22, 29, 23, 29, 24, 29, 25, 29,
26, 29, 27, 29, 30, 29, 31, 29, 32, 29, 33, 29, 39, 0, 43, 29, 47, 29, 48,
29, 49, 29, 50, 29, 51, 29, 52, 29, 53, 29, 54, 29, 55, 29, 56, 34, 56, 58,
57, 68, 57, 69, 59, 29, 60, 29, 61, 29, 62, 29, 63, 29, 64, 29, 65, 35, 65,
44, 65, 45, 66, 29, 67, 29, 70, 1, 70, 2, 70, 3, 70, 4, 70, 5, 70, 6,
70, 7, 71, 29, 72, 73, 74, 29, 75, 29, 76, 29, 77, 29, 78, 29};
const gpr_uint8
grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] = {
11, 32, 10, 32, 12, 32, 12, 46, 13, 32, 14, 32, 15, 32, 16, 32, 17, 32,
19, 32, 20, 32, 21, 32, 22, 32, 23, 32, 24, 32, 25, 32, 26, 32, 27, 32,
28, 18, 28, 32, 29, 32, 30, 32, 33, 32, 34, 32, 35, 32, 36, 32, 40, 31,
40, 45, 40, 50, 43, 0, 43, 1, 43, 2, 47, 32, 51, 32, 52, 32, 53, 32,
54, 32, 55, 32, 56, 32, 57, 32, 58, 32, 59, 32, 60, 37, 60, 62, 61, 72,
61, 73, 63, 32, 64, 32, 65, 32, 66, 32, 67, 32, 68, 32, 69, 38, 69, 48,
69, 49, 70, 32, 71, 32, 74, 3, 74, 4, 74, 5, 74, 6, 74, 7, 74, 8,
74, 9, 75, 32, 76, 77, 78, 32, 79, 32, 80, 32, 81, 32, 82, 32};
const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
"0",
"1",
"2",
"200",
"204",
"206",
@ -74,6 +77,7 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
"access-control-allow-origin",
"age",
"allow",
"application/grpc",
":authority",
"authorization",
"cache-control",
@ -96,6 +100,7 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
"grpc",
"grpc-accept-encoding",
"grpc-encoding",
"grpc-internal-encoding-request",
"grpc-message",
"grpc-status",
"grpc-timeout",

@ -46,168 +46,176 @@
#include "src/core/transport/metadata.h"
#define GRPC_STATIC_MDSTR_COUNT 79
#define GRPC_STATIC_MDSTR_COUNT 83
extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
/* "0" */
#define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0])
/* "1" */
#define GRPC_MDSTR_1 (&grpc_static_mdstr_table[1])
/* "2" */
#define GRPC_MDSTR_2 (&grpc_static_mdstr_table[2])
/* "200" */
#define GRPC_MDSTR_200 (&grpc_static_mdstr_table[1])
#define GRPC_MDSTR_200 (&grpc_static_mdstr_table[3])
/* "204" */
#define GRPC_MDSTR_204 (&grpc_static_mdstr_table[2])
#define GRPC_MDSTR_204 (&grpc_static_mdstr_table[4])
/* "206" */
#define GRPC_MDSTR_206 (&grpc_static_mdstr_table[3])
#define GRPC_MDSTR_206 (&grpc_static_mdstr_table[5])
/* "304" */
#define GRPC_MDSTR_304 (&grpc_static_mdstr_table[4])
#define GRPC_MDSTR_304 (&grpc_static_mdstr_table[6])
/* "400" */
#define GRPC_MDSTR_400 (&grpc_static_mdstr_table[5])
#define GRPC_MDSTR_400 (&grpc_static_mdstr_table[7])
/* "404" */
#define GRPC_MDSTR_404 (&grpc_static_mdstr_table[6])
#define GRPC_MDSTR_404 (&grpc_static_mdstr_table[8])
/* "500" */
#define GRPC_MDSTR_500 (&grpc_static_mdstr_table[7])
#define GRPC_MDSTR_500 (&grpc_static_mdstr_table[9])
/* "accept" */
#define GRPC_MDSTR_ACCEPT (&grpc_static_mdstr_table[8])
#define GRPC_MDSTR_ACCEPT (&grpc_static_mdstr_table[10])
/* "accept-charset" */
#define GRPC_MDSTR_ACCEPT_CHARSET (&grpc_static_mdstr_table[9])
#define GRPC_MDSTR_ACCEPT_CHARSET (&grpc_static_mdstr_table[11])
/* "accept-encoding" */
#define GRPC_MDSTR_ACCEPT_ENCODING (&grpc_static_mdstr_table[10])
#define GRPC_MDSTR_ACCEPT_ENCODING (&grpc_static_mdstr_table[12])
/* "accept-language" */
#define GRPC_MDSTR_ACCEPT_LANGUAGE (&grpc_static_mdstr_table[11])
#define GRPC_MDSTR_ACCEPT_LANGUAGE (&grpc_static_mdstr_table[13])
/* "accept-ranges" */
#define GRPC_MDSTR_ACCEPT_RANGES (&grpc_static_mdstr_table[12])
#define GRPC_MDSTR_ACCEPT_RANGES (&grpc_static_mdstr_table[14])
/* "access-control-allow-origin" */
#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (&grpc_static_mdstr_table[13])
#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (&grpc_static_mdstr_table[15])
/* "age" */
#define GRPC_MDSTR_AGE (&grpc_static_mdstr_table[14])
#define GRPC_MDSTR_AGE (&grpc_static_mdstr_table[16])
/* "allow" */
#define GRPC_MDSTR_ALLOW (&grpc_static_mdstr_table[15])
#define GRPC_MDSTR_ALLOW (&grpc_static_mdstr_table[17])
/* "application/grpc" */
#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (&grpc_static_mdstr_table[18])
/* ":authority" */
#define GRPC_MDSTR_AUTHORITY (&grpc_static_mdstr_table[16])
#define GRPC_MDSTR_AUTHORITY (&grpc_static_mdstr_table[19])
/* "authorization" */
#define GRPC_MDSTR_AUTHORIZATION (&grpc_static_mdstr_table[17])
#define GRPC_MDSTR_AUTHORIZATION (&grpc_static_mdstr_table[20])
/* "cache-control" */
#define GRPC_MDSTR_CACHE_CONTROL (&grpc_static_mdstr_table[18])
#define GRPC_MDSTR_CACHE_CONTROL (&grpc_static_mdstr_table[21])
/* "content-disposition" */
#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[19])
#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[22])
/* "content-encoding" */
#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[20])
#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[23])
/* "content-language" */
#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[21])
#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[24])
/* "content-length" */
#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[22])
#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[25])
/* "content-location" */
#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[23])
#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[26])
/* "content-range" */
#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[24])
#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[27])
/* "content-type" */
#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[25])
#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[28])
/* "cookie" */
#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[26])
#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[29])
/* "date" */
#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[27])
#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[30])
/* "deflate" */
#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[28])
#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[31])
/* "" */
#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[29])
#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[32])
/* "etag" */
#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[30])
#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[33])
/* "expect" */
#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[31])
#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[34])
/* "expires" */
#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[32])
#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[35])
/* "from" */
#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[33])
#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[36])
/* "GET" */
#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[34])
#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[37])
/* "grpc" */
#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[35])
#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[38])
/* "grpc-accept-encoding" */
#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[36])
#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[39])
/* "grpc-encoding" */
#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[37])
#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[40])
/* "grpc-internal-encoding-request" */
#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[41])
/* "grpc-message" */
#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[38])
#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[42])
/* "grpc-status" */
#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[39])
#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[43])
/* "grpc-timeout" */
#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[40])
#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[44])
/* "gzip" */
#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[41])
#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[45])
/* "gzip, deflate" */
#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[42])
#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[46])
/* "host" */
#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[43])
#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[47])
/* "http" */
#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[44])
#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[48])
/* "https" */
#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[45])
#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[49])
/* "identity" */
#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[46])
#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[50])
/* "if-match" */
#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[47])
#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[51])
/* "if-modified-since" */
#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[48])
#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[52])
/* "if-none-match" */
#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[49])
#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[53])
/* "if-range" */
#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[50])
#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[54])
/* "if-unmodified-since" */
#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[51])
#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[55])
/* "last-modified" */
#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[52])
#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[56])
/* "link" */
#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[53])
#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[57])
/* "location" */
#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[54])
#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[58])
/* "max-forwards" */
#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[55])
#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[59])
/* ":method" */
#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[56])
#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[60])
/* ":path" */
#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[57])
#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[61])
/* "POST" */
#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[58])
#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[62])
/* "proxy-authenticate" */
#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[59])
#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[63])
/* "proxy-authorization" */
#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[60])
#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[64])
/* "range" */
#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[61])
#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[65])
/* "referer" */
#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[62])
#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[66])
/* "refresh" */
#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[63])
#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[67])
/* "retry-after" */
#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[64])
#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[68])
/* ":scheme" */
#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[65])
#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[69])
/* "server" */
#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[66])
#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[70])
/* "set-cookie" */
#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[67])
#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[71])
/* "/" */
#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[68])
#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[72])
/* "/index.html" */
#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[69])
#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[73])
/* ":status" */
#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[70])
#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[74])
/* "strict-transport-security" */
#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[71])
#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[75])
/* "te" */
#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[72])
#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[76])
/* "trailers" */
#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[73])
#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[77])
/* "transfer-encoding" */
#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[74])
#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[78])
/* "user-agent" */
#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[75])
#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[79])
/* "vary" */
#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[76])
#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[80])
/* "via" */
#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[77])
#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[81])
/* "www-authenticate" */
#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[78])
#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[82])
#define GRPC_STATIC_MDELEM_COUNT 65
#define GRPC_STATIC_MDELEM_COUNT 71
extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
/* "accept-charset": "" */
#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY (&grpc_static_mdelem_table[0])
@ -247,101 +255,114 @@ extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY (&grpc_static_mdelem_table[16])
/* "content-range": "" */
#define GRPC_MDELEM_CONTENT_RANGE_EMPTY (&grpc_static_mdelem_table[17])
/* "content-type": "application/grpc" */
#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \
(&grpc_static_mdelem_table[18])
/* "content-type": "" */
#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (&grpc_static_mdelem_table[18])
#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (&grpc_static_mdelem_table[19])
/* "cookie": "" */
#define GRPC_MDELEM_COOKIE_EMPTY (&grpc_static_mdelem_table[19])
#define GRPC_MDELEM_COOKIE_EMPTY (&grpc_static_mdelem_table[20])
/* "date": "" */
#define GRPC_MDELEM_DATE_EMPTY (&grpc_static_mdelem_table[20])
#define GRPC_MDELEM_DATE_EMPTY (&grpc_static_mdelem_table[21])
/* "etag": "" */
#define GRPC_MDELEM_ETAG_EMPTY (&grpc_static_mdelem_table[21])
#define GRPC_MDELEM_ETAG_EMPTY (&grpc_static_mdelem_table[22])
/* "expect": "" */
#define GRPC_MDELEM_EXPECT_EMPTY (&grpc_static_mdelem_table[22])
#define GRPC_MDELEM_EXPECT_EMPTY (&grpc_static_mdelem_table[23])
/* "expires": "" */
#define GRPC_MDELEM_EXPIRES_EMPTY (&grpc_static_mdelem_table[23])
#define GRPC_MDELEM_EXPIRES_EMPTY (&grpc_static_mdelem_table[24])
/* "from": "" */
#define GRPC_MDELEM_FROM_EMPTY (&grpc_static_mdelem_table[24])
#define GRPC_MDELEM_FROM_EMPTY (&grpc_static_mdelem_table[25])
/* "grpc-encoding": "deflate" */
#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE (&grpc_static_mdelem_table[26])
/* "grpc-encoding": "gzip" */
#define GRPC_MDELEM_GRPC_ENCODING_GZIP (&grpc_static_mdelem_table[27])
/* "grpc-encoding": "identity" */
#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY (&grpc_static_mdelem_table[28])
/* "grpc-status": "0" */
#define GRPC_MDELEM_GRPC_STATUS_0 (&grpc_static_mdelem_table[25])
#define GRPC_MDELEM_GRPC_STATUS_0 (&grpc_static_mdelem_table[29])
/* "grpc-status": "1" */
#define GRPC_MDELEM_GRPC_STATUS_1 (&grpc_static_mdelem_table[30])
/* "grpc-status": "2" */
#define GRPC_MDELEM_GRPC_STATUS_2 (&grpc_static_mdelem_table[31])
/* "host": "" */
#define GRPC_MDELEM_HOST_EMPTY (&grpc_static_mdelem_table[26])
#define GRPC_MDELEM_HOST_EMPTY (&grpc_static_mdelem_table[32])
/* "if-match": "" */
#define GRPC_MDELEM_IF_MATCH_EMPTY (&grpc_static_mdelem_table[27])
#define GRPC_MDELEM_IF_MATCH_EMPTY (&grpc_static_mdelem_table[33])
/* "if-modified-since": "" */
#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[28])
#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[34])
/* "if-none-match": "" */
#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (&grpc_static_mdelem_table[29])
#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (&grpc_static_mdelem_table[35])
/* "if-range": "" */
#define GRPC_MDELEM_IF_RANGE_EMPTY (&grpc_static_mdelem_table[30])
#define GRPC_MDELEM_IF_RANGE_EMPTY (&grpc_static_mdelem_table[36])
/* "if-unmodified-since": "" */
#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[31])
#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[37])
/* "last-modified": "" */
#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[32])
#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[38])
/* "link": "" */
#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[33])
#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[39])
/* "location": "" */
#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[34])
#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[40])
/* "max-forwards": "" */
#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[35])
#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[41])
/* ":method": "GET" */
#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[36])
#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[42])
/* ":method": "POST" */
#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[37])
#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[43])
/* ":path": "/" */
#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[38])
#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[44])
/* ":path": "/index.html" */
#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[39])
#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[45])
/* "proxy-authenticate": "" */
#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[40])
#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[46])
/* "proxy-authorization": "" */
#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[41])
#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[47])
/* "range": "" */
#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[42])
#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[48])
/* "referer": "" */
#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[43])
#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[49])
/* "refresh": "" */
#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[44])
#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[50])
/* "retry-after": "" */
#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[45])
#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[51])
/* ":scheme": "grpc" */
#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[46])
#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[52])
/* ":scheme": "http" */
#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[47])
#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[53])
/* ":scheme": "https" */
#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[48])
#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[54])
/* "server": "" */
#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[49])
#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[55])
/* "set-cookie": "" */
#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[50])
#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[56])
/* ":status": "200" */
#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[51])
#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[57])
/* ":status": "204" */
#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[52])
#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[58])
/* ":status": "206" */
#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[53])
#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[59])
/* ":status": "304" */
#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[54])
#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[60])
/* ":status": "400" */
#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[55])
#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[61])
/* ":status": "404" */
#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[56])
#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[62])
/* ":status": "500" */
#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[57])
#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[63])
/* "strict-transport-security": "" */
#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \
(&grpc_static_mdelem_table[58])
(&grpc_static_mdelem_table[64])
/* "te": "trailers" */
#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[59])
#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[65])
/* "transfer-encoding": "" */
#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[60])
#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[66])
/* "user-agent": "" */
#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[61])
#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[67])
/* "vary": "" */
#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[62])
#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[68])
/* "via": "" */
#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[63])
#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[69])
/* "www-authenticate": "" */
#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[64])
#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[70])
const gpr_uint8 grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2];
const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT];

@ -109,7 +109,7 @@ static void test_create_channel_stack(void) {
channel_stack = gpr_malloc(grpc_channel_stack_size(&filters, 1));
grpc_channel_stack_init(&exec_ctx, &filters, 1, NULL, &chan_args,
metadata_context, channel_stack);
channel_stack);
GPR_ASSERT(channel_stack->count == 1);
channel_elem = grpc_channel_stack_element(channel_stack, 0);
channel_data = (int *)channel_elem->channel_data;
@ -117,7 +117,7 @@ static void test_create_channel_stack(void) {
call_stack = gpr_malloc(channel_stack->call_stack_size);
grpc_call_stack_init(&exec_ctx, channel_stack, 0, NULL, NULL, NULL, NULL,
call_stack);
metadata_context, call_stack);
GPR_ASSERT(call_stack->count == 1);
call_elem = grpc_call_stack_element(call_stack, 0);
GPR_ASSERT(call_elem->filter == channel_elem->filter);

@ -263,7 +263,9 @@ static void chttp2_init_client_micro_fullstack(grpc_end2end_test_fixture *f,
/* here sniffed_subchannel should be ready to use */
GPR_ASSERT(conn_state == GRPC_CHANNEL_IDLE);
GPR_ASSERT(ffd->sniffed_subchannel != NULL);
f->client = grpc_client_uchannel_create(ffd->sniffed_subchannel, client_args);
f->client = grpc_client_uchannel_create(
ffd->sniffed_subchannel, client_args,
grpc_channel_get_metadata_context(ffd->master_channel));
grpc_client_uchannel_set_subchannel(f->client, ffd->sniffed_subchannel);
gpr_log(GPR_INFO, "CHANNEL WRAPPING SUBCHANNEL: %p(%p)", f->client,
ffd->sniffed_subchannel);

@ -35,6 +35,7 @@
#include <stdarg.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/slice.h>

@ -35,11 +35,13 @@
#include <stdio.h>
#include "src/core/support/string.h"
#include "src/core/transport/chttp2/bin_encoder.h"
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/support/string.h"
#include "src/core/transport/chttp2/bin_encoder.h"
#include "test/core/util/test_config.h"
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)

@ -41,6 +41,7 @@ import sys
CONFIG = [
'grpc-timeout',
'grpc-internal-encoding-request',
':path',
'grpc-encoding',
'grpc-accept-encoding',
@ -54,7 +55,13 @@ CONFIG = [
'identity',
'',
('grpc-status', '0'),
('grpc-status', '1'),
('grpc-status', '2'),
('grpc-encoding', 'identity'),
('grpc-encoding', 'gzip'),
('grpc-encoding', 'deflate'),
('te', 'trailers'),
('content-type', 'application/grpc'),
(':method', 'POST'),
(':status', '200'),
(':status', '404'),

@ -809,6 +809,7 @@ src/core/client_config/subchannel_factory.h \
src/core/client_config/subchannel_factory_decorators/add_channel_arg.h \
src/core/client_config/subchannel_factory_decorators/merge_channel_args.h \
src/core/client_config/uri_parser.h \
src/core/compression/algorithm_metadata.h \
src/core/compression/message_compress.h \
src/core/debug/trace.h \
src/core/httpcli/format_request.h \

@ -485,10 +485,10 @@ _CONFIGS = {
'msan': SimpleConfig('msan', timeout_multiplier=1.5),
'ubsan': SimpleConfig('ubsan'),
'asan': SimpleConfig('asan', timeout_multiplier=1.5, environ={
'ASAN_OPTIONS': 'detect_leaks=1:color=always:suppressions=tools/tsan_suppressions.txt',
'ASAN_OPTIONS': 'detect_leaks=1:color=always',
'LSAN_OPTIONS': 'report_objects=1'}),
'asan-noleaks': SimpleConfig('asan', environ={
'ASAN_OPTIONS': 'detect_leaks=0:color=always:suppressions=tools/tsan_suppressions.txt'}),
'ASAN_OPTIONS': 'detect_leaks=0:color=always'}),
'gcov': SimpleConfig('gcov'),
'memcheck': ValgrindConfig('valgrind', 'memcheck', ['--leak-check=full']),
'helgrind': ValgrindConfig('dbg', 'helgrind')

@ -14032,6 +14032,7 @@
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
"src/core/debug/trace.h",
"src/core/httpcli/format_request.h",
@ -14207,6 +14208,7 @@
"src/core/client_config/uri_parser.c",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm.c",
"src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.c",
"src/core/compression/message_compress.h",
"src/core/debug/trace.c",
@ -14547,6 +14549,7 @@
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
"src/core/debug/trace.h",
"src/core/httpcli/format_request.h",
@ -14708,6 +14711,7 @@
"src/core/client_config/uri_parser.c",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm.c",
"src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.c",
"src/core/compression/message_compress.h",
"src/core/debug/trace.c",

@ -295,6 +295,7 @@
<ClInclude Include="..\..\..\src\core\client_config\subchannel_factory_decorators\add_channel_arg.h" />
<ClInclude Include="..\..\..\src\core\client_config\subchannel_factory_decorators\merge_channel_args.h" />
<ClInclude Include="..\..\..\src\core\client_config\uri_parser.h" />
<ClInclude Include="..\..\..\src\core\compression\algorithm_metadata.h" />
<ClInclude Include="..\..\..\src\core\compression\message_compress.h" />
<ClInclude Include="..\..\..\src\core\debug\trace.h" />
<ClInclude Include="..\..\..\src\core\httpcli\format_request.h" />

@ -602,6 +602,9 @@
<ClInclude Include="..\..\..\src\core\client_config\uri_parser.h">
<Filter>src\core\client_config</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\core\compression\algorithm_metadata.h">
<Filter>src\core\compression</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\core\compression\message_compress.h">
<Filter>src\core\compression</Filter>
</ClInclude>

@ -274,6 +274,7 @@
<ClInclude Include="..\..\..\src\core\client_config\subchannel_factory_decorators\add_channel_arg.h" />
<ClInclude Include="..\..\..\src\core\client_config\subchannel_factory_decorators\merge_channel_args.h" />
<ClInclude Include="..\..\..\src\core\client_config\uri_parser.h" />
<ClInclude Include="..\..\..\src\core\compression\algorithm_metadata.h" />
<ClInclude Include="..\..\..\src\core\compression\message_compress.h" />
<ClInclude Include="..\..\..\src\core\debug\trace.h" />
<ClInclude Include="..\..\..\src\core\httpcli\format_request.h" />

@ -500,6 +500,9 @@
<ClInclude Include="..\..\..\src\core\client_config\uri_parser.h">
<Filter>src\core\client_config</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\core\compression\algorithm_metadata.h">
<Filter>src\core\compression</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\core\compression\message_compress.h">
<Filter>src\core\compression</Filter>
</ClInclude>

Loading…
Cancel
Save