Capture :path, and send it separately

pull/151/head
Craig Tiller 10 years ago committed by Craig Tiller
parent 85eea08ba8
commit d2d0a1184e
  1. 11
      src/core/channel/channel_stack.c
  2. 2
      src/core/channel/channel_stack.h
  3. 30
      src/core/channel/http_server_filter.c

@ -202,6 +202,17 @@ grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) {
static void do_nothing(void *user_data, grpc_op_error error) {} static void do_nothing(void *user_data, grpc_op_error error) {}
void grpc_call_element_recv_metadata(grpc_call_element *cur_elem,
grpc_mdelem *mdelem) {
grpc_call_op metadata_op;
metadata_op.type = GRPC_RECV_METADATA;
metadata_op.dir = GRPC_CALL_UP;
metadata_op.done_cb = do_nothing;
metadata_op.user_data = NULL;
metadata_op.data.metadata = grpc_mdelem_ref(mdelem);
grpc_call_next_op(cur_elem, &metadata_op);
}
void grpc_call_element_send_metadata(grpc_call_element *cur_elem, void grpc_call_element_send_metadata(grpc_call_element *cur_elem,
grpc_mdelem *mdelem) { grpc_mdelem *mdelem) {
grpc_call_op metadata_op; grpc_call_op metadata_op;

@ -292,6 +292,8 @@ void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
void grpc_call_element_send_metadata(grpc_call_element *cur_elem, void grpc_call_element_send_metadata(grpc_call_element *cur_elem,
grpc_mdelem *elem); grpc_mdelem *elem);
void grpc_call_element_recv_metadata(grpc_call_element *cur_elem,
grpc_mdelem *elem);
void grpc_call_element_send_cancel(grpc_call_element *cur_elem); void grpc_call_element_send_cancel(grpc_call_element *cur_elem);
#ifdef GRPC_CHANNEL_STACK_TRACE #ifdef GRPC_CHANNEL_STACK_TRACE

@ -37,10 +37,11 @@
#include <grpc/support/log.h> #include <grpc/support/log.h>
typedef struct call_data { typedef struct call_data {
int sent_status; gpr_uint8 sent_status;
int seen_scheme; gpr_uint8 seen_scheme;
int seen_method; gpr_uint8 seen_method;
int seen_te_trailers; gpr_uint8 seen_te_trailers;
grpc_mdelem *path;
} call_data; } call_data;
typedef struct channel_data { typedef struct channel_data {
@ -52,6 +53,7 @@ typedef struct channel_data {
grpc_mdelem *grpc_scheme; grpc_mdelem *grpc_scheme;
grpc_mdelem *content_type; grpc_mdelem *content_type;
grpc_mdelem *status; grpc_mdelem *status;
grpc_mdstr *path_key;
} channel_data; } channel_data;
/* used to silence 'variable not used' warnings */ /* used to silence 'variable not used' warnings */
@ -120,6 +122,13 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
grpc_mdelem_unref(op->data.metadata); grpc_mdelem_unref(op->data.metadata);
op->done_cb(op->user_data, GRPC_OP_OK); op->done_cb(op->user_data, GRPC_OP_OK);
grpc_call_element_send_cancel(elem); grpc_call_element_send_cancel(elem);
} else if (op->data.metadata->key == channeld->path_key) {
if (calld->path != NULL) {
gpr_log(GPR_ERROR, "Received :path twice");
grpc_mdelem_unref(calld->path);
}
calld->path = grpc_mdelem_ref(op->data.metadata);
op->done_cb(op->user_data, GRPC_OP_OK);
} else { } else {
/* pass the event up */ /* pass the event up */
grpc_call_next_op(elem, op); grpc_call_next_op(elem, op);
@ -129,7 +138,10 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
/* Have we seen the required http2 transport headers? /* Have we seen the required http2 transport headers?
(:method, :scheme, content-type, with :path and :authority covered (:method, :scheme, content-type, with :path and :authority covered
at the channel level right now) */ at the channel level right now) */
if (calld->seen_method && calld->seen_scheme && calld->seen_te_trailers) { if (calld->seen_method && calld->seen_scheme && calld->seen_te_trailers &&
calld->path) {
grpc_call_element_recv_metadata(elem, calld->path);
calld->path = NULL;
grpc_call_next_op(elem, op); grpc_call_next_op(elem, op);
} else { } else {
if (!calld->seen_method) { if (!calld->seen_method) {
@ -189,6 +201,7 @@ static void init_call_elem(grpc_call_element *elem,
ignore_unused(channeld); ignore_unused(channeld);
/* initialize members */ /* initialize members */
calld->path = NULL;
calld->sent_status = 0; calld->sent_status = 0;
calld->seen_scheme = 0; calld->seen_scheme = 0;
calld->seen_method = 0; calld->seen_method = 0;
@ -201,8 +214,11 @@ static void destroy_call_elem(grpc_call_element *elem) {
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data; channel_data *channeld = elem->channel_data;
ignore_unused(calld);
ignore_unused(channeld); ignore_unused(channeld);
if (calld->path) {
grpc_mdelem_unref(calld->path);
}
} }
/* Constructor for channel_data */ /* Constructor for channel_data */
@ -225,6 +241,7 @@ static void init_channel_elem(grpc_channel_element *elem,
channeld->http_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "http"); channeld->http_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "http");
channeld->https_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "https"); channeld->https_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "https");
channeld->grpc_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "grpc"); channeld->grpc_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "grpc");
channeld->path_key = grpc_mdstr_from_string(mdctx, ":path");
channeld->content_type = channeld->content_type =
grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc"); grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc");
} }
@ -241,6 +258,7 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
grpc_mdelem_unref(channeld->https_scheme); grpc_mdelem_unref(channeld->https_scheme);
grpc_mdelem_unref(channeld->grpc_scheme); grpc_mdelem_unref(channeld->grpc_scheme);
grpc_mdelem_unref(channeld->content_type); grpc_mdelem_unref(channeld->content_type);
grpc_mdstr_unref(channeld->path_key);
} }
const grpc_channel_filter grpc_http_server_filter = { const grpc_channel_filter grpc_http_server_filter = {

Loading…
Cancel
Save