|
|
|
@ -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 = { |
|
|
|
|