aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar klempner <klempner@google.com>2014-12-19 13:03:35 -0800
committerGravatar Craig Tiller <ctiller@google.com>2014-12-19 13:49:05 -0800
commitc463f746c90240d5b724c546660e90853ebed77d (patch)
treee0be20f930e0346abfeb95b23900ab9f822400a3
parent186cdab82eaca139c63f4742a57658e01e2571ec (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.c39
-rw-r--r--src/core/surface/call.c33
-rw-r--r--src/core/surface/call.h3
-rw-r--r--src/core/surface/channel.c36
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);
}