|
|
|
@ -40,10 +40,12 @@ |
|
|
|
|
typedef struct call_data { |
|
|
|
|
grpc_linked_mdelem method; |
|
|
|
|
grpc_linked_mdelem scheme; |
|
|
|
|
grpc_linked_mdelem authority; |
|
|
|
|
grpc_linked_mdelem te_trailers; |
|
|
|
|
grpc_linked_mdelem content_type; |
|
|
|
|
grpc_linked_mdelem user_agent; |
|
|
|
|
int sent_initial_metadata; |
|
|
|
|
int sent_authority; |
|
|
|
|
|
|
|
|
|
int got_initial_metadata; |
|
|
|
|
grpc_stream_op_buffer *recv_ops; |
|
|
|
@ -62,6 +64,7 @@ typedef struct channel_data { |
|
|
|
|
grpc_mdelem *scheme; |
|
|
|
|
grpc_mdelem *content_type; |
|
|
|
|
grpc_mdelem *status; |
|
|
|
|
grpc_mdelem *default_authority; |
|
|
|
|
/** complete user agent mdelem */ |
|
|
|
|
grpc_mdelem *user_agent; |
|
|
|
|
} channel_data; |
|
|
|
@ -100,6 +103,7 @@ static void hc_on_recv(void *user_data, int success) { |
|
|
|
|
|
|
|
|
|
static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { |
|
|
|
|
grpc_call_element *elem = user_data; |
|
|
|
|
call_data *calld = elem->call_data; |
|
|
|
|
channel_data *channeld = elem->channel_data; |
|
|
|
|
/* eat the things we'd like to set ourselves */ |
|
|
|
|
if (md->key == channeld->method->key) return NULL; |
|
|
|
@ -107,6 +111,9 @@ static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { |
|
|
|
|
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 (channeld->default_authority && channeld->default_authority->key == md->key) { |
|
|
|
|
calld->sent_authority = 1; |
|
|
|
|
} |
|
|
|
|
return md; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -130,6 +137,9 @@ static void hc_mutate_op(grpc_call_element *elem, |
|
|
|
|
GRPC_MDELEM_REF(channeld->method)); |
|
|
|
|
grpc_metadata_batch_add_head(&op->data.metadata, &calld->scheme, |
|
|
|
|
GRPC_MDELEM_REF(channeld->scheme)); |
|
|
|
|
if (channeld->default_authority && !calld->sent_authority) { |
|
|
|
|
grpc_metadata_batch_add_head(&op->data.metadata, &calld->authority, GRPC_MDELEM_REF(channeld->default_authority)); |
|
|
|
|
} |
|
|
|
|
grpc_metadata_batch_add_tail(&op->data.metadata, &calld->te_trailers, |
|
|
|
|
GRPC_MDELEM_REF(channeld->te_trailers)); |
|
|
|
|
grpc_metadata_batch_add_tail(&op->data.metadata, &calld->content_type, |
|
|
|
@ -162,6 +172,7 @@ static void init_call_elem(grpc_call_element *elem, |
|
|
|
|
call_data *calld = elem->call_data; |
|
|
|
|
calld->sent_initial_metadata = 0; |
|
|
|
|
calld->got_initial_metadata = 0; |
|
|
|
|
calld->sent_authority = 0; |
|
|
|
|
calld->on_done_recv = NULL; |
|
|
|
|
grpc_iomgr_closure_init(&calld->hc_on_recv, hc_on_recv, elem); |
|
|
|
|
if (initial_op) hc_mutate_op(elem, initial_op); |
|
|
|
@ -241,8 +252,10 @@ static grpc_mdstr *user_agent_from_args(grpc_mdctx *mdctx, |
|
|
|
|
|
|
|
|
|
/* Constructor for channel_data */ |
|
|
|
|
static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, |
|
|
|
|
const grpc_channel_args *args, grpc_mdctx *mdctx, |
|
|
|
|
const grpc_channel_args *channel_args, grpc_mdctx *mdctx, |
|
|
|
|
int is_first, int is_last) { |
|
|
|
|
size_t i; |
|
|
|
|
|
|
|
|
|
/* grab pointers to our data from the channel element */ |
|
|
|
|
channel_data *channeld = elem->channel_data; |
|
|
|
|
|
|
|
|
@ -251,17 +264,32 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, |
|
|
|
|
path */ |
|
|
|
|
GPR_ASSERT(!is_last); |
|
|
|
|
|
|
|
|
|
channeld->default_authority = NULL; |
|
|
|
|
if (channel_args) { |
|
|
|
|
for (i = 0; i < channel_args->num_args; i++) { |
|
|
|
|
if (0 == |
|
|
|
|
strcmp(channel_args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) { |
|
|
|
|
if (channel_args->args[i].type != GRPC_ARG_STRING) { |
|
|
|
|
gpr_log(GPR_ERROR, "%s: must be an string", |
|
|
|
|
GRPC_ARG_MAX_CONCURRENT_STREAMS); |
|
|
|
|
} else { |
|
|
|
|
channeld->default_authority = grpc_mdelem_from_strings(mdctx, ":authority", channel_args->args[i].value.string); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* initialize members */ |
|
|
|
|
channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers"); |
|
|
|
|
channeld->method = grpc_mdelem_from_strings(mdctx, ":method", "POST"); |
|
|
|
|
channeld->scheme = |
|
|
|
|
grpc_mdelem_from_strings(mdctx, ":scheme", scheme_from_args(args)); |
|
|
|
|
grpc_mdelem_from_strings(mdctx, ":scheme", scheme_from_args(channel_args)); |
|
|
|
|
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)); |
|
|
|
|
user_agent_from_args(mdctx, channel_args)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Destructor for channel data */ |
|
|
|
@ -275,6 +303,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) { |
|
|
|
|
GRPC_MDELEM_UNREF(channeld->content_type); |
|
|
|
|
GRPC_MDELEM_UNREF(channeld->status); |
|
|
|
|
GRPC_MDELEM_UNREF(channeld->user_agent); |
|
|
|
|
if (channeld->default_authority) { |
|
|
|
|
GRPC_MDELEM_UNREF(channeld->default_authority); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const grpc_channel_filter grpc_http_client_filter = { |
|
|
|
|