diff options
author | Craig Tiller <ctiller@google.com> | 2015-07-21 12:19:34 -0700 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2015-07-21 12:19:34 -0700 |
commit | 90220b3241190f2b4bd28594ececf09b911fa2db (patch) | |
tree | 18351ed26dffa80f2ccc947611209c477683183f /src/core/channel | |
parent | 1c62870cc01583a8adf564580e70b42bfa6a835d (diff) | |
parent | 61e647819c85ded55f1005c01a6e1dd408218186 (diff) |
Merge github.com:grpc/grpc into sometimes-its-good-just-to-check-in-with-each-other
Diffstat (limited to 'src/core/channel')
-rw-r--r-- | src/core/channel/http_client_filter.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index 63e4912397..bc821b16fa 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -32,13 +32,17 @@ #include "src/core/channel/http_client_filter.h" #include <string.h> +#include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include "src/core/support/string.h" typedef struct call_data { grpc_linked_mdelem method; grpc_linked_mdelem scheme; grpc_linked_mdelem te_trailers; grpc_linked_mdelem content_type; + grpc_linked_mdelem user_agent; int sent_initial_metadata; int got_initial_metadata; @@ -58,6 +62,8 @@ typedef struct channel_data { grpc_mdelem *scheme; grpc_mdelem *content_type; grpc_mdelem *status; + /** complete user agent mdelem */ + grpc_mdelem *user_agent; } channel_data; /* used to silence 'variable not used' warnings */ @@ -115,6 +121,8 @@ static void hc_mutate_op(grpc_call_element *elem, GRPC_MDELEM_REF(channeld->te_trailers)); grpc_metadata_batch_add_tail(&op->data.metadata, &calld->content_type, GRPC_MDELEM_REF(channeld->content_type)); + grpc_metadata_batch_add_tail(&op->data.metadata, &calld->user_agent, + GRPC_MDELEM_REF(channeld->user_agent)); break; } } @@ -169,6 +177,55 @@ static const char *scheme_from_args(const grpc_channel_args *args) { 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; +} + /* Constructor for channel_data */ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, @@ -189,6 +246,9 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, channeld->content_type = grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc"); channeld->status = grpc_mdelem_from_strings(mdctx, ":status", "200"); + channeld->user_agent = grpc_mdelem_from_metadata_strings( + mdctx, grpc_mdstr_from_string(mdctx, "user-agent"), + user_agent_from_args(mdctx, args)); } /* Destructor for channel data */ @@ -201,6 +261,7 @@ static void destroy_channel_elem(grpc_channel_element *elem) { 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 = { |