Don't URL-encode slashes in gRPC request headers. (#6310)

Per internal document go/api-url-encoding (approved on 2017-04-20), "the
client library will %-encode everything except "/" and unreserved
characters, and the server will %-decode everything except "%2F"
and %2f"

This is currently affecting a private API which passes a resource name
(containing slashes) as a query parameter over gRPC.
diff --git a/google/api_core/gapic_v1/routing_header.py b/google/api_core/gapic_v1/routing_header.py
index ca35116..fc88bb6 100644
--- a/google/api_core/gapic_v1/routing_header.py
+++ b/google/api_core/gapic_v1/routing_header.py
@@ -20,6 +20,8 @@
 Generally, these headers are specified as gRPC metadata.
 """
 
+import sys
+
 from six.moves.urllib.parse import urlencode
 
 ROUTING_METADATA_KEY = 'x-goog-request-params'
@@ -35,7 +37,13 @@
     Returns:
         str: The routing header string.
     """
-    return urlencode(params)
+    if sys.version_info[0] < 3:
+        # Python 2 does not have the "safe" parameter for urlencode.
+        return urlencode(params).replace('%2F', '/')
+    return urlencode(
+        params,
+        # Per Google API policy (go/api-url-encoding), / is not encoded.
+        safe='/')
 
 
 def to_grpc_metadata(params):
diff --git a/tests/unit/gapic/test_routing_header.py b/tests/unit/gapic/test_routing_header.py
index d3a4bc3..6bedf29 100644
--- a/tests/unit/gapic/test_routing_header.py
+++ b/tests/unit/gapic/test_routing_header.py
@@ -22,6 +22,12 @@
     assert value == "name=meep&book.read=1"
 
 
+def test_to_routing_header_with_slashes():
+    params = [('name', 'me/ep'), ('book.read', '1&2')]
+    value = routing_header.to_routing_header(params)
+    assert value == "name=me/ep&book.read=1%262"
+
+
 def test_to_grpc_metadata():
     params = [('name', 'meep'), ('book.read', '1')]
     metadata = routing_header.to_grpc_metadata(params)