mirror of https://github.com/grpc/grpc-java.git
xds/federation: fix percent encoding on server side
Overlooked in #8857 on server side. Since `XdsNameResolver.percentEncodePath()` will be also used for server side, I moved the method to `XdsClient`.
This commit is contained in:
parent
7a9ceacafc
commit
a1c41e3d30
|
|
@ -24,6 +24,7 @@ import com.google.common.base.Joiner;
|
|||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.net.UrlEscapers;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.protobuf.Any;
|
||||
import io.grpc.Status;
|
||||
|
|
@ -106,6 +107,15 @@ abstract class XdsClient {
|
|||
return resourceName.replace(rawQuery, canonifiedQuery);
|
||||
}
|
||||
|
||||
static String percentEncodePath(String input) {
|
||||
Iterable<String> pathSegs = Splitter.on('/').split(input);
|
||||
List<String> encodedSegs = new ArrayList<>();
|
||||
for (String pathSeg : pathSegs) {
|
||||
encodedSegs.add(UrlEscapers.urlPathSegmentEscaper().escape(pathSeg));
|
||||
}
|
||||
return Joiner.on('/').join(encodedSegs);
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
abstract static class LdsUpdate implements ResourceUpdate {
|
||||
// Http level api listener configuration.
|
||||
|
|
|
|||
|
|
@ -22,12 +22,10 @@ import static io.grpc.xds.Bootstrapper.XDSTP_SCHEME;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.net.UrlEscapers;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.protobuf.util.Durations;
|
||||
import io.grpc.Attributes;
|
||||
|
|
@ -193,7 +191,7 @@ final class XdsNameResolver extends NameResolver {
|
|||
}
|
||||
String replacement = serviceAuthority;
|
||||
if (listenerNameTemplate.startsWith(XDSTP_SCHEME)) {
|
||||
replacement = percentEncodePath(replacement);
|
||||
replacement = XdsClient.percentEncodePath(replacement);
|
||||
}
|
||||
String ldsResourceName = expandPercentS(listenerNameTemplate, replacement);
|
||||
if (!XdsClient.isResourceNameValid(ldsResourceName, ResourceType.LDS.typeUrl())
|
||||
|
|
@ -208,16 +206,6 @@ final class XdsNameResolver extends NameResolver {
|
|||
resolveState.start();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static String percentEncodePath(String input) {
|
||||
Iterable<String> pathSegs = Splitter.on('/').split(input);
|
||||
List<String> encodedSegs = new ArrayList<>();
|
||||
for (String pathSeg : pathSegs) {
|
||||
encodedSegs.add(UrlEscapers.urlPathSegmentEscaper().escape(pathSeg));
|
||||
}
|
||||
return Joiner.on('/').join(encodedSegs);
|
||||
}
|
||||
|
||||
private static String expandPercentS(String template, String replacement) {
|
||||
return template.replace("%s", replacement);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import com.google.auto.value.AutoValue;
|
|||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.net.UrlEscapers;
|
||||
import com.google.common.util.concurrent.SettableFuture;
|
||||
import io.grpc.Attributes;
|
||||
import io.grpc.InternalServerInterceptors;
|
||||
|
|
@ -196,7 +195,7 @@ final class XdsServerWrapper extends Server {
|
|||
}
|
||||
String replacement = listenerAddress;
|
||||
if (listenerTemplate.startsWith(XDSTP_SCHEME)) {
|
||||
replacement = UrlEscapers.urlFragmentEscaper().escape(replacement);
|
||||
replacement = XdsClient.percentEncodePath(replacement);
|
||||
}
|
||||
discoveryState = new DiscoveryState(listenerTemplate.replaceAll("%s", replacement));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2619,6 +2619,31 @@ public class ClientXdsClientDataTest {
|
|||
.isEqualTo(expectedCanonifiedName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests compliance with RFC 3986 section 3.3
|
||||
* https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
|
||||
*/
|
||||
@Test
|
||||
public void percentEncodePath() {
|
||||
String unreserved = "aAzZ09-._~";
|
||||
assertThat(XdsClient.percentEncodePath(unreserved)).isEqualTo(unreserved);
|
||||
|
||||
String subDelims = "!$&'(*+,;/=";
|
||||
assertThat(XdsClient.percentEncodePath(subDelims)).isEqualTo(subDelims);
|
||||
|
||||
String colonAndAt = ":@";
|
||||
assertThat(XdsClient.percentEncodePath(colonAndAt)).isEqualTo(colonAndAt);
|
||||
|
||||
String needBeEncoded = "?#[]";
|
||||
assertThat(XdsClient.percentEncodePath(needBeEncoded)).isEqualTo("%3F%23%5B%5D");
|
||||
|
||||
String ipv4 = "0.0.0.0:8080";
|
||||
assertThat(XdsClient.percentEncodePath(ipv4)).isEqualTo(ipv4);
|
||||
|
||||
String ipv6 = "[::1]:8080";
|
||||
assertThat(XdsClient.percentEncodePath(ipv6)).isEqualTo("%5B::1%5D:8080");
|
||||
}
|
||||
|
||||
private static Filter buildHttpConnectionManagerFilter(HttpFilter... httpFilters) {
|
||||
return Filter.newBuilder()
|
||||
.setName("envoy.http_connection_manager")
|
||||
|
|
|
|||
|
|
@ -1955,31 +1955,6 @@ public class XdsNameResolverTest {
|
|||
.isFalse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests compliance with RFC 3986 section 3.3
|
||||
* https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
|
||||
*/
|
||||
@Test
|
||||
public void percentEncodePath() {
|
||||
String unreserved = "aAzZ09-._~";
|
||||
assertThat(XdsNameResolver.percentEncodePath(unreserved)).isEqualTo(unreserved);
|
||||
|
||||
String subDelims = "!$&'(*+,;/=";
|
||||
assertThat(XdsNameResolver.percentEncodePath(subDelims)).isEqualTo(subDelims);
|
||||
|
||||
String colonAndAt = ":@";
|
||||
assertThat(XdsNameResolver.percentEncodePath(colonAndAt)).isEqualTo(colonAndAt);
|
||||
|
||||
String needBeEncoded = "?#[]";
|
||||
assertThat(XdsNameResolver.percentEncodePath(needBeEncoded)).isEqualTo("%3F%23%5B%5D");
|
||||
|
||||
String ipv4 = "0.0.0.0:8080";
|
||||
assertThat(XdsNameResolver.percentEncodePath(ipv4)).isEqualTo(ipv4);
|
||||
|
||||
String ipv6 = "[::1]:8080";
|
||||
assertThat(XdsNameResolver.percentEncodePath(ipv6)).isEqualTo("%5B::1%5D:8080");
|
||||
}
|
||||
|
||||
private final class FakeXdsClientPoolFactory implements XdsClientPoolFactory {
|
||||
Map<String, ?> bootstrap;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue