From 4d40ba326274a47e0e6badbb7d5e2d8646c6a324 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 9 Mar 2016 17:48:40 -0800 Subject: [PATCH] Wire up server side --- src/core/channel/http_client_filter.c | 2 +- src/core/channel/http_server_filter.c | 31 +++++++++++++++++++-------- src/core/surface/call.c | 2 +- src/core/surface/server.c | 3 +++ src/core/transport/transport.h | 3 ++- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index f08eb7e519a..0f44f4e844b 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -112,7 +112,7 @@ static void hc_mutate_op(grpc_call_element *elem, /* Send : prefixed headers, which have to be before any application layer headers. */ grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method, - op->idempotent_request + op->send_idempotent_request ? GRPC_MDELEM_METHOD_PUT : GRPC_MDELEM_METHOD_POST); grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme, diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c index 370f8dbe423..96a34e3a603 100644 --- a/src/core/channel/http_server_filter.c +++ b/src/core/channel/http_server_filter.c @@ -41,7 +41,7 @@ typedef struct call_data { uint8_t seen_path; - uint8_t seen_post; + uint8_t seen_method; uint8_t sent_status; uint8_t seen_scheme; uint8_t seen_te_trailers; @@ -50,6 +50,7 @@ typedef struct call_data { grpc_linked_mdelem content_type; grpc_metadata_batch *recv_initial_metadata; + bool *recv_idempotent_request; /** Closure to call when finished with the hs_on_recv hook */ grpc_closure *on_done_recv; /** Receive closures are chained: we inject this closure as the on_done_recv @@ -72,11 +73,16 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { /* Check if it is one of the headers we care about. */ if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST || - md == GRPC_MDELEM_SCHEME_HTTP || md == GRPC_MDELEM_SCHEME_HTTPS || + md == GRPC_MDELEM_METHOD_PUT || md == GRPC_MDELEM_SCHEME_HTTP || + md == GRPC_MDELEM_SCHEME_HTTPS || md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) { /* swallow it */ if (md == GRPC_MDELEM_METHOD_POST) { - calld->seen_post = 1; + calld->seen_method = 1; + *calld->recv_idempotent_request = false; + } else if (md == GRPC_MDELEM_METHOD_PUT) { + calld->seen_method = 1; + *calld->recv_idempotent_request = true; } else if (md->key == GRPC_MDSTR_SCHEME) { calld->seen_scheme = 1; } else if (md == GRPC_MDELEM_TE_TRAILERS) { @@ -142,7 +148,7 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { /* Have we seen the required http2 transport headers? (:method, :scheme, content-type, with :path and :authority covered at the channel level right now) */ - if (calld->seen_post && calld->seen_scheme && calld->seen_te_trailers && + if (calld->seen_method && calld->seen_scheme && calld->seen_te_trailers && calld->seen_path && calld->seen_authority) { /* do nothing */ } else { @@ -152,7 +158,7 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { if (!calld->seen_authority) { gpr_log(GPR_ERROR, "Missing :authority header"); } - if (!calld->seen_post) { + if (!calld->seen_method) { gpr_log(GPR_ERROR, "Missing :method header"); } if (!calld->seen_scheme) { @@ -227,7 +233,14 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) {} const grpc_channel_filter grpc_http_server_filter = { - hs_start_transport_op, grpc_channel_next_op, sizeof(call_data), - init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem, - sizeof(channel_data), init_channel_elem, destroy_channel_elem, - grpc_call_next_get_peer, "http-server"}; + hs_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "http-server"}; diff --git a/src/core/surface/call.c b/src/core/surface/call.c index cf5c928d84b..a369795ac83 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -1229,7 +1229,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, call->metadata_batch[0][0].deadline = call->send_deadline; stream_op.send_initial_metadata = &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]; - stream_op.idempotent_request = + stream_op.send_idempotent_request = (op->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) != 0; break; case GRPC_OP_SEND_MESSAGE: diff --git a/src/core/surface/server.c b/src/core/surface/server.c index 72b3065894d..e0b97725695 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -153,6 +153,7 @@ struct call_data { grpc_completion_queue *cq_new; grpc_metadata_batch *recv_initial_metadata; + bool recv_idempotent_request; grpc_metadata_array initial_metadata; grpc_closure got_initial_metadata; @@ -602,9 +603,11 @@ static void server_mutate_op(grpc_call_element *elem, call_data *calld = elem->call_data; if (op->recv_initial_metadata != NULL) { + GPR_ASSERT(op->recv_idempotent_request == NULL); calld->recv_initial_metadata = op->recv_initial_metadata; calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready; op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata; + op->recv_idempotent_request = &calld->recv_idempotent_request; } } diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h index 53f735ef237..0374c98087b 100644 --- a/src/core/transport/transport.h +++ b/src/core/transport/transport.h @@ -86,7 +86,7 @@ typedef struct grpc_transport_stream_op { grpc_metadata_batch *send_initial_metadata; /** Iff send_initial_metadata != NULL, flags if this is an idempotent request or not */ - bool idempotent_request; + bool send_idempotent_request; /** Send trailing metadata to the peer, from the provided metadata batch. */ grpc_metadata_batch *send_trailing_metadata; @@ -96,6 +96,7 @@ typedef struct grpc_transport_stream_op { /** Receive initial metadata from the stream, into provided metadata batch. */ grpc_metadata_batch *recv_initial_metadata; + bool *recv_idempotent_request; /** Should be enqueued when initial metadata is ready to be processed. */ grpc_closure *recv_initial_metadata_ready;