remote: 'grpc' scheme prefix converted to an empty scheme for grpc remote connections

Part of #7205

Closes #8000.

PiperOrigin-RevId: 243062400
diff --git a/src/main/java/com/google/devtools/build/lib/authandtls/GoogleAuthUtils.java b/src/main/java/com/google/devtools/build/lib/authandtls/GoogleAuthUtils.java
index a6c51da..203c309 100644
--- a/src/main/java/com/google/devtools/build/lib/authandtls/GoogleAuthUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/authandtls/GoogleAuthUtils.java
@@ -53,9 +53,11 @@
     final SslContext sslContext =
         options.tlsEnabled ? createSSlContext(options.tlsCertificate) : null;
 
+    String targetUrl = convertTargetScheme(target);
+
     try {
       NettyChannelBuilder builder =
-          NettyChannelBuilder.forTarget(target)
+          NettyChannelBuilder.forTarget(targetUrl)
               .negotiationType(options.tlsEnabled ? NegotiationType.TLS : NegotiationType.PLAINTEXT)
               .loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance())
               .intercept(interceptors);
@@ -70,10 +72,20 @@
       // gRPC might throw all kinds of RuntimeExceptions: StatusRuntimeException,
       // IllegalStateException, NullPointerException, ...
       String message = "Failed to connect to '%s': %s";
-      throw new IOException(String.format(message, target, e.getMessage()));
+      throw new IOException(String.format(message, targetUrl, e.getMessage()));
     }
   }
 
+  /**
+   * Converts 'grpc(s)' into an empty protocol, because 'grpc(s)' is not a widely supported scheme
+   * and is interpreted as 'dns' under the hood.
+   *
+   * @return target URL with converted scheme
+   */
+  private static String convertTargetScheme(String target) {
+    return target.replace("grpc://", "").replace("grpcs://", "");
+  }
+
   private static SslContext createSSlContext(@Nullable String rootCert) throws IOException {
     if (rootCert == null) {
       try {
diff --git a/src/test/shell/bazel/remote/remote_execution_test.sh b/src/test/shell/bazel/remote/remote_execution_test.sh
index f035647..4fe983c 100755
--- a/src/test/shell/bazel/remote/remote_execution_test.sh
+++ b/src/test/shell/bazel/remote/remote_execution_test.sh
@@ -61,6 +61,23 @@
   rm -rf "${cas_path}"
 }
 
+function test_remote_grpc_cache_with_protocol() {
+  # Test that if 'grpc' is provided as a scheme for --remote_cache flag, remote cache works.
+  mkdir -p a
+  cat > a/BUILD <<EOF
+genrule(
+  name = 'foo',
+  outs = ["foo.txt"],
+  cmd = "echo \"foo bar\" > \$@",
+)
+EOF
+
+  bazel build \
+      --remote_cache=grpc://localhost:${worker_port} \
+      //a:foo \
+      || fail "Failed to build //a:foo with remote cache"
+}
+
 function test_cc_binary() {
   if [[ "$PLATFORM" == "darwin" ]]; then
     # TODO(b/37355380): This test is disabled due to RemoteWorker not supporting