diff --git a/xds/src/main/java/io/grpc/xds/RouteMatch.java b/xds/src/main/java/io/grpc/xds/RouteMatch.java index 5b52e71c2988..4fdbe7c29a77 100644 --- a/xds/src/main/java/io/grpc/xds/RouteMatch.java +++ b/xds/src/main/java/io/grpc/xds/RouteMatch.java @@ -65,7 +65,16 @@ boolean matches(String path, Map> headers) { return false; } for (HeaderMatcher headerMatcher : headerMatchers) { - if (!headerMatcher.matchesValue(headers.get(headerMatcher.getName()))) { + Iterable headerValues = headers.get(headerMatcher.getName()); + // Special cases for hiding headers: "grpc-previous-rpc-attempts". + if (headerMatcher.getName().equals("grpc-previous-rpc-attempts")) { + headerValues = null; + } + // Special case for exposing headers: "content-type". + if (headerMatcher.getName().equals("content-type")) { + headerValues = Collections.singletonList("application/grpc"); + } + if (!headerMatcher.matchesValue(headerValues)) { return false; } } diff --git a/xds/src/test/java/io/grpc/xds/RouteMatchTest.java b/xds/src/test/java/io/grpc/xds/RouteMatchTest.java index 712758e11685..463473d7fc68 100644 --- a/xds/src/test/java/io/grpc/xds/RouteMatchTest.java +++ b/xds/src/test/java/io/grpc/xds/RouteMatchTest.java @@ -40,7 +40,7 @@ public class RouteMatchTest { @Before public void setUp() { - headers.put("content-type", Collections.singletonList("application/grpc")); + headers.put("authority", Collections.singletonList("foo.googleapis.com")); headers.put("grpc-encoding", Collections.singletonList("gzip")); headers.put("user-agent", Collections.singletonList("gRPC-Java")); headers.put("content-length", Collections.singletonList("1000")); @@ -79,7 +79,7 @@ public void routeMatching_withHeaders() { new HeaderMatcher( "grpc-encoding", "gzip", null, null, null, null, null, false), new HeaderMatcher( - "content-type", null, Pattern.compile(".*grpc.*"), null, null, null, + "authority", null, Pattern.compile(".*googleapis.*"), null, null, null, null, false), new HeaderMatcher( "content-length", null, null, new Range(100, 10000), null, null, null, false), @@ -93,7 +93,7 @@ public void routeMatching_withHeaders() { new PathMatcher("/FooService/barMethod", null, null), Collections.singletonList( new HeaderMatcher( - "content-type", null, Pattern.compile(".*grpc.*"), null, null, null, + "authority", null, Pattern.compile(".*googleapis.*"), null, null, null, null, true)), null); assertThat(routeMatch2.matches("/FooService/barMethod", headers)).isFalse(); @@ -161,6 +161,30 @@ public void routeMatching_withRuntimeFraction() { assertThat(routeMatch2.matches("/FooService/barMethod", headers)).isFalse(); } + @Test + public void headerMatching_specialCaseGrpcHeaders() { + Map> headers = new HashMap<>(); + headers.put("grpc-previous-rpc-attempts", Collections.singletonList("0")); + + RouteMatch routeMatch1 = + new RouteMatch(new PathMatcher("/FooService/barMethod", null, null), + Arrays.asList( + new HeaderMatcher( + "grpc-previous-rpc-attempts", "0", null, null, null, null, + null, false)), + null); + assertThat(routeMatch1.matches("/FooService/barMethod", headers)).isFalse(); + + RouteMatch routeMatch2 = + new RouteMatch(new PathMatcher("/FooService/barMethod", null, null), + Arrays.asList( + new HeaderMatcher( + "content-type", "application/grpc", null, null, null, null, + null, false)), + null); + assertThat(routeMatch2.matches("/FooService/barMethod", headers)).isTrue(); + } + private static final class FakeRandom implements ThreadSafeRandom { private final int value;