diff options
author | klempner <klempner@google.com> | 2014-12-19 13:03:35 -0800 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2014-12-19 13:49:05 -0800 |
commit | c463f746c90240d5b724c546660e90853ebed77d (patch) | |
tree | e0be20f930e0346abfeb95b23900ab9f822400a3 | |
parent | 186cdab82eaca139c63f4742a57658e01e2571ec (diff) |
Pre allocate client side strings per channel for method, scheme, path, and
authority.
For method and scheme, move these from channel to http_client_filter.
Change on 2014/12/19 by klempner <klempner@google.com>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=82536909
-rw-r--r-- | src/core/channel/http_client_filter.c | 39 | ||||
-rw-r--r-- | src/core/surface/call.c | 33 | ||||
-rw-r--r-- | src/core/surface/call.h | 3 | ||||
-rw-r--r-- | src/core/surface/channel.c | 36 |
4 files changed, 80 insertions, 31 deletions
diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index 949f1fefeb..98e26aa563 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -34,11 +34,14 @@ #include "src/core/channel/http_client_filter.h" #include <grpc/support/log.h> -typedef struct call_data { - int unused; /* C89 requires at least one struct element */ -} call_data; +typedef struct call_data { int sent_headers; } call_data; -typedef struct channel_data { grpc_mdelem *te_trailers; } channel_data; +typedef struct channel_data { + grpc_mdelem *te_trailers; + grpc_mdelem *method; + grpc_mdelem *scheme; + grpc_mdelem *content_type; +} channel_data; /* used to silence 'variable not used' warnings */ static void ignore_unused(void *ignored) {} @@ -58,9 +61,26 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem, ignore_unused(calld); switch (op->type) { + case GRPC_SEND_METADATA: + if (!calld->sent_headers) { + /* Send : prefixed headers, which have to be before any application + * layer headers. */ + calld->sent_headers = 1; + grpc_call_element_send_metadata(elem, channeld->method); + grpc_call_element_send_metadata(elem, channeld->scheme); + } + grpc_call_next_op(elem, op); + break; case GRPC_SEND_START: - /* just prior to starting, add a te: trailers header */ + if (!calld->sent_headers) { + /* Send : prefixed headers, if we haven't already */ + calld->sent_headers = 1; + grpc_call_element_send_metadata(elem, channeld->method); + grpc_call_element_send_metadata(elem, channeld->scheme); + } + /* Send non : prefixed headers */ grpc_call_element_send_metadata(elem, channeld->te_trailers); + grpc_call_element_send_metadata(elem, channeld->content_type); grpc_call_next_op(elem, op); break; default: @@ -97,7 +117,7 @@ static void init_call_elem(grpc_call_element *elem, ignore_unused(channeld); /* initialize members */ - calld->unused = 0; + calld->sent_headers = 0; } /* Destructor for call_data */ @@ -125,6 +145,10 @@ static void init_channel_elem(grpc_channel_element *elem, /* 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", "grpc"); + channeld->content_type = + grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc"); } /* Destructor for channel data */ @@ -133,6 +157,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) { 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); } const grpc_channel_filter grpc_http_client_filter = { diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 7e894f1f72..9ed617f665 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -291,11 +291,28 @@ void grpc_call_execute_op(grpc_call *call, grpc_call_op *op) { elem->filter->call_op(elem, NULL, op); } -grpc_call_error grpc_call_add_metadata(grpc_call *call, grpc_metadata *metadata, - gpr_uint32 flags) { +void grpc_call_add_mdelem(grpc_call *call, grpc_mdelem *mdelem, + gpr_uint32 flags) { grpc_call_element *elem; grpc_call_op op; + GPR_ASSERT(call->state < CALL_FINISHED); + + op.type = GRPC_SEND_METADATA; + op.dir = GRPC_CALL_DOWN; + op.flags = flags; + op.done_cb = do_nothing; + op.user_data = NULL; + op.data.metadata = mdelem; + + elem = CALL_ELEM_FROM_CALL(call, 0); + elem->filter->call_op(elem, NULL, &op); +} + +grpc_call_error grpc_call_add_metadata(grpc_call *call, grpc_metadata *metadata, + gpr_uint32 flags) { + grpc_mdelem *mdelem; + if (call->is_client) { if (call->state >= CALL_STARTED) { return GRPC_CALL_ERROR_ALREADY_INVOKED; @@ -306,18 +323,10 @@ grpc_call_error grpc_call_add_metadata(grpc_call *call, grpc_metadata *metadata, } } - op.type = GRPC_SEND_METADATA; - op.dir = GRPC_CALL_DOWN; - op.flags = flags; - op.done_cb = do_nothing; - op.user_data = NULL; - op.data.metadata = grpc_mdelem_from_string_and_buffer( + mdelem = grpc_mdelem_from_string_and_buffer( call->metadata_context, metadata->key, (gpr_uint8 *)metadata->value, metadata->value_length); - - elem = CALL_ELEM_FROM_CALL(call, 0); - elem->filter->call_op(elem, NULL, &op); - + grpc_call_add_mdelem(call, mdelem, flags); return GRPC_CALL_OK; } diff --git a/src/core/surface/call.h b/src/core/surface/call.h index 2c785a59fc..5c2ef3be18 100644 --- a/src/core/surface/call.h +++ b/src/core/surface/call.h @@ -70,4 +70,7 @@ grpc_call *grpc_call_from_top_element(grpc_call_element *surface_element); /* Get the metadata buffer. */ grpc_metadata_buffer *grpc_call_get_metadata_buffer(grpc_call *call); +void grpc_call_add_mdelem(grpc_call *call, grpc_mdelem *mdelem, + gpr_uint32 flags); + #endif /* __GRPC_INTERNAL_SURFACE_CALL_H__ */ diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index fe7a3afcc9..8ef13675fe 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -47,6 +47,8 @@ struct grpc_channel { grpc_mdctx *metadata_context; grpc_mdstr *grpc_status_string; grpc_mdstr *grpc_message_string; + grpc_mdstr *path_string; + grpc_mdstr *authority_string; }; #define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c)+1)) @@ -63,6 +65,8 @@ grpc_channel *grpc_channel_create_from_filters( channel->metadata_context = mdctx; channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status"); channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message"); + channel->path_string = grpc_mdstr_from_string(mdctx, ":path"); + channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority"); grpc_channel_stack_init(filters, num_filters, args, channel->metadata_context, CHANNEL_STACK_FROM_CHANNEL(channel)); return channel; @@ -74,7 +78,8 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, const char *method, const char *host, gpr_timespec absolute_deadline) { grpc_call *call; - grpc_metadata md; + grpc_mdelem *path_mdelem; + grpc_mdelem *authority_mdelem; if (!channel->is_client) { gpr_log(GPR_ERROR, "Cannot create a call on the server."); @@ -83,18 +88,21 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, const char *method, call = grpc_call_create(channel, NULL); -#define ADDMD(k, v) \ - do { \ - md.key = (k); \ - md.value = (char *)(v); \ - md.value_length = strlen((v)); \ - grpc_call_add_metadata(call, &md, 0); \ - } while (0) - ADDMD(":method", "POST"); - ADDMD(":scheme", "grpc"); - ADDMD(":path", method); - ADDMD(":authority", host); - ADDMD("content-type", "application/grpc"); + /* Add :path and :authority headers. */ + /* TODO(klempner): Consider optimizing this by stashing mdelems for common + values of method and host. */ + grpc_mdstr_ref(channel->path_string); + path_mdelem = grpc_mdelem_from_metadata_strings( + channel->metadata_context, channel->path_string, + grpc_mdstr_from_string(channel->metadata_context, method)); + grpc_call_add_mdelem(call, path_mdelem, 0); + + grpc_mdstr_ref(channel->authority_string); + authority_mdelem = grpc_mdelem_from_metadata_strings( + channel->metadata_context, channel->authority_string, + grpc_mdstr_from_string(channel->metadata_context, host)); + grpc_call_add_mdelem(call, authority_mdelem, 0); + if (0 != gpr_time_cmp(absolute_deadline, gpr_inf_future)) { grpc_call_op op; op.type = GRPC_SEND_DEADLINE; @@ -118,6 +126,8 @@ void grpc_channel_internal_unref(grpc_channel *channel) { grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel)); grpc_mdstr_unref(channel->grpc_status_string); grpc_mdstr_unref(channel->grpc_message_string); + grpc_mdstr_unref(channel->path_string); + grpc_mdstr_unref(channel->authority_string); grpc_mdctx_orphan(channel->metadata_context); gpr_free(channel); } |