diff options
author | Craig Tiller <ctiller@google.com> | 2016-11-16 16:05:01 -0800 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2016-11-16 16:05:01 -0800 |
commit | 66b14c125ef7a792ce277021619e8a14a2619dda (patch) | |
tree | 53aa69cb045258a49bb4b974742030e900d5f9f5 /src/core/lib/channel/http_client_filter.c | |
parent | 8cfe059dbc82bcfbd35647654a869369978b052e (diff) | |
parent | 1094c32f358cef7df323952c117a6773809019c0 (diff) |
Merge branch 'slice_interning' into eliminate_mdstr
Diffstat (limited to 'src/core/lib/channel/http_client_filter.c')
-rw-r--r-- | src/core/lib/channel/http_client_filter.c | 74 |
1 files changed, 52 insertions, 22 deletions
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index 2ef066c5b2..4b62a35750 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -36,6 +36,7 @@ #include <grpc/support/string_util.h> #include <string.h> #include "src/core/lib/profiling/timers.h" +#include "src/core/lib/slice/percent_encoding.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/support/string.h" @@ -58,6 +59,7 @@ typedef struct call_data { grpc_linked_mdelem payload_bin; grpc_metadata_batch *recv_initial_metadata; + grpc_metadata_batch *recv_trailing_metadata; uint8_t *payload_bytes; /* Vars to read data off of send_message */ @@ -71,14 +73,16 @@ typedef struct call_data { bool send_message_blocked; /** Closure to call when finished with the hc_on_recv hook */ - grpc_closure *on_done_recv; + grpc_closure *on_done_recv_initial_metadata; + grpc_closure *on_done_recv_trailing_metadata; grpc_closure *on_complete; grpc_closure *post_send; /** Receive closures are chained: we inject this closure as the on_done_recv up-call on transport_op, and remember to call our on_done_recv member after handling it. */ - grpc_closure hc_on_recv; + grpc_closure hc_on_recv_initial_metadata; + grpc_closure hc_on_recv_trailing_metadata; grpc_closure hc_on_complete; grpc_closure got_slice; grpc_closure send_done; @@ -90,13 +94,9 @@ typedef struct channel_data { size_t max_payload_size_for_get; } channel_data; -typedef struct { - grpc_call_element *elem; - grpc_exec_ctx *exec_ctx; -} client_recv_filter_args; - -static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) { - client_recv_filter_args *a = user_data; +static grpc_mdelem *client_recv_filter(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_mdelem *md) { + grpc_call_element *elem = user_data; if (md == GRPC_MDELEM_STATUS_200) { return NULL; } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_STATUS) == 0) { @@ -106,9 +106,19 @@ static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) { grpc_slice message = grpc_slice_from_copied_string(message_string); gpr_free(message_string); gpr_free(val); - grpc_call_element_send_close_with_message(a->exec_ctx, a->elem, + grpc_call_element_send_close_with_message(exec_ctx, elem, GRPC_STATUS_CANCELLED, &message); return NULL; + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_GRPC_MESSAGE) == 0) { + grpc_slice pct_decoded_msg = + grpc_permissive_percent_decode_slice(md->value); + if (grpc_slice_is_equivalent(pct_decoded_msg, md->value)) { + grpc_slice_unref(pct_decoded_msg); + return md; + } else { + return grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, + pct_decoded_msg); + } } else if (md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) { return NULL; } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_CONTENT_TYPE) == 0) { @@ -134,16 +144,24 @@ static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) { return md; } -static void hc_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_error *error) { +static void hc_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, + void *user_data, grpc_error *error) { grpc_call_element *elem = user_data; call_data *calld = elem->call_data; - client_recv_filter_args a; - a.elem = elem; - a.exec_ctx = exec_ctx; grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata, - client_recv_filter, &a); - calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, error); + client_recv_filter, elem); + grpc_closure_run(exec_ctx, calld->on_done_recv_initial_metadata, + GRPC_ERROR_REF(error)); +} + +static void hc_on_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, + void *user_data, grpc_error *error) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + grpc_metadata_batch_filter(exec_ctx, calld->recv_trailing_metadata, + client_recv_filter, elem); + grpc_closure_run(exec_ctx, calld->on_done_recv_trailing_metadata, + GRPC_ERROR_REF(error)); } static void hc_on_complete(grpc_exec_ctx *exec_ctx, void *user_data, @@ -164,7 +182,8 @@ static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error); } -static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { +static grpc_mdelem *client_strip_filter(grpc_exec_ctx *exec_ctx, + void *user_data, grpc_mdelem *md) { /* eat the things we'd like to set ourselves */ if (grpc_slice_cmp(md->key, GRPC_MDSTR_METHOD) == 0) return NULL; if (grpc_slice_cmp(md->key, GRPC_MDSTR_SCHEME) == 0) return NULL; @@ -286,8 +305,15 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, if (op->recv_initial_metadata != NULL) { /* substitute our callback for the higher callback */ calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv = op->recv_initial_metadata_ready; - op->recv_initial_metadata_ready = &calld->hc_on_recv; + calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->hc_on_recv_initial_metadata; + } + + if (op->recv_trailing_metadata != NULL) { + /* substitute our callback for the higher callback */ + calld->recv_trailing_metadata = op->recv_trailing_metadata; + calld->on_done_recv_trailing_metadata = op->on_complete; + op->on_complete = &calld->hc_on_recv_trailing_metadata; } } @@ -313,11 +339,15 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { call_data *calld = elem->call_data; - calld->on_done_recv = NULL; + calld->on_done_recv_initial_metadata = NULL; + calld->on_done_recv_trailing_metadata = NULL; calld->on_complete = NULL; calld->payload_bytes = NULL; grpc_slice_buffer_init(&calld->slices); - grpc_closure_init(&calld->hc_on_recv, hc_on_recv, elem); + grpc_closure_init(&calld->hc_on_recv_initial_metadata, + hc_on_recv_initial_metadata, elem); + grpc_closure_init(&calld->hc_on_recv_trailing_metadata, + hc_on_recv_trailing_metadata, elem); grpc_closure_init(&calld->hc_on_complete, hc_on_complete, elem); grpc_closure_init(&calld->got_slice, got_slice, elem); grpc_closure_init(&calld->send_done, send_done, elem); |