Skip to content

Commit 46c951d

Browse files
committed
Change HeaderMutationFilter to match envoy's implementation
1 parent f95c176 commit 46c951d

2 files changed

Lines changed: 39 additions & 11 deletions

File tree

xds/src/main/java/io/grpc/xds/internal/headermutations/HeaderMutationFilter.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,14 @@ private <T> ImmutableList<T> filterCollection(Collection<T> items,
6262
throws HeaderMutationDisallowedException {
6363
ImmutableList.Builder<T> allowed = ImmutableList.builder();
6464
for (T item : items) {
65-
if (isIgnoredPredicate.test(item)) {
66-
continue;
67-
}
68-
if (isAllowedPredicate.test(item)) {
65+
boolean isIgnored = isIgnoredPredicate.test(item);
66+
boolean isAllowed = isAllowedPredicate.test(item);
67+
68+
// TODO(sauravzg): The specification is ambiguous regarding whether system headers
69+
// should be silently ignored or trigger an error when disallowIsError is enabled.
70+
// We default to triggering errors matching Envoy's implementation.
71+
// Ref: https://github.com/grpc/proposal/pull/481#discussion_r3124453674
72+
if (!isIgnored && isAllowed) {
6973
allowed.add(item);
7074
} else if (disallowIsError()) {
7175
throw new HeaderMutationDisallowedException("Header mutation disallowed");

xds/src/test/java/io/grpc/xds/internal/headermutations/HeaderMutationFilterTest.java

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,39 @@ public void filter_ignoresUppercaseHeaders() throws HeaderMutationDisallowedExce
245245
assertThat(filtered.headersToRemove()).containsExactly("lower-remove");
246246
}
247247

248-
@Test
249-
public void filter_ignoresGrpcHeadersInRemoval() throws HeaderMutationDisallowedException {
250-
HeaderMutationFilter filter = new HeaderMutationFilter(Optional.empty());
248+
@Test(expected = HeaderMutationDisallowedException.class)
249+
public void filter_disallowIsError_throwsExceptionOnUppercaseHeaders()
250+
throws HeaderMutationDisallowedException {
251+
HeaderMutationRulesConfig rules =
252+
HeaderMutationRulesConfig.builder().disallowIsError(true).build();
253+
HeaderMutationFilter filter = new HeaderMutationFilter(Optional.of(rules));
251254
HeaderMutations mutations = HeaderMutations.create(
252-
ImmutableList.of(),
253-
ImmutableList.of("grpc-timeout", "valid-remove"));
255+
ImmutableList.of(header("Valid-Key", "value")),
256+
ImmutableList.of());
257+
filter.filter(mutations);
258+
}
254259

255-
HeaderMutations filtered = filter.filter(mutations);
260+
@Test(expected = HeaderMutationDisallowedException.class)
261+
public void filter_disallowIsError_throwsExceptionOnSystemHeadersRemoval()
262+
throws HeaderMutationDisallowedException {
263+
HeaderMutationRulesConfig rules =
264+
HeaderMutationRulesConfig.builder().disallowIsError(true).build();
265+
HeaderMutationFilter filter = new HeaderMutationFilter(Optional.of(rules));
266+
HeaderMutations mutations = HeaderMutations.create(
267+
ImmutableList.of(),
268+
ImmutableList.of(":path"));
269+
filter.filter(mutations);
270+
}
256271

257-
assertThat(filtered.headersToRemove()).containsExactly("valid-remove");
272+
@Test(expected = HeaderMutationDisallowedException.class)
273+
public void filter_disallowIsError_throwsExceptionOnSystemHeadersModification()
274+
throws HeaderMutationDisallowedException {
275+
HeaderMutationRulesConfig rules =
276+
HeaderMutationRulesConfig.builder().disallowIsError(true).build();
277+
HeaderMutationFilter filter = new HeaderMutationFilter(Optional.of(rules));
278+
HeaderMutations mutations = HeaderMutations.create(
279+
ImmutableList.of(header(":path", "/new-path")),
280+
ImmutableList.of());
281+
filter.filter(mutations);
258282
}
259283
}

0 commit comments

Comments
 (0)