Skip to content

Commit 779b8ed

Browse files
committed
Fixup 12492: Address copilot comments
1 parent b28bd3c commit 779b8ed

File tree

8 files changed

+80
-43
lines changed

8 files changed

+80
-43
lines changed

xds/src/main/java/io/grpc/xds/internal/extauthz/ExtAuthzConfigParser.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import io.grpc.xds.internal.grpcservice.GrpcServiceConfigParser;
2525
import io.grpc.xds.internal.grpcservice.GrpcServiceParseException;
2626
import io.grpc.xds.internal.grpcservice.GrpcServiceXdsContextProvider;
27+
import io.grpc.xds.internal.headermutations.HeaderMutationRulesParseException;
2728
import io.grpc.xds.internal.headermutations.HeaderMutationRulesParser;
2829

2930

@@ -87,8 +88,12 @@ public static ExtAuthzConfig parse(
8788
}
8889

8990
if (extAuthzProto.hasDecoderHeaderMutationRules()) {
90-
builder.decoderHeaderMutationRules(
91-
HeaderMutationRulesParser.parse(extAuthzProto.getDecoderHeaderMutationRules()));
91+
try {
92+
builder.decoderHeaderMutationRules(
93+
HeaderMutationRulesParser.parse(extAuthzProto.getDecoderHeaderMutationRules()));
94+
} catch (HeaderMutationRulesParseException e) {
95+
throw new ExtAuthzParseException(e.getMessage(), e);
96+
}
9297
}
9398

9499
return builder.build();

