From c5b1eef8b1e6d56a9f3c25962d815ae6579c78ee Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Tue, 26 Apr 2016 14:16:20 -0700
Subject: [PATCH] Change C implementation to not log an "Unexpected
 content-type" message when the header includes a semicolon.

---
 src/core/lib/channel/http_server_filter.c     |  9 ++++----
 .../tests/server_registered_method.headers    |  2 +-
 test/core/bad_client/tests/simple_request.c   | 22 +++++++++++++++++++
 .../tests/simple_request_unusual2.headers     | 13 +++++++++++
 4 files changed, 41 insertions(+), 5 deletions(-)
 create mode 100644 test/core/bad_client/tests/simple_request_unusual2.headers

diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index c140c61b8f..ad3462bff4 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -92,8 +92,10 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
        require */
     return NULL;
   } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) {
-    if (strncmp(grpc_mdstr_as_c_string(md->value), "application/grpc+", 17) ==
-        0) {
+    const char* value_str = grpc_mdstr_as_c_string(md->value);
+    if (strncmp(value_str, "application/grpc", 16) == 0 &&
+        (strlen(value_str) == 16 ||
+         value_str[16] == '+' || value_str[16] == ';')) {
       /* Although the C implementation doesn't (currently) generate them,
          any custom +-suffix is explicitly valid. */
       /* TODO(klempner): We should consider preallocating common values such
@@ -102,8 +104,7 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
     } else {
       /* TODO(klempner): We're currently allowing this, but we shouldn't
          see it without a proxy so log for now. */
-      gpr_log(GPR_INFO, "Unexpected content-type %s",
-              grpc_mdstr_as_c_string(md->value));
+      gpr_log(GPR_INFO, "Unexpected content-type %s", value_str);
     }
     return NULL;
   } else if (md->key == GRPC_MDSTR_TE || md->key == GRPC_MDSTR_METHOD ||
diff --git a/test/core/bad_client/tests/server_registered_method.headers b/test/core/bad_client/tests/server_registered_method.headers
index 06ee73c82e..2640cc9cb8 100644
--- a/test/core/bad_client/tests/server_registered_method.headers
+++ b/test/core/bad_client/tests/server_registered_method.headers
@@ -1,4 +1,4 @@
-# headers used in simple_request.c
+# headers used in server_registered_method.c
 # use tools/codegen/core/gen_header_frame.py to generate the binary strings
 # contained in the source code
 :path: /registered/bar
diff --git a/test/core/bad_client/tests/simple_request.c b/test/core/bad_client/tests/simple_request.c
index ac0fdde876..d6b85aefb5 100644
--- a/test/core/bad_client/tests/simple_request.c
+++ b/test/core/bad_client/tests/simple_request.c
@@ -77,6 +77,27 @@
   "\x10\x0cgrpc-timeout\x02"                                               \
   "5S"
 
+#define PFX_STR_UNUSUAL2                                                   \
+  "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"                                       \
+  "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */              \
+  "\x00\x00\xf4\x01\x04\x00\x00\x00\x01" /* headers: generated from        \
+                                            simple_request_unusual2.headers \
+                                            in this directory */           \
+  "\x10\x05:path\x08/foo/bar"                                              \
+  "\x10\x07:scheme\x04http"                                                \
+  "\x10\x07:method\x04POST"                                                \
+  "\x10\x04host\x09localhost"                                              \
+  "\x10\x0c"                                                               \
+  "content-type\x1e"                                                       \
+  "application/grpc;this-is-valid"                                         \
+  "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"                  \
+  "\x10\x02te\x08trailers"                                                 \
+  "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"                 \
+  "\x10\x0cgrpc-timeout\x03"                                               \
+  "10S"                                                                    \
+  "\x10\x0cgrpc-timeout\x02"                                               \
+  "5S"
+
 static void *tag(intptr_t t) { return (void *)t; }
 
 static void verifier(grpc_server *server, grpc_completion_queue *cq,
@@ -120,6 +141,7 @@ int main(int argc, char **argv) {
   /* basic request: check that things are working */
   GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR, 0);
   GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR_UNUSUAL, 0);
+  GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR_UNUSUAL2, 0);
 
   /* push an illegal data frame */
   GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
diff --git a/test/core/bad_client/tests/simple_request_unusual2.headers b/test/core/bad_client/tests/simple_request_unusual2.headers
new file mode 100644
index 0000000000..f70920f372
--- /dev/null
+++ b/test/core/bad_client/tests/simple_request_unusual2.headers
@@ -0,0 +1,13 @@
+# headers used in simple_request.c
+# use tools/codegen/core/gen_header_frame.py to generate the binary strings
+# contained in the source code
+:path: /foo/bar
+:scheme: http
+:method: POST
+host: localhost
+content-type: application/grpc;this-is-valid
+grpc-accept-encoding: deflate,identity,gzip
+te: trailers
+user-agent: bad-client grpc-c/0.12.0.0 (linux)
+grpc-timeout: 10S
+grpc-timeout: 5S
-- 
GitLab