Remove metadata context from the channel stack
diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c
index 3a0f68f..ec77916 100644
--- a/src/core/channel/http_client_filter.c
+++ b/src/core/channel/http_client_filter.c
@@ -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 @@
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 @@
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 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 @@
/* 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 @@
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 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 = {