Skip to content

Commit 4456721

Browse files
committed
api: Turn on RFC 3986 parsing by default and update javadoc.
Removed the "NameResolver-compliant" terminology because it's no longer needed. All RFC 3986 URIs are absolute in the sense that have a scheme (URI != "URI-reference"). RFC 3986 also does away with the hierarchical vs opaque distinction. All URIs now have a hierarchy of components (scheme, authority, path, query and fragment) it's just that some components can be absent and/or the empty string. Added discussion of ambiguity which is technically new with the RFC 3986 change. If you believed the current javadoc, a target like foo:8888 didn't used to be ambiguous because it is not a "valid NameResolver- compliant" URI -- the path doesn't start with / and so java.net.URI considers it opaque, not hierarchical as required. Fortunately (???) ManagedChannelImplBuilder never enforced the !isOpaque() requirement mentioned in the javadoc and so this ambiguity isn't actually new in practice. gRPC C++ also appears to suffer from the same problem.
1 parent 2b86f8f commit 4456721

3 files changed

Lines changed: 29 additions & 19 deletions

File tree

api/src/main/java/io/grpc/FeatureFlags.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import com.google.common.base.Strings;
2121

2222
class FeatureFlags {
23-
private static boolean enableRfc3986Uris = getFlag("GRPC_ENABLE_RFC3986_URIS", false);
23+
private static boolean enableRfc3986Uris = getFlag("GRPC_ENABLE_RFC3986_URIS", true);
2424

2525
/** Whether to parse targets as RFC 3986 URIs (true), or use {@link java.net.URI} (false). */
2626
@VisibleForTesting

api/src/main/java/io/grpc/Grpc.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,25 +73,24 @@ private Grpc() {
7373
public @interface TransportAttr {}
7474

7575
/**
76-
* Creates a channel builder with a target string and credentials. The target can be either a
77-
* valid {@link NameResolver}-compliant URI, or an authority string.
76+
* Creates a channel builder with a target string and credentials. The target can be either an RFC
77+
* 3986 URI, or an authority string.
7878
*
79-
* <p>A {@code NameResolver}-compliant URI is an absolute hierarchical URI as defined by {@link
80-
* java.net.URI}. Example URIs:
79+
* <p>Example URIs:
8180
* <ul>
8281
* <li>{@code "dns:///foo.googleapis.com:8080"}</li>
8382
* <li>{@code "dns:///foo.googleapis.com"}</li>
8483
* <li>{@code "dns:///%5B2001:db8:85a3:8d3:1319:8a2e:370:7348%5D:443"}</li>
8584
* <li>{@code "dns://8.8.8.8/foo.googleapis.com:8080"}</li>
8685
* <li>{@code "dns://8.8.8.8/foo.googleapis.com"}</li>
8786
* <li>{@code "zookeeper://zk.example.com:9900/example_service"}</li>
87+
* <li>{@code "intent:#Intent;package=com.some.app;action=a;category=c;end;"}</li>
8888
* </ul>
8989
*
90-
* <p>An authority string will be converted to a {@code NameResolver}-compliant URI, which has
91-
* the scheme from the name resolver with the highest priority (e.g. {@code "dns"}),
92-
* no authority, and the original authority string as its path after properly escaped.
93-
* We recommend libraries to specify the schema explicitly if it is known, since libraries cannot
94-
* know which NameResolver will be default during runtime.
90+
* <p>An authority string will be converted to a URI having the scheme of the name resolver with
91+
* the highest priority (e.g. {@code "dns"}), the empty string as the authority, and
92+
* {@code target} as its absolute path. We recommend libraries specify {@code target} as a URI
93+
* instead since they cannot know which NameResolver will be default at runtime.
9594
* Example authority strings:
9695
* <ul>
9796
* <li>{@code "localhost"}</li>
@@ -102,6 +101,12 @@ private Grpc() {
102101
* <li>{@code "[2001:db8:85a3:8d3:1319:8a2e:370:7348]"}</li>
103102
* <li>{@code "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443"}</li>
104103
* </ul>
104+
*
105+
* <p>The URI form of {@code target} is preferred because it is less ambiguous. For example, the
106+
* target string {@code foo:8080} is a valid authority string with host {@code foo} and port
107+
* {@code 8080} but it is also a valid RFC 3986 URI with scheme {@code foo} and path {@code 8080}.
108+
* gRPC prioritizes the URI form, which means {@code foo:8080} will be treated as a URI with
109+
* scheme {@code foo}. Using {@code dns:///foo:8080} avoids this ambiguity.
105110
*/
106111
public static ManagedChannelBuilder<?> newChannelBuilder(
107112
String target, ChannelCredentials creds) {

api/src/main/java/io/grpc/ManagedChannelBuilder.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,24 @@ public static ManagedChannelBuilder<?> forAddress(String name, int port) {
4545
}
4646

4747
/**
48-
* Creates a channel with a target string, which can be either a valid {@link
49-
* NameResolver}-compliant URI, or an authority string.
48+
* Creates a channel with a target string, which can be either an RFC 3986 URI, or an authority
49+
* string.
5050
*
51-
* <p>A {@code NameResolver}-compliant URI is an absolute hierarchical URI as defined by {@link
52-
* java.net.URI}. Example URIs:
51+
* <p>Example URIs:
5352
* <ul>
5453
* <li>{@code "dns:///foo.googleapis.com:8080"}</li>
5554
* <li>{@code "dns:///foo.googleapis.com"}</li>
5655
* <li>{@code "dns:///%5B2001:db8:85a3:8d3:1319:8a2e:370:7348%5D:443"}</li>
5756
* <li>{@code "dns://8.8.8.8/foo.googleapis.com:8080"}</li>
5857
* <li>{@code "dns://8.8.8.8/foo.googleapis.com"}</li>
5958
* <li>{@code "zookeeper://zk.example.com:9900/example_service"}</li>
59+
* <li>{@code "intent:#Intent;package=com.some.app;action=a;category=c;end;"}</li>
6060
* </ul>
6161
*
62-
* <p>An authority string will be converted to a {@code NameResolver}-compliant URI, which has
63-
* the scheme from the name resolver with the highest priority (e.g. {@code "dns"}),
64-
* no authority, and the original authority string as its path after properly escaped.
65-
* We recommend libraries to specify the schema explicitly if it is known, since libraries cannot
66-
* know which NameResolver will be default during runtime.
62+
* <p>An authority string will be converted to a URI having the scheme of the name resolver with
63+
* the highest priority (e.g. {@code "dns"}), the empty string as the authority, and
64+
* {@code target} as its absolute path. We recommend libraries specify {@code target} as a URI
65+
* instead since they cannot know which NameResolver will be default at runtime.
6766
* Example authority strings:
6867
* <ul>
6968
* <li>{@code "localhost"}</li>
@@ -75,6 +74,12 @@ public static ManagedChannelBuilder<?> forAddress(String name, int port) {
7574
* <li>{@code "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443"}</li>
7675
* </ul>
7776
*
77+
* <p>The URI form of {@code target} is preferred because it is less ambiguous. For example, the
78+
* target string {@code foo:8080} is a valid authority string with host {@code foo} and port
79+
* {@code 8080} but it is also a valid RFC 3986 URI with scheme {@code foo} and path {@code 8080}.
80+
* gRPC prioritizes the URI form, which means {@code foo:8080} will be treated as a URI with
81+
* scheme {@code foo}. Using {@code dns:///foo:8080} avoids this ambiguity.
82+
*
7883
* <p>Note that there is an open JDK bug on {@link java.net.URI} class parsing an ipv6 scope ID:
7984
* bugs.openjdk.org/browse/JDK-8199396. This method is exposed to this bug. If you experience an
8085
* issue, a work-around is to convert the scope ID to its numeric form (e.g. by using

0 commit comments

Comments
 (0)