|
47 | 47 | import io.grpc.NameResolverRegistry; |
48 | 48 | import io.grpc.ProxyDetector; |
49 | 49 | import io.grpc.StatusOr; |
| 50 | +import io.grpc.Uri; |
50 | 51 | import java.lang.reflect.InvocationTargetException; |
51 | 52 | import java.lang.reflect.Method; |
52 | 53 | import java.net.SocketAddress; |
@@ -719,8 +720,11 @@ protected ManagedChannelImplBuilder addMetricSink(MetricSink metricSink) { |
719 | 720 | public ManagedChannel build() { |
720 | 721 | ClientTransportFactory clientTransportFactory = |
721 | 722 | clientTransportFactoryBuilder.buildClientTransportFactory(); |
722 | | - ResolvedNameResolver resolvedResolver = getNameResolverProvider( |
723 | | - target, nameResolverRegistry, clientTransportFactory.getSupportedSocketAddressTypes()); |
| 723 | + ResolvedNameResolver resolvedResolver = |
| 724 | + GrpcUtil.getFlag("GRPC_ENABLE_RFC3986_URIS", false) |
| 725 | + ? getNameResolverProviderNew(target, nameResolverRegistry) |
| 726 | + : getNameResolverProvider(target, nameResolverRegistry); |
| 727 | + resolvedResolver.checkAddressTypes(clientTransportFactory.getSupportedSocketAddressTypes()); |
724 | 728 | return new ManagedChannelOrphanWrapper(new ManagedChannelImpl( |
725 | 729 | this, |
726 | 730 | clientTransportFactory, |
@@ -822,12 +826,25 @@ public ResolvedNameResolver(UriWrapper targetUri, NameResolverProvider provider) |
822 | 826 | this.targetUri = checkNotNull(targetUri, "targetUri"); |
823 | 827 | this.provider = checkNotNull(provider, "provider"); |
824 | 828 | } |
| 829 | + |
| 830 | + void checkAddressTypes( |
| 831 | + Collection<Class<? extends SocketAddress>> channelTransportSocketAddressTypes) { |
| 832 | + if (channelTransportSocketAddressTypes != null) { |
| 833 | + Collection<Class<? extends SocketAddress>> nameResolverSocketAddressTypes = |
| 834 | + provider.getProducedSocketAddressTypes(); |
| 835 | + if (!channelTransportSocketAddressTypes.containsAll(nameResolverSocketAddressTypes)) { |
| 836 | + throw new IllegalArgumentException( |
| 837 | + String.format( |
| 838 | + "Address types of NameResolver '%s' for '%s' not supported by transport", |
| 839 | + provider.getDefaultScheme(), targetUri)); |
| 840 | + } |
| 841 | + } |
| 842 | + } |
825 | 843 | } |
826 | 844 |
|
827 | 845 | @VisibleForTesting |
828 | 846 | static ResolvedNameResolver getNameResolverProvider( |
829 | | - String target, NameResolverRegistry nameResolverRegistry, |
830 | | - Collection<Class<? extends SocketAddress>> channelTransportSocketAddressTypes) { |
| 847 | + String target, NameResolverRegistry nameResolverRegistry) { |
831 | 848 | // Finding a NameResolver. Try using the target string as the URI. If that fails, try prepending |
832 | 849 | // "dns:///". |
833 | 850 | NameResolverProvider provider = null; |
@@ -863,14 +880,45 @@ static ResolvedNameResolver getNameResolverProvider( |
863 | 880 | target, uriSyntaxErrors.length() > 0 ? " (" + uriSyntaxErrors + ")" : "")); |
864 | 881 | } |
865 | 882 |
|
866 | | - if (channelTransportSocketAddressTypes != null) { |
867 | | - Collection<Class<? extends SocketAddress>> nameResolverSocketAddressTypes |
868 | | - = provider.getProducedSocketAddressTypes(); |
869 | | - if (!channelTransportSocketAddressTypes.containsAll(nameResolverSocketAddressTypes)) { |
870 | | - throw new IllegalArgumentException(String.format( |
871 | | - "Address types of NameResolver '%s' for '%s' not supported by transport", |
872 | | - targetUri.getScheme(), target)); |
873 | | - } |
| 883 | + return new ResolvedNameResolver(wrap(targetUri), provider); |
| 884 | + } |
| 885 | + |
| 886 | + static ResolvedNameResolver getNameResolverProviderNew( |
| 887 | + String target, NameResolverRegistry nameResolverRegistry) { |
| 888 | + // Finding a NameResolver. Try using the target string as the URI. If that fails, try prepending |
| 889 | + // "dns:///". |
| 890 | + NameResolverProvider provider = null; |
| 891 | + Uri targetUri = null; |
| 892 | + StringBuilder uriSyntaxErrors = new StringBuilder(); |
| 893 | + try { |
| 894 | + targetUri = Uri.parse(target); |
| 895 | + } catch (URISyntaxException e) { |
| 896 | + // Can happen with ip addresses like "[::1]:1234" or 127.0.0.1:1234. |
| 897 | + uriSyntaxErrors.append(e.getMessage()); |
| 898 | + } |
| 899 | + if (targetUri != null) { |
| 900 | + // For "localhost:8080" this would likely cause provider to be null, because "localhost" is |
| 901 | + // parsed as the scheme. Will hit the next case and try "dns:///localhost:8080". |
| 902 | + provider = nameResolverRegistry.getProviderForScheme(targetUri.getScheme()); |
| 903 | + } |
| 904 | + |
| 905 | + if (provider == null && !URI_PATTERN.matcher(target).matches()) { |
| 906 | + // It doesn't look like a URI target. Maybe it's an authority string. Try with the default |
| 907 | + // scheme from the registry. |
| 908 | + targetUri = |
| 909 | + Uri.newBuilder() |
| 910 | + .setScheme(nameResolverRegistry.getDefaultScheme()) |
| 911 | + .setHost("") |
| 912 | + .setPath("/" + target) |
| 913 | + .build(); |
| 914 | + provider = nameResolverRegistry.getProviderForScheme(targetUri.getScheme()); |
| 915 | + } |
| 916 | + |
| 917 | + if (provider == null) { |
| 918 | + throw new IllegalArgumentException( |
| 919 | + String.format( |
| 920 | + "Could not find a NameResolverProvider for %s%s", |
| 921 | + target, uriSyntaxErrors.length() > 0 ? " (" + uriSyntaxErrors + ")" : "")); |
874 | 922 | } |
875 | 923 |
|
876 | 924 | return new ResolvedNameResolver(wrap(targetUri), provider); |
|
0 commit comments