| 
					
				 | 
			
			
				@@ -36,17 +36,24 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <string.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <grpc/support/log.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+typedef enum { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  NOT_RECEIVED, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  POST, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GET 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} known_method_type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 typedef struct call_data { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  known_method_type seen_method; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_uint8 sent_status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_uint8 seen_scheme; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gpr_uint8 seen_method; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_uint8 seen_te_trailers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_mdelem *path; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } call_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 typedef struct channel_data { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_mdelem *te_trailers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_mdelem *method; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_mdelem *method_get; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_mdelem *method_post; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_mdelem *http_scheme; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_mdelem *https_scheme; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* TODO(klempner): Remove this once we stop using it */ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -75,14 +82,17 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case GRPC_RECV_METADATA: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       /* Check if it is one of the headers we care about. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if (op->data.metadata == channeld->te_trailers || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          op->data.metadata == channeld->method || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          op->data.metadata == channeld->method_get || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          op->data.metadata == channeld->method_post || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           op->data.metadata == channeld->http_scheme || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           op->data.metadata == channeld->https_scheme || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           op->data.metadata == channeld->grpc_scheme || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           op->data.metadata == channeld->content_type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /* swallow it */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (op->data.metadata == channeld->method) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          calld->seen_method = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (op->data.metadata == channeld->method_get) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          calld->seen_method = GET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (op->data.metadata == channeld->method_post) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          calld->seen_method = POST; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else if (op->data.metadata->key == channeld->http_scheme->key) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           calld->seen_scheme = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else if (op->data.metadata == channeld->te_trailers) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -110,7 +120,7 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         grpc_mdelem_unref(op->data.metadata); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         op->done_cb(op->user_data, GRPC_OP_OK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } else if (op->data.metadata->key == channeld->te_trailers->key || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 op->data.metadata->key == channeld->method->key || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 op->data.metadata->key == channeld->method_post->key || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                  op->data.metadata->key == channeld->http_scheme->key || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                  op->data.metadata->key == channeld->content_type->key) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         gpr_log(GPR_ERROR, "Invalid %s: header: '%s'", 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -138,17 +148,19 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       /* 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_method && calld->seen_scheme && calld->seen_te_trailers && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (calld->seen_method == POST && 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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!calld->seen_method) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (calld->seen_method == NOT_RECEIVED) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           gpr_log(GPR_ERROR, "Missing :method header"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (!calld->seen_scheme) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!calld->seen_scheme) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           gpr_log(GPR_ERROR, "Missing :scheme header"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (!calld->seen_te_trailers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!calld->seen_te_trailers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           gpr_log(GPR_ERROR, "Missing te trailers header"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /* Error this call out */ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -204,7 +216,7 @@ static void init_call_elem(grpc_call_element *elem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   calld->path = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   calld->sent_status = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   calld->seen_scheme = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  calld->seen_method = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  calld->seen_method = NOT_RECEIVED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   calld->seen_te_trailers = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -237,7 +249,8 @@ static void init_channel_elem(grpc_channel_element *elem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* initialize members */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   channeld->status = grpc_mdelem_from_strings(mdctx, ":status", "200"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  channeld->method = grpc_mdelem_from_strings(mdctx, ":method", "POST"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  channeld->method_post = grpc_mdelem_from_strings(mdctx, ":method", "POST"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  channeld->method_get = grpc_mdelem_from_strings(mdctx, ":method", "GET"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   channeld->http_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "http"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   channeld->https_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "https"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   channeld->grpc_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "grpc"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -253,7 +266,8 @@ static void destroy_channel_elem(grpc_channel_element *elem) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_mdelem_unref(channeld->te_trailers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_mdelem_unref(channeld->status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_mdelem_unref(channeld->method); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_mdelem_unref(channeld->method_post); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_mdelem_unref(channeld->method_get); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_mdelem_unref(channeld->http_scheme); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_mdelem_unref(channeld->https_scheme); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_mdelem_unref(channeld->grpc_scheme); 
			 |