Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xds: add header matching special cases for hiding/exposing some gRPC headers #7224

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 10 additions & 1 deletion xds/src/main/java/io/grpc/xds/RouteMatch.java
Expand Up @@ -65,7 +65,16 @@ boolean matches(String path, Map<String, Iterable<String>> headers) {
return false;
}
for (HeaderMatcher headerMatcher : headerMatchers) {
if (!headerMatcher.matchesValue(headers.get(headerMatcher.getName()))) {
Iterable<String> 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;
}
}
Expand Down
30 changes: 27 additions & 3 deletions xds/src/test/java/io/grpc/xds/RouteMatchTest.java
Expand Up @@ -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"));
Expand Down Expand Up @@ -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),
Expand All @@ -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();
Expand Down Expand Up @@ -161,6 +161,30 @@ public void routeMatching_withRuntimeFraction() {
assertThat(routeMatch2.matches("/FooService/barMethod", headers)).isFalse();
}

@Test
public void headerMatching_specialCaseGrpcHeaders() {
Map<String, Iterable<String>> 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;

Expand Down