Switching to batch oriented metadata passing
diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c
index 3ccc39b..5506fa1 100644
--- a/src/core/channel/http_client_filter.c
+++ b/src/core/channel/http_client_filter.c
@@ -35,7 +35,10 @@
#include <grpc/support/log.h>
typedef struct call_data {
- int sent_headers;
+ grpc_linked_mdelem method;
+ grpc_linked_mdelem scheme;
+ grpc_linked_mdelem te_trailers;
+ grpc_linked_mdelem content_type;
} call_data;
typedef struct channel_data {
@@ -49,6 +52,18 @@
/* used to silence 'variable not used' warnings */
static void ignore_unused(void *ignored) {}
+static grpc_mdelem *client_filter(void *user_data, grpc_mdelem *md) {
+ grpc_call_element *elem = user_data;
+ channel_data *channeld = elem->channel_data;
+ if (md == channeld->status) {
+ return NULL;
+ } else if (md->key == channeld->status->key) {
+ grpc_call_element_send_cancel(elem);
+ return NULL;
+ }
+ return md;
+}
+
/* Called either:
- in response to an API call (or similar) from above, to send something
- a network event (or similar) from below, to receive something
@@ -61,42 +76,19 @@
channel_data *channeld = elem->channel_data;
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
- 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, grpc_mdelem_ref(channeld->method));
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->scheme));
- }
- grpc_call_next_op(elem, op);
- break;
- case GRPC_SEND_START:
- if (!calld->sent_headers) {
- /* Send : prefixed headers, if we haven't already */
- calld->sent_headers = 1;
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->method));
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->scheme));
- }
- /* Send non : prefixed headers */
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->te_trailers));
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->content_type));
+ /* Send : prefixed headers, which have to be before any application
+ * layer headers. */
+ grpc_call_op_metadata_add_head(&op->data.metadata, &calld->method, grpc_mdelem_ref(channeld->method));
+ grpc_call_op_metadata_add_head(&op->data.metadata, &calld->scheme, grpc_mdelem_ref(channeld->scheme));
+ grpc_call_op_metadata_add_tail(&op->data.metadata, &calld->te_trailers, grpc_mdelem_ref(channeld->te_trailers));
+ grpc_call_op_metadata_add_tail(&op->data.metadata, &calld->content_type, grpc_mdelem_ref(channeld->content_type));
grpc_call_next_op(elem, op);
break;
case GRPC_RECV_METADATA:
- if (op->data.metadata == channeld->status) {
- grpc_mdelem_unref(op->data.metadata);
- op->done_cb(op->user_data, GRPC_OP_OK);
- } else if (op->data.metadata->key == channeld->status->key) {
- grpc_mdelem_unref(op->data.metadata);
- op->done_cb(op->user_data, GRPC_OP_OK);
- grpc_call_element_send_cancel(elem);
- } else {
- grpc_call_next_op(elem, op);
- }
+ grpc_call_op_metadata_filter(&op->data.metadata, client_filter, elem);
+ grpc_call_next_op(elem, op);
break;
default:
/* pass control up or down the stack depending on op->dir */
@@ -125,14 +117,6 @@
/* Constructor for call_data */
static void init_call_elem(grpc_call_element *elem,
const void *server_transport_data) {
- /* grab pointers to our data from the call element */
- call_data *calld = elem->call_data;
- channel_data *channeld = elem->channel_data;
-
- ignore_unused(channeld);
-
- /* initialize members */
- calld->sent_headers = 0;
}
/* Destructor for call_data */