diff options
Diffstat (limited to 'src/core/lib/channel')
-rw-r--r-- | src/core/lib/channel/channel_args.c | 26 | ||||
-rw-r--r-- | src/core/lib/channel/channel_args.h | 2 | ||||
-rw-r--r-- | src/core/lib/channel/channel_stack.c | 22 | ||||
-rw-r--r-- | src/core/lib/channel/channel_stack.h | 38 | ||||
-rw-r--r-- | src/core/lib/channel/channel_stack_builder.c | 4 | ||||
-rw-r--r-- | src/core/lib/channel/compress_filter.c | 47 | ||||
-rw-r--r-- | src/core/lib/channel/compress_filter.h | 6 | ||||
-rw-r--r-- | src/core/lib/channel/connected_channel.c | 12 | ||||
-rw-r--r-- | src/core/lib/channel/http_client_filter.c | 37 | ||||
-rw-r--r-- | src/core/lib/channel/http_client_filter.h | 2 | ||||
-rw-r--r-- | src/core/lib/channel/http_server_filter.c | 6 |
11 files changed, 127 insertions, 75 deletions
diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c index 569be4dc28..79ceeb66b3 100644 --- a/src/core/lib/channel/channel_args.c +++ b/src/core/lib/channel/channel_args.c @@ -35,6 +35,7 @@ #include <grpc/grpc.h> #include "src/core/lib/support/string.h" +#include <grpc/compression.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> @@ -148,6 +149,7 @@ grpc_channel_args *grpc_channel_args_normalize(const grpc_channel_args *a) { void grpc_channel_args_destroy(grpc_channel_args *a) { size_t i; + if (!a) return; for (i = 0; i < a->num_args; i++) { switch (a->args[i].type) { case GRPC_ARG_STRING: @@ -181,6 +183,7 @@ grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( grpc_channel_args *grpc_channel_args_set_compression_algorithm( grpc_channel_args *a, grpc_compression_algorithm algorithm) { + GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT); grpc_arg tmp; tmp.type = GRPC_ARG_INTEGER; tmp.key = GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM; @@ -200,7 +203,8 @@ static int find_compression_algorithm_states_bitset(const grpc_channel_args *a, !strcmp(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET, a->args[i].key)) { *states_arg = &a->args[i].value.integer; - return 1; /* GPR_TRUE */ + **states_arg |= 0x1; /* forcefully enable support for no compression */ + return 1; } } } @@ -209,15 +213,23 @@ static int find_compression_algorithm_states_bitset(const grpc_channel_args *a, grpc_channel_args *grpc_channel_args_compression_algorithm_set_state( grpc_channel_args **a, grpc_compression_algorithm algorithm, int state) { - int *states_arg; + int *states_arg = NULL; grpc_channel_args *result = *a; const int states_arg_found = find_compression_algorithm_states_bitset(*a, &states_arg); - if (states_arg_found) { + if (grpc_channel_args_get_compression_algorithm(*a) == algorithm && + state == 0) { + char *algo_name = NULL; + GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0); + gpr_log(GPR_ERROR, + "Tried to disable default compression algorithm '%s'. The " + "operation has been ignored.", + algo_name); + } else if (states_arg_found) { if (state != 0) { GPR_BITSET((unsigned *)states_arg, algorithm); - } else { + } else if (algorithm != GRPC_COMPRESS_NONE) { GPR_BITCLEAR((unsigned *)states_arg, algorithm); } } else { @@ -229,7 +241,7 @@ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state( tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; if (state != 0) { GPR_BITSET((unsigned *)&tmp.value.integer, algorithm); - } else { + } else if (algorithm != GRPC_COMPRESS_NONE) { GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm); } result = grpc_channel_args_copy_and_add(*a, &tmp, 1); @@ -239,11 +251,11 @@ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state( return result; } -int grpc_channel_args_compression_algorithm_get_states( +uint32_t grpc_channel_args_compression_algorithm_get_states( const grpc_channel_args *a) { int *states_arg; if (find_compression_algorithm_states_bitset(a, &states_arg)) { - return *states_arg; + return (uint32_t)*states_arg; } else { return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */ } diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h index 23c7b7b897..653d04f427 100644 --- a/src/core/lib/channel/channel_args.h +++ b/src/core/lib/channel/channel_args.h @@ -81,7 +81,7 @@ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state( * * The i-th bit of the returned bitset corresponds to the i-th entry in the * grpc_compression_algorithm enum. */ -int grpc_channel_args_compression_algorithm_get_states( +uint32_t grpc_channel_args_compression_algorithm_get_states( const grpc_channel_args *a); int grpc_channel_args_compare(const grpc_channel_args *a, diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c index ad182d1f69..42075b127b 100644 --- a/src/core/lib/channel/channel_stack.c +++ b/src/core/lib/channel/channel_stack.c @@ -106,6 +106,7 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs, const grpc_channel_filter **filters, size_t filter_count, const grpc_channel_args *channel_args, + grpc_transport *optional_transport, const char *name, grpc_channel_stack *stack) { size_t call_size = ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) + @@ -127,6 +128,7 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs, for (i = 0; i < filter_count; i++) { args.channel_stack = stack; args.channel_args = channel_args; + args.optional_transport = optional_transport; args.is_first = i == 0; args.is_last = i == (filter_count - 1); elems[i].filter = filters[i]; @@ -189,9 +191,9 @@ void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, } } -void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx, - grpc_call_stack *call_stack, - grpc_pollset *pollset) { +void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, + grpc_call_stack *call_stack, + grpc_polling_entity *pollent) { size_t count = call_stack->count; grpc_call_element *call_elems; char *user_data; @@ -203,17 +205,19 @@ void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx, /* init per-filter data */ for (i = 0; i < count; i++) { - call_elems[i].filter->set_pollset(exec_ctx, &call_elems[i], pollset); + call_elems[i].filter->set_pollset_or_pollset_set(exec_ctx, &call_elems[i], + pollent); user_data += ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); } } -void grpc_call_stack_ignore_set_pollset(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_pollset *pollset) {} +void grpc_call_stack_ignore_set_pollset_or_pollset_set( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_polling_entity *pollent) {} void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack, + const grpc_call_stats *call_stats, void *and_free_memory) { grpc_call_element *elems = CALL_ELEMS_FROM_STACK(stack); size_t count = stack->count; @@ -221,7 +225,7 @@ void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack, /* destroy per-filter data */ for (i = 0; i < count; i++) { - elems[i].filter->destroy_call_elem(exec_ctx, &elems[i], + elems[i].filter->destroy_call_elem(exec_ctx, &elems[i], call_stats, i == count - 1 ? and_free_memory : NULL); } } @@ -259,6 +263,6 @@ void grpc_call_element_send_cancel(grpc_exec_ctx *exec_ctx, grpc_call_element *cur_elem) { grpc_transport_stream_op op; memset(&op, 0, sizeof(op)); - op.cancel_with_status = GRPC_STATUS_CANCELLED; + op.cancel_error = GRPC_ERROR_CANCELLED; grpc_call_next_op(exec_ctx, cur_elem, &op); } diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 36c17cb467..41dd4a0d8a 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -45,7 +45,10 @@ #include <grpc/grpc.h> #include <grpc/support/log.h> +#include <grpc/support/time.h> + #include "src/core/lib/debug/trace.h" +#include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/transport/transport.h" typedef struct grpc_channel_element grpc_channel_element; @@ -57,6 +60,8 @@ typedef struct grpc_call_stack grpc_call_stack; typedef struct { grpc_channel_stack *channel_stack; const grpc_channel_args *channel_args; + /** Transport, iff it is known */ + grpc_transport *optional_transport; int is_first; int is_last; } grpc_channel_element_args; @@ -67,6 +72,12 @@ typedef struct { grpc_call_context_element *context; } grpc_call_element_args; +typedef struct { + grpc_transport_stream_stats transport_stream_stats; + gpr_timespec latency; /* From call creating to enqueing of received status */ + grpc_status_code final_status; +} grpc_call_stats; + /* Channel filters specify: 1. the amount of memory needed in the channel & call (via the sizeof_XXX members) @@ -101,14 +112,16 @@ typedef struct { argument. */ void (*init_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args); - void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_pollset *pollset); + void (*set_pollset_or_pollset_set)(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent); /* Destroy per call data. The filter does not need to do any chaining. The bottom filter of a stack will be passed a non-NULL pointer to \a and_free_memory that should be passed to gpr_free when destruction is complete. */ void (*destroy_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + const grpc_call_stats *stats, void *and_free_memory); /* sizeof(per channel data) */ @@ -187,6 +200,7 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg, const grpc_channel_filter **filters, size_t filter_count, const grpc_channel_args *args, + grpc_transport *optional_transport, const char *name, grpc_channel_stack *stack); /* Destroy a channel stack */ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, @@ -201,10 +215,11 @@ void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, grpc_call_context_element *context, const void *transport_server_data, grpc_call_stack *call_stack); -/* Set a pollset for a call stack: must occur before the first op is started */ -void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx, - grpc_call_stack *call_stack, - grpc_pollset *pollset); +/* Set a pollset or a pollset_set for a call stack: must occur before the first + * op is started */ +void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, + grpc_call_stack *call_stack, + grpc_polling_entity *pollent); #ifdef GRPC_STREAM_REFCOUNT_DEBUG #define GRPC_CALL_STACK_REF(call_stack, reason) \ @@ -228,13 +243,14 @@ void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx, /* Destroy a call stack */ void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack, + const grpc_call_stats *call_stats, void *and_free_memory); -/* Ignore set pollset - used by filters to implement the set_pollset method - if they don't care about pollsets at all. Does nothing. */ -void grpc_call_stack_ignore_set_pollset(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_pollset *pollset); +/* Ignore set pollset{_set} - used by filters if they don't care about pollsets + * at all. Does nothing. */ +void grpc_call_stack_ignore_set_pollset_or_pollset_set( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_polling_entity *pollent); /* Call the next operation in a call stack */ void grpc_call_next_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_transport_stream_op *op); diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c index a8646c9565..eda4968f48 100644 --- a/src/core/lib/channel/channel_stack_builder.c +++ b/src/core/lib/channel/channel_stack_builder.c @@ -257,8 +257,8 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx, // and initialize it grpc_channel_stack_init(exec_ctx, initial_refs, destroy, destroy_arg == NULL ? result : destroy_arg, filters, - num_filters, builder->args, builder->name, - channel_stack); + num_filters, builder->args, builder->transport, + builder->name, channel_stack); // run post-initialization functions i = 0; diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c index 27a87db0c2..32ebe53ee6 100644 --- a/src/core/lib/channel/compress_filter.c +++ b/src/core/lib/channel/compress_filter.c @@ -73,8 +73,8 @@ typedef struct call_data { typedef struct channel_data { /** The default, channel-level, compression algorithm */ grpc_compression_algorithm default_compression_algorithm; - /** Compression options for the channel */ - grpc_compression_options compression_options; + /** Bitset of enabled algorithms */ + uint32_t enabled_algorithms_bitset; /** Supported compression algorithms */ uint32_t supported_compression_algorithms; } channel_data; @@ -96,9 +96,8 @@ static grpc_mdelem *compression_md_filter(void *user_data, grpc_mdelem *md) { md_c_str); calld->compression_algorithm = GRPC_COMPRESS_NONE; } - if (grpc_compression_options_is_algorithm_enabled( - &channeld->compression_options, calld->compression_algorithm) == - 0) { + if (!GPR_BITGET(channeld->enabled_algorithms_bitset, + calld->compression_algorithm)) { gpr_log(GPR_ERROR, "Invalid compression algorithm: '%s' (previously disabled). " "Ignoring.", @@ -178,8 +177,8 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx, const float savings_ratio = 1.0f - (float)after_size / (float)before_size; GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm, &algo_name)); - gpr_log(GPR_DEBUG, - "Compressed[%s] %d bytes vs. %d bytes (%.2f%% savings)", + gpr_log(GPR_DEBUG, "Compressed[%s] %" PRIuPTR " bytes vs. %" PRIuPTR + " bytes (%.2f%% savings)", algo_name, before_size, after_size, 100 * savings_ratio); } gpr_slice_buffer_swap(&calld->slices, &tmp); @@ -189,10 +188,10 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx, char *algo_name; GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm, &algo_name)); - gpr_log( - GPR_DEBUG, - "Algorithm '%s' enabled but decided not to compress. Input size: %d", - algo_name, calld->slices.length); + gpr_log(GPR_DEBUG, + "Algorithm '%s' enabled but decided not to compress. Input size: " + "%" PRIuPTR, + algo_name, calld->slices.length); } } @@ -271,7 +270,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - void *ignored) { + const grpc_call_stats *stats, void *ignored) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; gpr_slice_buffer_destroy(&calld->slices); @@ -282,32 +281,26 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_channel_element_args *args) { channel_data *channeld = elem->channel_data; - grpc_compression_algorithm algo_idx; - grpc_compression_options_init(&channeld->compression_options); - channeld->compression_options.enabled_algorithms_bitset = - (uint32_t)grpc_channel_args_compression_algorithm_get_states( - args->channel_args); + channeld->enabled_algorithms_bitset = + grpc_channel_args_compression_algorithm_get_states(args->channel_args); channeld->default_compression_algorithm = grpc_channel_args_get_compression_algorithm(args->channel_args); /* Make sure the default isn't disabled. */ - if (!grpc_compression_options_is_algorithm_enabled( - &channeld->compression_options, - channeld->default_compression_algorithm)) { + if (!GPR_BITGET(channeld->enabled_algorithms_bitset, + channeld->default_compression_algorithm)) { gpr_log(GPR_DEBUG, "compression algorithm %d not enabled: switching to none", channeld->default_compression_algorithm); channeld->default_compression_algorithm = GRPC_COMPRESS_NONE; } - channeld->compression_options.default_compression_algorithm = - channeld->default_compression_algorithm; - channeld->supported_compression_algorithms = 0; - for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) { + channeld->supported_compression_algorithms = 1; /* always support identity */ + for (grpc_compression_algorithm algo_idx = 1; + algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) { /* skip disabled algorithms */ - if (grpc_compression_options_is_algorithm_enabled( - &channeld->compression_options, algo_idx) == 0) { + if (!GPR_BITGET(channeld->enabled_algorithms_bitset, algo_idx)) { continue; } channeld->supported_compression_algorithms |= 1u << algo_idx; @@ -325,7 +318,7 @@ const grpc_channel_filter grpc_compress_filter = { grpc_channel_next_op, sizeof(call_data), init_call_elem, - grpc_call_stack_ignore_set_pollset, + grpc_call_stack_ignore_set_pollset_or_pollset_set, destroy_call_elem, sizeof(channel_data), init_channel_elem, diff --git a/src/core/lib/channel/compress_filter.h b/src/core/lib/channel/compress_filter.h index 0ce5d08837..e4a2a829d5 100644 --- a/src/core/lib/channel/compress_filter.h +++ b/src/core/lib/channel/compress_filter.h @@ -34,9 +34,9 @@ #ifndef GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H #define GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H -#include "src/core/lib/channel/channel_stack.h" +#include <grpc/impl/codegen/compression_types.h> -#define GRPC_COMPRESS_REQUEST_ALGORITHM_KEY "grpc-internal-encoding-request" +#include "src/core/lib/channel/channel_stack.h" extern int grpc_compression_trace; @@ -48,7 +48,7 @@ extern int grpc_compression_trace; * - Channel configuration, as established at channel creation time. * - The metadata accompanying the outgoing data to be compressed. This is * taken as a request only. We may choose not to honor it. The metadata key - * is given by \a GRPC_COMPRESS_REQUEST_ALGORITHM_KEY. + * is given by \a GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY. * * Compression can be disabled for concrete messages (for instance in order to * prevent CRIME/BEAST type attacks) by having the GRPC_WRITE_NO_COMPRESS set in diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c index 68a3a7d6fd..0a7d27a1dc 100644 --- a/src/core/lib/channel/connected_channel.c +++ b/src/core/lib/channel/connected_channel.c @@ -93,16 +93,18 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, GPR_ASSERT(r == 0); } -static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_pollset *pollset) { +static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; - grpc_transport_set_pollset(exec_ctx, chand->transport, - TRANSPORT_STREAM_FROM_CALL_DATA(calld), pollset); + grpc_transport_set_pops(exec_ctx, chand->transport, + TRANSPORT_STREAM_FROM_CALL_DATA(calld), pollent); } /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + const grpc_call_stats *stats, void *and_free_memory) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; @@ -137,7 +139,7 @@ static const grpc_channel_filter connected_channel_filter = { con_start_transport_op, sizeof(call_data), init_call_elem, - set_pollset, + set_pollset_or_pollset_set, destroy_call_elem, sizeof(channel_data), init_channel_elem, diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index ced3d75cd2..ab6c6c9ef0 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -38,6 +38,10 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/support/string.h" #include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/transport_impl.h" + +#define EXPECTED_CONTENT_TYPE "application/grpc" +#define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1 typedef struct call_data { grpc_linked_mdelem method; @@ -74,7 +78,24 @@ static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) { } else if (md->key == GRPC_MDSTR_STATUS) { grpc_call_element_send_cancel(a->exec_ctx, a->elem); return NULL; + } else if (md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) { + return NULL; } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) { + const char *value_str = grpc_mdstr_as_c_string(md->value); + if (strncmp(value_str, EXPECTED_CONTENT_TYPE, + EXPECTED_CONTENT_TYPE_LENGTH) == 0 && + (value_str[EXPECTED_CONTENT_TYPE_LENGTH] == '+' || + value_str[EXPECTED_CONTENT_TYPE_LENGTH] == ';')) { + /* Although the C implementation doesn't (currently) generate them, + any custom +-suffix is explicitly valid. */ + /* TODO(klempner): We should consider preallocating common values such + as +proto or +json, or at least stashing them if we see them. */ + /* TODO(klempner): Should we be surfacing this to application code? */ + } else { + /* 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'", value_str); + } return NULL; } return md; @@ -157,7 +178,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - void *ignored) {} + const grpc_call_stats *stats, void *ignored) {} static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) { unsigned i; @@ -180,7 +201,8 @@ static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) { return GRPC_MDELEM_SCHEME_HTTP; } -static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args) { +static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args, + const char *transport_name) { gpr_strvec v; size_t i; int is_first = 1; @@ -202,8 +224,8 @@ static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args) { } } - gpr_asprintf(&tmp, "%sgrpc-c/%s (%s)", is_first ? "" : " ", - grpc_version_string(), GPR_PLATFORM_STRING); + gpr_asprintf(&tmp, "%sgrpc-c/%s (%s; %s)", is_first ? "" : " ", + grpc_version_string(), GPR_PLATFORM_STRING, transport_name); is_first = 0; gpr_strvec_add(&v, tmp); @@ -234,9 +256,12 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element_args *args) { channel_data *chand = elem->channel_data; GPR_ASSERT(!args->is_last); + GPR_ASSERT(args->optional_transport != NULL); chand->static_scheme = scheme_from_args(args->channel_args); chand->user_agent = grpc_mdelem_from_metadata_strings( - GRPC_MDSTR_USER_AGENT, user_agent_from_args(args->channel_args)); + GRPC_MDSTR_USER_AGENT, + user_agent_from_args(args->channel_args, + args->optional_transport->vtable->name)); } /* Destructor for channel data */ @@ -251,7 +276,7 @@ const grpc_channel_filter grpc_http_client_filter = { grpc_channel_next_op, sizeof(call_data), init_call_elem, - grpc_call_stack_ignore_set_pollset, + grpc_call_stack_ignore_set_pollset_or_pollset_set, destroy_call_elem, sizeof(channel_data), init_channel_elem, diff --git a/src/core/lib/channel/http_client_filter.h b/src/core/lib/channel/http_client_filter.h index a884b36318..47081175ea 100644 --- a/src/core/lib/channel/http_client_filter.h +++ b/src/core/lib/channel/http_client_filter.h @@ -1,5 +1,4 @@ /* - * * Copyright 2015, Google Inc. * All rights reserved. * @@ -39,6 +38,7 @@ /* Processes metadata on the client side for HTTP2 transports */ extern const grpc_channel_filter grpc_http_client_filter; +/* Channel arg to override the http2 :scheme header */ #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme" #endif /* GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H */ diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c index 876eaddc1e..d0beebd817 100644 --- a/src/core/lib/channel/http_server_filter.c +++ b/src/core/lib/channel/http_server_filter.c @@ -108,7 +108,7 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { } else { /* 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", value_str); + gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str); } return NULL; } else if (md->key == GRPC_MDSTR_TE || md->key == GRPC_MDSTR_METHOD || @@ -235,7 +235,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - void *ignored) {} + const grpc_call_stats *stats, void *ignored) {} /* Constructor for channel_data */ static void init_channel_elem(grpc_exec_ctx *exec_ctx, @@ -253,7 +253,7 @@ const grpc_channel_filter grpc_http_server_filter = { grpc_channel_next_op, sizeof(call_data), init_call_elem, - grpc_call_stack_ignore_set_pollset, + grpc_call_stack_ignore_set_pollset_or_pollset_set, destroy_call_elem, sizeof(channel_data), init_channel_elem, |