xds/src/main/java/io/grpc/xds/internal/grpcservice/GrpcServiceConfigParser.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.google.common.collect.ImmutableList;
2222
import com.google.protobuf.Any;
2323
import com.google.protobuf.InvalidProtocolBufferException;
24+
import com.google.protobuf.util.Durations;
2425
import io.envoyproxy.envoy.config.core.v3.GrpcService;
2526
import io.envoyproxy.envoy.extensions.grpc_service.call_credentials.access_token.v3.AccessTokenCredentials;
2627
import io.envoyproxy.envoy.extensions.grpc_service.channel_credentials.xds.v3.XdsCredentials;
@@ -92,7 +93,7 @@ public static GrpcServiceConfig parse(GrpcService grpcServiceProto,
9293
} else {
9394
headerValue = HeaderValue.create(key, header.getValue());
9495
}
95-
if (HeaderValueValidationUtils.shouldIgnore(headerValue)) {
96+
if (HeaderValueValidationUtils.isDisallowed(headerValue)) {
9697
throw new GrpcServiceParseException("Invalid initial metadata header: " + key);
9798
}
9899
initialMetadata.add(headerValue);
@@ -101,9 +102,8 @@ public static GrpcServiceConfig parse(GrpcService grpcServiceProto,
101102

102103
if (grpcServiceProto.hasTimeout()) {
103104
com.google.protobuf.Duration timeout = grpcServiceProto.getTimeout();
104-
if (timeout.getSeconds() < 0 || timeout.getNanos() < 0
105-
|| (timeout.getSeconds() == 0 && timeout.getNanos() == 0)) {
106-
throw new GrpcServiceParseException("Timeout must be strictly positive");
105+
if (!Durations.isValid(timeout) || Durations.compare(timeout, Durations.ZERO) <= 0) {
106+
throw new GrpcServiceParseException("Timeout must be strictly positive and valid");
107107
}
108108
builder.timeout(Duration.ofSeconds(timeout.getSeconds(), timeout.getNanos()));
109109
}

xds/src/main/java/io/grpc/xds/internal/grpcservice/HeaderValueValidationUtils.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ public final class HeaderValueValidationUtils {
2727
private HeaderValueValidationUtils() {}
2828

2929
/**
30-
* Returns true if the header key should be ignored for mutations or validation.
30+
* Returns true if the header key is disallowed for mutations or validation.
3131
*
3232
* @param key The header key (e.g., "content-type")
3333
*/
34-
public static boolean shouldIgnore(String key) {
34+
public static boolean isDisallowed(String key) {
3535
if (key.isEmpty() || key.length() > MAX_HEADER_LENGTH) {
3636
return true;
3737
}
@@ -48,12 +48,12 @@ public static boolean shouldIgnore(String key) {
4848
}
4949

5050
/**
51-
* Returns true if the header value should be ignored.
51+
* Returns true if the header value is disallowed.
5252
*
5353
* @param header The HeaderValue containing key and values
5454
*/
55-
public static boolean shouldIgnore(HeaderValue header) {
56-
if (shouldIgnore(header.key())) {
55+
public static boolean isDisallowed(HeaderValue header) {
56+
if (isDisallowed(header.key())) {
5757
return true;
5858
}
5959
if (header.value().isPresent() && header.value().get().length() > MAX_HEADER_LENGTH) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public static Builder builder() {
5555
public abstract boolean disallowAll();
5656

5757
/**
58-
* If true, disallows any header mutation that would result in an invalid header value.
58+
* If true, a disallowed header mutation will result in an error instead of being ignored.
5959
*
6060
* @see HeaderMutationRules#getDisallowIsError()
6161
*/
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2025 The gRPC Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.grpc.xds.internal.headermutations;
18+
19+
/**
20+
* Exception thrown when parsing header mutation rules fails.
21+
*/
22+
public final class HeaderMutationRulesParseException extends Exception {
23+
private static final long serialVersionUID = 1L;
24+
25+
public HeaderMutationRulesParseException(String message) {
26+
super(message);
27+
}
28+
29+
public HeaderMutationRulesParseException(String message, Throwable cause) {
30+
super(message, cause);
31+
}
32+
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import com.google.re2j.Pattern;
2020
import com.google.re2j.PatternSyntaxException;
2121
import io.envoyproxy.envoy.config.common.mutation_rules.v3.HeaderMutationRules;
22-
import io.grpc.xds.internal.extauthz.ExtAuthzParseException;
2322

2423
/**
2524
* Parser for {@link io.envoyproxy.envoy.config.common.mutation_rules.v3.HeaderMutationRules}.
@@ -29,7 +28,7 @@ public final class HeaderMutationRulesParser {
2928
private HeaderMutationRulesParser() {}
3029

3130
public static HeaderMutationRulesConfig parse(HeaderMutationRules proto)
32-
throws ExtAuthzParseException {
31+
throws HeaderMutationRulesParseException {
3332
HeaderMutationRulesConfig.Builder builder = HeaderMutationRulesConfig.builder();
3433
builder.disallowAll(proto.getDisallowAll().getValue());
3534
builder.disallowIsError(proto.getDisallowIsError().getValue());
@@ -44,11 +43,12 @@ public static HeaderMutationRulesConfig parse(HeaderMutationRules proto)
4443
return builder.build();
4544
}
4645

47-
private static Pattern parseRegex(String regex, String fieldName) throws ExtAuthzParseException {
46+
private static Pattern parseRegex(String regex, String fieldName)
47+
throws HeaderMutationRulesParseException {
4848
try {
4949
return Pattern.compile(regex);
5050
} catch (PatternSyntaxException e) {
51-
throw new ExtAuthzParseException(
51+
throw new HeaderMutationRulesParseException(
5252
"Invalid regex pattern for " + fieldName + ": " + e.getMessage(), e);
5353
}
5454
}

xds/src/test/java/io/grpc/xds/internal/grpcservice/HeaderValueValidationUtilsTest.java

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,58 +30,58 @@
3030
public class HeaderValueValidationUtilsTest {
3131

3232
@Test
33-
public void shouldIgnore_string_emptyKey() {
34-
assertThat(HeaderValueValidationUtils.shouldIgnore("")).isTrue();
33+
public void isDisallowed_string_emptyKey() {
34+
assertThat(HeaderValueValidationUtils.isDisallowed("")).isTrue();
3535
}
3636

3737
@Test
38-
public void shouldIgnore_string_tooLongKey() {
38+
public void isDisallowed_string_tooLongKey() {
3939
String longKey = new String(new char[16385]).replace('\0', 'a');
40-
assertThat(HeaderValueValidationUtils.shouldIgnore(longKey)).isTrue();
40+
assertThat(HeaderValueValidationUtils.isDisallowed(longKey)).isTrue();
4141
}
4242

4343
@Test
44-
public void shouldIgnore_string_notLowercase() {
45-
assertThat(HeaderValueValidationUtils.shouldIgnore("Content-Type")).isTrue();
44+
public void isDisallowed_string_notLowercase() {
45+
assertThat(HeaderValueValidationUtils.isDisallowed("Content-Type")).isTrue();
4646
}
4747

4848
@Test
49-
public void shouldIgnore_string_grpcPrefix() {
50-
assertThat(HeaderValueValidationUtils.shouldIgnore("grpc-timeout")).isTrue();
49+
public void isDisallowed_string_grpcPrefix() {
50+
assertThat(HeaderValueValidationUtils.isDisallowed("grpc-timeout")).isTrue();
5151
}
5252

5353
@Test
54-
public void shouldIgnore_string_systemHeader_colon() {
55-
assertThat(HeaderValueValidationUtils.shouldIgnore(":authority")).isTrue();
54+
public void isDisallowed_string_systemHeader_colon() {
55+
assertThat(HeaderValueValidationUtils.isDisallowed(":authority")).isTrue();
5656
}
5757

5858
@Test
59-
public void shouldIgnore_string_systemHeader_host() {
60-
assertThat(HeaderValueValidationUtils.shouldIgnore("host")).isTrue();
59+
public void isDisallowed_string_systemHeader_host() {
60+
assertThat(HeaderValueValidationUtils.isDisallowed("host")).isTrue();
6161
}
6262

6363
@Test
64-
public void shouldIgnore_string_valid() {
65-
assertThat(HeaderValueValidationUtils.shouldIgnore("content-type")).isFalse();
64+
public void isDisallowed_string_valid() {
65+
assertThat(HeaderValueValidationUtils.isDisallowed("content-type")).isFalse();
6666
}
6767

6868
@Test
69-
public void shouldIgnore_headerValue_tooLongValue() {
69+
public void isDisallowed_headerValue_tooLongValue() {
7070
String longValue = new String(new char[16385]).replace('\0', 'v');
7171
HeaderValue header = HeaderValue.create("content-type", longValue);
72-
assertThat(HeaderValueValidationUtils.shouldIgnore(header)).isTrue();
72+
assertThat(HeaderValueValidationUtils.isDisallowed(header)).isTrue();
7373
}
7474

7575
@Test
76-
public void shouldIgnore_headerValue_tooLongRawValue() {
76+
public void isDisallowed_headerValue_tooLongRawValue() {
7777
ByteString longRawValue = ByteString.copyFrom(new byte[16385]);
7878
HeaderValue header = HeaderValue.create("content-type", longRawValue);
79-
assertThat(HeaderValueValidationUtils.shouldIgnore(header)).isTrue();
79+
assertThat(HeaderValueValidationUtils.isDisallowed(header)).isTrue();
8080
}
8181

8282
@Test
83-
public void shouldIgnore_headerValue_valid() {
83+
public void isDisallowed_headerValue_valid() {
8484
HeaderValue header = HeaderValue.create("content-type", "application/grpc");
85-
assertThat(HeaderValueValidationUtils.shouldIgnore(header)).isFalse();
85+
assertThat(HeaderValueValidationUtils.isDisallowed(header)).isFalse();
8686
}
8787
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import com.google.protobuf.BoolValue;
2323
import io.envoyproxy.envoy.config.common.mutation_rules.v3.HeaderMutationRules;
2424
import io.envoyproxy.envoy.type.matcher.v3.RegexMatcher;
25-
import io.grpc.xds.internal.extauthz.ExtAuthzParseException;
25+
import io.grpc.xds.internal.headermutations.HeaderMutationRulesParseException;
2626
import org.junit.Test;
2727
import org.junit.runner.RunWith;
2828
import org.junit.runners.JUnit4;
@@ -64,25 +64,25 @@ public void parse_protoWithNoExpressions_success() throws Exception {
6464
}
6565

6666
@Test
67-
public void parse_invalidRegexAllowExpression_throwsExtAuthzParseException() {
67+
public void parse_invalidRegexAllowExpression_throwsHeaderMutationRulesParseException() {
6868
HeaderMutationRules proto = HeaderMutationRules.newBuilder()
6969
.setAllowExpression(RegexMatcher.newBuilder().setRegex("allow-["))
7070
.build();
7171

72-
ExtAuthzParseException exception = assertThrows(
73-
ExtAuthzParseException.class, () -> HeaderMutationRulesParser.parse(proto));
72+
HeaderMutationRulesParseException exception = assertThrows(
73+
HeaderMutationRulesParseException.class, () -> HeaderMutationRulesParser.parse(proto));
7474

7575
assertThat(exception).hasMessageThat().contains("Invalid regex pattern for allow_expression");
7676
}
7777

7878
@Test
79-
public void parse_invalidRegexDisallowExpression_throwsExtAuthzParseException() {
79+
public void parse_invalidRegexDisallowExpression_throwsHeaderMutationRulesParseException() {
8080
HeaderMutationRules proto = HeaderMutationRules.newBuilder()
8181
.setDisallowExpression(RegexMatcher.newBuilder().setRegex("disallow-["))
8282
.build();
8383

84-
ExtAuthzParseException exception = assertThrows(
85-
ExtAuthzParseException.class, () -> HeaderMutationRulesParser.parse(proto));
84+
HeaderMutationRulesParseException exception = assertThrows(
85+
HeaderMutationRulesParseException.class, () -> HeaderMutationRulesParser.parse(proto));
8686

8787
assertThat(exception).hasMessageThat()
8888
.contains("Invalid regex pattern for disallow_expression");

0 commit comments

Comments
 (0)