From 3a38e59bae00ac63d0e743d88fd03207bd9fd394 Mon Sep 17 00:00:00 2001 From: Ignacio del Valle Alles Date: Thu, 24 Jan 2019 01:57:40 +0100 Subject: [PATCH] core: Allow specifying a ProxyDetector per ManagedChannel --- .../io/grpc/ForwardingChannelBuilder.java | 6 ++ .../java/io/grpc/ManagedChannelBuilder.java | 12 +++ core/src/main/java/io/grpc/NameResolver.java | 9 ++- .../io/grpc/{internal => }/ProxyDetector.java | 3 +- .../grpc/{internal => }/ProxyParameters.java | 76 +++++++++++++++++-- .../AbstractManagedChannelImplBuilder.java | 10 +++ .../grpc/internal/ClientTransportFactory.java | 1 + .../io/grpc/internal/DnsNameResolver.java | 4 +- .../internal/DnsNameResolverProvider.java | 6 +- .../main/java/io/grpc/internal/GrpcUtil.java | 2 + .../io/grpc/internal/InternalSubchannel.java | 1 + .../io/grpc/internal/ManagedChannelImpl.java | 17 ++++- .../io/grpc/internal/ProxyDetectorImpl.java | 14 ++-- .../io/grpc/internal/ProxySocketAddress.java | 1 + .../internal/ClientTransportFactoryTest.java | 3 +- .../internal/DnsNameResolverProviderTest.java | 11 ++- .../io/grpc/internal/DnsNameResolverTest.java | 22 ++++-- .../grpc/internal/ManagedChannelImplTest.java | 5 +- .../grpc/internal/ProxyDetectorImplTest.java | 36 ++++----- .../io/grpc/cronet/CronetChannelBuilder.java | 1 - .../io/grpc/netty/NettyChannelBuilder.java | 6 +- .../grpc/netty/NettyChannelBuilderTest.java | 2 +- .../io/grpc/okhttp/OkHttpClientTransport.java | 17 ++++- .../okhttp/OkHttpClientTransportTest.java | 14 ++-- 24 files changed, 218 insertions(+), 61 deletions(-) rename core/src/main/java/io/grpc/{internal => }/ProxyDetector.java (94%) rename core/src/main/java/io/grpc/{internal => }/ProxyParameters.java (50%) diff --git a/core/src/main/java/io/grpc/ForwardingChannelBuilder.java b/core/src/main/java/io/grpc/ForwardingChannelBuilder.java index 78bd9d5114..8b9cb6ef02 100644 --- a/core/src/main/java/io/grpc/ForwardingChannelBuilder.java +++ b/core/src/main/java/io/grpc/ForwardingChannelBuilder.java @@ -236,6 +236,12 @@ public abstract class ForwardingChannelBuilder> throw new UnsupportedOperationException(); } + /** + * Sets the proxy detector to be used in addresses name resolution. If null is passed + * the default proxy detector will be used. + * + * @return this + * @since 1.19.0 + */ + @ExperimentalApi("https://github.com/grpc/grpc-java/issues/5113") + public T proxyDetector(ProxyDetector proxyDetector) { + throw new UnsupportedOperationException(); + } + /** * Builds a channel using the given parameters. * diff --git a/core/src/main/java/io/grpc/NameResolver.java b/core/src/main/java/io/grpc/NameResolver.java index 845dcb02fd..718895bc08 100644 --- a/core/src/main/java/io/grpc/NameResolver.java +++ b/core/src/main/java/io/grpc/NameResolver.java @@ -99,6 +99,13 @@ public abstract class NameResolver { public static final Attributes.Key PARAMS_DEFAULT_PORT = Attributes.Key.create("params-default-port"); + /** + * Proxy detector used in name resolution. + */ + @ExperimentalApi("https://github.com/grpc/grpc-java/issues/5113") + public static final Attributes.Key PARAMS_PROXY_DETECTOR = + Attributes.Key.create("params-proxy-detector"); + /** * Creates a {@link NameResolver} for the given target URI, or {@code null} if the given URI * cannot be resolved by this factory. The decision should be solely based on the scheme of the @@ -106,7 +113,7 @@ public abstract class NameResolver { * * @param targetUri the target URI to be resolved, whose scheme must not be {@code null} * @param params optional parameters. Canonical keys are defined as {@code PARAMS_*} fields in - * {@link Factory}. + * {@link Factory}. * @since 1.0.0 */ @Nullable diff --git a/core/src/main/java/io/grpc/internal/ProxyDetector.java b/core/src/main/java/io/grpc/ProxyDetector.java similarity index 94% rename from core/src/main/java/io/grpc/internal/ProxyDetector.java rename to core/src/main/java/io/grpc/ProxyDetector.java index 5dc9629363..493e07f883 100644 --- a/core/src/main/java/io/grpc/internal/ProxyDetector.java +++ b/core/src/main/java/io/grpc/ProxyDetector.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.grpc.internal; +package io.grpc; import java.io.IOException; import java.net.SocketAddress; @@ -26,6 +26,7 @@ import javax.annotation.Nullable; * and should only be used in places that are expected to do IO such as the * {@link io.grpc.NameResolver}. */ +@ExperimentalApi("https://github.com/grpc/grpc-java/issues/5113") public interface ProxyDetector { /** * Given a target address, returns which proxy address should be used. If no proxy should be diff --git a/core/src/main/java/io/grpc/internal/ProxyParameters.java b/core/src/main/java/io/grpc/ProxyParameters.java similarity index 50% rename from core/src/main/java/io/grpc/internal/ProxyParameters.java rename to core/src/main/java/io/grpc/ProxyParameters.java index b880550a99..119b35d4fc 100644 --- a/core/src/main/java/io/grpc/internal/ProxyParameters.java +++ b/core/src/main/java/io/grpc/ProxyParameters.java @@ -14,35 +14,58 @@ * limitations under the License. */ -package io.grpc.internal; +package io.grpc; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import java.net.InetSocketAddress; +import java.net.SocketAddress; import javax.annotation.Nullable; /** * Used to express the result of a proxy lookup. */ +@ExperimentalApi("https://github.com/grpc/grpc-java/issues/5113") public final class ProxyParameters { - public final InetSocketAddress proxyAddress; - @Nullable public final String username; - @Nullable public final String password; - /** Creates an instance. */ - public ProxyParameters( - InetSocketAddress proxyAddress, + private final SocketAddress proxyAddress; + @Nullable + private final String username; + @Nullable + private final String password; + + /** + * Creates an instance. + */ + private ProxyParameters( + SocketAddress proxyAddress, @Nullable String username, @Nullable String password) { Preconditions.checkNotNull(proxyAddress); // The resolution must be done by the ProxyParameters producer, because consumers // may not be allowed to do IO. - Preconditions.checkState(!proxyAddress.isUnresolved()); + if (proxyAddress instanceof InetSocketAddress) { + Preconditions.checkState(!((InetSocketAddress)proxyAddress).isUnresolved()); + } this.proxyAddress = proxyAddress; this.username = username; this.password = password; } + @Nullable + public String getPassword() { + return password; + } + + @Nullable + public String getUsername() { + return username; + } + + public SocketAddress getProxyAddress() { + return proxyAddress; + } + @Override public boolean equals(Object o) { if (!(o instanceof ProxyParameters)) { @@ -58,4 +81,41 @@ public final class ProxyParameters { public int hashCode() { return Objects.hashCode(proxyAddress, username, password); } + + /** + * Create a new builder. + */ + public static Builder forAddress(SocketAddress proxyAddress) { + return new Builder(proxyAddress); + } + + /** + * The helper class to build an Attributes instance. + */ + public static final class Builder { + + private final SocketAddress proxyAddress; + @Nullable + private String username; + @Nullable + private String password; + + private Builder(SocketAddress proxyAddress) { + this.proxyAddress = Preconditions.checkNotNull(proxyAddress, "proxyAddress"); + } + + public Builder username(@Nullable String username) { + this.username = username; + return this; + } + + public Builder password(@Nullable String password) { + this.password = password; + return this; + } + + public ProxyParameters build() { + return new ProxyParameters(this.proxyAddress, this.username, this.password); + } + } } diff --git a/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java b/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java index abadccea31..eb1c6b75f1 100644 --- a/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java +++ b/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java @@ -33,6 +33,7 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.NameResolver; import io.grpc.NameResolverProvider; +import io.grpc.ProxyDetector; import io.opencensus.trace.Tracing; import java.net.SocketAddress; import java.net.URI; @@ -145,6 +146,9 @@ public abstract class AbstractManagedChannelImplBuilder @Nullable BinaryLog binlog; + @Nullable + ProxyDetector proxyDetector; + /** * Sets the maximum message size allowed for a single gRPC frame. If an inbound messages * larger than this limit is received it will not be processed and the RPC will fail with @@ -369,6 +373,12 @@ public abstract class AbstractManagedChannelImplBuilder return thisT(); } + @Override + public T proxyDetector(@Nullable ProxyDetector proxyDetector) { + this.proxyDetector = proxyDetector; + return thisT(); + } + /** * Disable or enable stats features. Enabled by default. * diff --git a/core/src/main/java/io/grpc/internal/ClientTransportFactory.java b/core/src/main/java/io/grpc/internal/ClientTransportFactory.java index a26d41d60b..cf577a0c26 100644 --- a/core/src/main/java/io/grpc/internal/ClientTransportFactory.java +++ b/core/src/main/java/io/grpc/internal/ClientTransportFactory.java @@ -19,6 +19,7 @@ package io.grpc.internal; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import io.grpc.Attributes; +import io.grpc.ProxyParameters; import java.io.Closeable; import java.net.SocketAddress; import java.util.concurrent.ScheduledExecutorService; diff --git a/core/src/main/java/io/grpc/internal/DnsNameResolver.java b/core/src/main/java/io/grpc/internal/DnsNameResolver.java index 9fd5da9f7f..a7387e2a84 100644 --- a/core/src/main/java/io/grpc/internal/DnsNameResolver.java +++ b/core/src/main/java/io/grpc/internal/DnsNameResolver.java @@ -27,6 +27,8 @@ import com.google.common.base.Verify; import io.grpc.Attributes; import io.grpc.EquivalentAddressGroup; import io.grpc.NameResolver; +import io.grpc.ProxyDetector; +import io.grpc.ProxyParameters; import io.grpc.Status; import io.grpc.internal.SharedResourceHolder.Resource; import java.io.IOException; @@ -251,7 +253,7 @@ final class DnsNameResolver extends NameResolver { } if (proxy != null) { if (logger.isLoggable(Level.FINER)) { - logger.finer("Using proxy " + proxy.proxyAddress + " for " + resolver.host); + logger.finer("Using proxy " + proxy.getProxyAddress() + " for " + resolver.host); } EquivalentAddressGroup server = new EquivalentAddressGroup( diff --git a/core/src/main/java/io/grpc/internal/DnsNameResolverProvider.java b/core/src/main/java/io/grpc/internal/DnsNameResolverProvider.java index eda7754477..bf80c7eaba 100644 --- a/core/src/main/java/io/grpc/internal/DnsNameResolverProvider.java +++ b/core/src/main/java/io/grpc/internal/DnsNameResolverProvider.java @@ -20,7 +20,9 @@ import com.google.common.base.Preconditions; import com.google.common.base.Stopwatch; import io.grpc.Attributes; import io.grpc.InternalServiceProviders; +import io.grpc.NameResolver.Factory; import io.grpc.NameResolverProvider; +import io.grpc.ProxyDetector; import java.net.URI; /** @@ -49,12 +51,14 @@ public final class DnsNameResolverProvider extends NameResolverProvider { Preconditions.checkArgument(targetPath.startsWith("/"), "the path component (%s) of the target (%s) must start with '/'", targetPath, targetUri); String name = targetPath.substring(1); + ProxyDetector proxyDetector = Preconditions + .checkNotNull(params.get(Factory.PARAMS_PROXY_DETECTOR), "proxyDetector"); return new DnsNameResolver( targetUri.getAuthority(), name, params, GrpcUtil.SHARED_CHANNEL_EXECUTOR, - GrpcUtil.getDefaultProxyDetector(), + proxyDetector, Stopwatch.createUnstarted(), InternalServiceProviders.isAndroid(getClass().getClassLoader())); } else { diff --git a/core/src/main/java/io/grpc/internal/GrpcUtil.java b/core/src/main/java/io/grpc/internal/GrpcUtil.java index 53054157f1..2d3e2758c2 100644 --- a/core/src/main/java/io/grpc/internal/GrpcUtil.java +++ b/core/src/main/java/io/grpc/internal/GrpcUtil.java @@ -37,6 +37,8 @@ import io.grpc.LoadBalancer.PickResult; import io.grpc.LoadBalancer.Subchannel; import io.grpc.Metadata; import io.grpc.MethodDescriptor; +import io.grpc.ProxyDetector; +import io.grpc.ProxyParameters; import io.grpc.Status; import io.grpc.internal.ClientStreamListener.RpcProgress; import io.grpc.internal.SharedResourceHolder.Resource; diff --git a/core/src/main/java/io/grpc/internal/InternalSubchannel.java b/core/src/main/java/io/grpc/internal/InternalSubchannel.java index 516bdf1901..b150374789 100644 --- a/core/src/main/java/io/grpc/internal/InternalSubchannel.java +++ b/core/src/main/java/io/grpc/internal/InternalSubchannel.java @@ -44,6 +44,7 @@ import io.grpc.InternalLogId; import io.grpc.InternalWithLogId; import io.grpc.Metadata; import io.grpc.MethodDescriptor; +import io.grpc.ProxyParameters; import io.grpc.Status; import io.grpc.SynchronizationContext; import java.net.SocketAddress; diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java index d3c46445e2..6a37fe56ce 100644 --- a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java +++ b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java @@ -60,6 +60,7 @@ import io.grpc.ManagedChannel; import io.grpc.Metadata; import io.grpc.MethodDescriptor; import io.grpc.NameResolver; +import io.grpc.ProxyDetector; import io.grpc.Status; import io.grpc.SynchronizationContext; import io.grpc.SynchronizationContext.ScheduledHandle; @@ -135,6 +136,7 @@ final class ManagedChannelImpl extends ManagedChannel implements private final ExecutorHolder balancerRpcExecutorHolder; private final TimeProvider timeProvider; private final int maxTraceEvents; + private final ProxyDetector proxyDetector; @VisibleForTesting final SynchronizationContext syncContext = new SynchronizationContext( @@ -543,7 +545,10 @@ final class ManagedChannelImpl extends ManagedChannel implements this.target = checkNotNull(builder.target, "target"); this.logId = InternalLogId.allocate("Channel", target); this.nameResolverFactory = builder.getNameResolverFactory(); - this.nameResolverParams = checkNotNull(builder.getNameResolverParams(), "nameResolverParams"); + this.proxyDetector = + builder.proxyDetector != null ? builder.proxyDetector : GrpcUtil.getDefaultProxyDetector(); + this.nameResolverParams = addProxyToAttributes(this.proxyDetector, + checkNotNull(builder.getNameResolverParams(), "nameResolverParams")); this.nameResolver = getNameResolver(target, nameResolverFactory, nameResolverParams); this.timeProvider = checkNotNull(timeProvider, "timeProvider"); maxTraceEvents = builder.maxTraceEvents; @@ -612,6 +617,16 @@ final class ManagedChannelImpl extends ManagedChannel implements channelz.addRootChannel(this); } + private static Attributes addProxyToAttributes(ProxyDetector proxyDetector, + Attributes attributes) { + if (attributes.get(NameResolver.Factory.PARAMS_PROXY_DETECTOR) == null) { + return attributes.toBuilder() + .set(NameResolver.Factory.PARAMS_PROXY_DETECTOR, proxyDetector).build(); + } else { + return attributes; + } + } + @VisibleForTesting static NameResolver getNameResolver(String target, NameResolver.Factory nameResolverFactory, Attributes nameResolverParams) { diff --git a/core/src/main/java/io/grpc/internal/ProxyDetectorImpl.java b/core/src/main/java/io/grpc/internal/ProxyDetectorImpl.java index 1219d132d3..4ed8fd57af 100644 --- a/core/src/main/java/io/grpc/internal/ProxyDetectorImpl.java +++ b/core/src/main/java/io/grpc/internal/ProxyDetectorImpl.java @@ -20,6 +20,8 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Supplier; +import io.grpc.ProxyDetector; +import io.grpc.ProxyParameters; import java.io.IOException; import java.net.Authenticator; import java.net.InetAddress; @@ -176,7 +178,7 @@ class ProxyDetectorImpl implements ProxyDetector { this.proxySelector = checkNotNull(proxySelector); this.authenticationProvider = checkNotNull(authenticationProvider); if (proxyEnvString != null) { - override = new ProxyParameters(overrideProxy(proxyEnvString), null, null); + override = ProxyParameters.forAddress(overrideProxy(proxyEnvString)).build(); } else { override = null; } @@ -258,12 +260,14 @@ class ProxyDetectorImpl implements ProxyDetector { } if (auth == null) { - return new ProxyParameters(resolvedProxyAddr, null, null); + return ProxyParameters.forAddress(resolvedProxyAddr).build(); } - // TODO(spencerfang): users of ProxyParameters should clear the password when done - return new ProxyParameters( - resolvedProxyAddr, auth.getUserName(), new String(auth.getPassword())); + return ProxyParameters + .forAddress(resolvedProxyAddr) + .username(auth.getUserName()) + .password(auth.getPassword() == null ? null : new String(auth.getPassword())) + .build(); } /** diff --git a/core/src/main/java/io/grpc/internal/ProxySocketAddress.java b/core/src/main/java/io/grpc/internal/ProxySocketAddress.java index ae9d00bc69..8bc3fd1a89 100644 --- a/core/src/main/java/io/grpc/internal/ProxySocketAddress.java +++ b/core/src/main/java/io/grpc/internal/ProxySocketAddress.java @@ -17,6 +17,7 @@ package io.grpc.internal; import com.google.common.base.Preconditions; +import io.grpc.ProxyParameters; import java.net.SocketAddress; /** diff --git a/core/src/test/java/io/grpc/internal/ClientTransportFactoryTest.java b/core/src/test/java/io/grpc/internal/ClientTransportFactoryTest.java index 279d544d44..5d3d2197a7 100644 --- a/core/src/test/java/io/grpc/internal/ClientTransportFactoryTest.java +++ b/core/src/test/java/io/grpc/internal/ClientTransportFactoryTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; import io.grpc.Attributes; +import io.grpc.ProxyParameters; import io.grpc.internal.ClientTransportFactory.ClientTransportOptions; import java.net.InetSocketAddress; import org.junit.Test; @@ -33,7 +34,7 @@ public final class ClientTransportFactoryTest { Attributes.newBuilder().set(Attributes.Key.create("fake key"), "fake value").build(); private String userAgent = "best-ua/3.14"; private ProxyParameters proxyParameters = - new ProxyParameters(new InetSocketAddress(0), null, null); + ProxyParameters.forAddress(new InetSocketAddress(0)).build(); @Test public void clientTransportOptions_init_checkNotNulls() { diff --git a/core/src/test/java/io/grpc/internal/DnsNameResolverProviderTest.java b/core/src/test/java/io/grpc/internal/DnsNameResolverProviderTest.java index 9e771aac4d..273e6d2871 100644 --- a/core/src/test/java/io/grpc/internal/DnsNameResolverProviderTest.java +++ b/core/src/test/java/io/grpc/internal/DnsNameResolverProviderTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import io.grpc.Attributes; +import io.grpc.NameResolver; import java.net.URI; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,6 +30,12 @@ import org.junit.runners.JUnit4; /** Unit tests for {@link DnsNameResolverProvider}. */ @RunWith(JUnit4.class) public class DnsNameResolverProviderTest { + + private static final Attributes ATTRIBUTES = + Attributes.newBuilder() + .set(NameResolver.Factory.PARAMS_PROXY_DETECTOR, GrpcUtil.getDefaultProxyDetector()) + .build(); + private DnsNameResolverProvider provider = new DnsNameResolverProvider(); @Test @@ -39,8 +46,8 @@ public class DnsNameResolverProviderTest { @Test public void newNameResolver() { assertSame(DnsNameResolver.class, - provider.newNameResolver(URI.create("dns:///localhost:443"), Attributes.EMPTY).getClass()); + provider.newNameResolver(URI.create("dns:///localhost:443"), ATTRIBUTES).getClass()); assertNull( - provider.newNameResolver(URI.create("notdns:///localhost:443"), Attributes.EMPTY)); + provider.newNameResolver(URI.create("notdns:///localhost:443"), ATTRIBUTES)); } } diff --git a/core/src/test/java/io/grpc/internal/DnsNameResolverTest.java b/core/src/test/java/io/grpc/internal/DnsNameResolverTest.java index b499915628..2dd022e34e 100644 --- a/core/src/test/java/io/grpc/internal/DnsNameResolverTest.java +++ b/core/src/test/java/io/grpc/internal/DnsNameResolverTest.java @@ -38,6 +38,8 @@ import com.google.common.testing.FakeTicker; import io.grpc.Attributes; import io.grpc.EquivalentAddressGroup; import io.grpc.NameResolver; +import io.grpc.ProxyDetector; +import io.grpc.ProxyParameters; import io.grpc.Status; import io.grpc.Status.Code; import io.grpc.internal.DnsNameResolver.AddressResolver; @@ -92,7 +94,10 @@ public class DnsNameResolverTest { private static final int DEFAULT_PORT = 887; private static final Attributes NAME_RESOLVER_PARAMS = - Attributes.newBuilder().set(NameResolver.Factory.PARAMS_DEFAULT_PORT, DEFAULT_PORT).build(); + Attributes.newBuilder() + .set(NameResolver.Factory.PARAMS_DEFAULT_PORT, DEFAULT_PORT) + .set(NameResolver.Factory.PARAMS_PROXY_DETECTOR, GrpcUtil.getDefaultProxyDetector()) + .build(); private final DnsNameResolverProvider provider = new DnsNameResolverProvider(); private final FakeClock fakeClock = new FakeClock(); @@ -272,7 +277,9 @@ public class DnsNameResolverTest { public void resolveAll_failsOnEmptyResult() throws Exception { String hostname = "dns:///addr.fake:1234"; DnsNameResolver nrf = - new DnsNameResolverProvider().newNameResolver(new URI(hostname), Attributes.EMPTY); + new DnsNameResolverProvider().newNameResolver(new URI(hostname), Attributes.newBuilder() + .set(NameResolver.Factory.PARAMS_PROXY_DETECTOR, GrpcUtil.getDefaultProxyDetector()) + .build()); nrf.setAddressResolver(new AddressResolver() { @Override public List resolveAddress(String host) throws Exception { @@ -576,10 +583,11 @@ public class DnsNameResolverTest { final String name = "foo.googleapis.com"; final int port = 81; ProxyDetector alwaysDetectProxy = mock(ProxyDetector.class); - ProxyParameters proxyParameters = new ProxyParameters( - new InetSocketAddress(InetAddress.getByName("10.0.0.1"), 1000), - "username", - "password"); + ProxyParameters proxyParameters = ProxyParameters + .forAddress( + new InetSocketAddress(InetAddress.getByName("10.0.0.1"), 1000)) + .username("username") + .password("password").build(); when(alwaysDetectProxy.proxyFor(any(SocketAddress.class))) .thenReturn(proxyParameters); DnsNameResolver resolver = @@ -847,7 +855,7 @@ public class DnsNameResolverTest { public void shouldUseJndi_falseIfDisabledForLocalhost() { boolean enableJndi = true; boolean enableJndiLocalhost = false; - + assertFalse(DnsNameResolver.shouldUseJndi(enableJndi, enableJndiLocalhost, "localhost")); assertFalse(DnsNameResolver.shouldUseJndi(enableJndi, enableJndiLocalhost, "LOCALHOST")); } diff --git a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java index 3b83c6dda6..aae174d883 100644 --- a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java +++ b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java @@ -143,7 +143,10 @@ import org.mockito.stubbing.Answer; @RunWith(JUnit4.class) public class ManagedChannelImplTest { private static final Attributes NAME_RESOLVER_PARAMS = - Attributes.newBuilder().set(NameResolver.Factory.PARAMS_DEFAULT_PORT, 447).build(); + Attributes.newBuilder() + .set(NameResolver.Factory.PARAMS_DEFAULT_PORT, 447) + .set(NameResolver.Factory.PARAMS_PROXY_DETECTOR, GrpcUtil.getDefaultProxyDetector()) + .build(); private static final MethodDescriptor method = MethodDescriptor.newBuilder() diff --git a/core/src/test/java/io/grpc/internal/ProxyDetectorImplTest.java b/core/src/test/java/io/grpc/internal/ProxyDetectorImplTest.java index f2a21de49c..48c41367b3 100644 --- a/core/src/test/java/io/grpc/internal/ProxyDetectorImplTest.java +++ b/core/src/test/java/io/grpc/internal/ProxyDetectorImplTest.java @@ -28,6 +28,8 @@ import static org.mockito.Mockito.when; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; +import io.grpc.ProxyDetector; +import io.grpc.ProxyParameters; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.PasswordAuthentication; @@ -66,10 +68,10 @@ public class ProxyDetectorImplTest { proxyDetector = new ProxyDetectorImpl(proxySelectorSupplier, authenticator, null); int proxyPort = 1234; unresolvedProxy = InetSocketAddress.createUnresolved("10.0.0.1", proxyPort); - proxyParmeters = new ProxyParameters( - new InetSocketAddress(InetAddress.getByName(unresolvedProxy.getHostName()), proxyPort), - NO_USER, - NO_PW); + proxyParmeters = ProxyParameters + .forAddress( + new InetSocketAddress(InetAddress.getByName(unresolvedProxy.getHostName()), proxyPort)) + .build(); } @Test @@ -84,10 +86,10 @@ public class ProxyDetectorImplTest { ProxyParameters detected = proxyDetector.proxyFor(destination); assertNotNull(detected); assertEquals( - new ProxyParameters( - new InetSocketAddress(InetAddress.getByName(overrideHost), overridePort), - NO_USER, - NO_PW), + ProxyParameters + .forAddress( + new InetSocketAddress(InetAddress.getByName(overrideHost), overridePort)) + .build(), detected); } @@ -102,11 +104,10 @@ public class ProxyDetectorImplTest { ProxyParameters detected = proxyDetector.proxyFor(destination); assertNotNull(detected); assertEquals( - new ProxyParameters( + ProxyParameters.forAddress( new InetSocketAddress( - InetAddress.getByName(overrideHostWithoutPort), defaultPort), - NO_USER, - NO_PW), + InetAddress.getByName(overrideHostWithoutPort), defaultPort)) + .build(), detected); } @@ -148,7 +149,7 @@ public class ProxyDetectorImplTest { Proxy proxy1 = new java.net.Proxy(java.net.Proxy.Type.HTTP, unresolvedProxy); when(proxySelector.select(any(URI.class))).thenReturn(ImmutableList.of(proxy1)); ProxyParameters proxy = proxyDetector.proxyFor(destination); - assertFalse(proxy.proxyAddress.isUnresolved()); + assertFalse(((InetSocketAddress)proxy.getProxyAddress()).isUnresolved()); } @Test @@ -189,12 +190,13 @@ public class ProxyDetectorImplTest { ProxyParameters detected = proxyDetector.proxyFor(destination); assertEquals( - new ProxyParameters( + ProxyParameters.forAddress( new InetSocketAddress( InetAddress.getByName(unresolvedProxy.getHostName()), - unresolvedProxy.getPort()), - proxyUser, - proxyPassword), + unresolvedProxy.getPort())) + .username(proxyUser) + .password(proxyPassword) + .build(), detected); } diff --git a/cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java b/cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java index 5811387258..b91a950036 100644 --- a/cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java +++ b/cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java @@ -30,7 +30,6 @@ import io.grpc.internal.AbstractManagedChannelImplBuilder; import io.grpc.internal.ClientTransportFactory; import io.grpc.internal.ConnectionClientTransport; import io.grpc.internal.GrpcUtil; -import io.grpc.internal.ProxyParameters; import io.grpc.internal.SharedResourceHolder; import io.grpc.internal.TransportTracer; import java.net.InetSocketAddress; diff --git a/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java b/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java index 569568d406..790a791dd1 100644 --- a/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java +++ b/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java @@ -30,13 +30,13 @@ import io.grpc.EquivalentAddressGroup; import io.grpc.ExperimentalApi; import io.grpc.Internal; import io.grpc.NameResolver; +import io.grpc.ProxyParameters; import io.grpc.internal.AbstractManagedChannelImplBuilder; import io.grpc.internal.AtomicBackoff; import io.grpc.internal.ClientTransportFactory; import io.grpc.internal.ConnectionClientTransport; import io.grpc.internal.GrpcUtil; import io.grpc.internal.KeepAliveManager; -import io.grpc.internal.ProxyParameters; import io.grpc.internal.SharedResourceHolder; import io.grpc.internal.TransportTracer; import io.netty.channel.Channel; @@ -547,7 +547,9 @@ public final class NettyChannelBuilder ProxyParameters proxyParams = options.getProxyParameters(); if (proxyParams != null) { localNegotiator = ProtocolNegotiators.httpProxy( - proxyParams.proxyAddress, proxyParams.username, proxyParams.password, + proxyParams.getProxyAddress(), + proxyParams.getUsername(), + proxyParams.getPassword(), protocolNegotiator); } diff --git a/netty/src/test/java/io/grpc/netty/NettyChannelBuilderTest.java b/netty/src/test/java/io/grpc/netty/NettyChannelBuilderTest.java index 2d653a4ca9..78cbb1c4ca 100644 --- a/netty/src/test/java/io/grpc/netty/NettyChannelBuilderTest.java +++ b/netty/src/test/java/io/grpc/netty/NettyChannelBuilderTest.java @@ -21,7 +21,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import io.grpc.ManagedChannel; -import io.grpc.internal.ProxyParameters; +import io.grpc.ProxyParameters; import io.grpc.netty.InternalNettyChannelBuilder.OverrideAuthorityChecker; import io.grpc.netty.ProtocolNegotiators.TlsNegotiator; import io.netty.handler.ssl.SslContext; diff --git a/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java b/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java index b4e7e93d1c..f163b3f649 100644 --- a/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java +++ b/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java @@ -40,6 +40,7 @@ import io.grpc.InternalLogId; import io.grpc.Metadata; import io.grpc.MethodDescriptor; import io.grpc.MethodDescriptor.MethodType; +import io.grpc.ProxyParameters; import io.grpc.SecurityLevel; import io.grpc.Status; import io.grpc.Status.Code; @@ -52,7 +53,6 @@ import io.grpc.internal.Http2Ping; import io.grpc.internal.InUseStateAggregator; import io.grpc.internal.KeepAliveManager; import io.grpc.internal.KeepAliveManager.ClientKeepAlivePinger; -import io.grpc.internal.ProxyParameters; import io.grpc.internal.SerializingExecutor; import io.grpc.internal.SharedResourceHolder; import io.grpc.internal.StatsTraceContext; @@ -507,10 +507,19 @@ class OkHttpClientTransport implements ConnectionClientTransport, TransportExcep if (proxy == null) { sock = new Socket(address.getAddress(), address.getPort()); } else { - sock = createHttpProxySocket( - address, proxy.proxyAddress, proxy.username, proxy.password); + if (proxy.getProxyAddress() instanceof InetSocketAddress) { + sock = createHttpProxySocket( + address, + (InetSocketAddress)proxy.getProxyAddress(), + proxy.getUsername(), + proxy.getPassword() + ); + } else { + throw Status.INTERNAL.withDescription( + "Unsupported SocketAddress implementation " + proxy.getProxyAddress().getClass()) + .asException(); + } } - if (sslSocketFactory != null) { SSLSocket sslSocket = OkHttpTlsUpgrader.upgrade( sslSocketFactory, hostnameVerifier, sock, getOverridenHost(), getOverridenPort(), diff --git a/okhttp/src/test/java/io/grpc/okhttp/OkHttpClientTransportTest.java b/okhttp/src/test/java/io/grpc/okhttp/OkHttpClientTransportTest.java index 8e3552400d..29c5710743 100644 --- a/okhttp/src/test/java/io/grpc/okhttp/OkHttpClientTransportTest.java +++ b/okhttp/src/test/java/io/grpc/okhttp/OkHttpClientTransportTest.java @@ -62,6 +62,7 @@ import io.grpc.InternalStatus; import io.grpc.Metadata; import io.grpc.MethodDescriptor; import io.grpc.MethodDescriptor.MethodType; +import io.grpc.ProxyParameters; import io.grpc.Status; import io.grpc.Status.Code; import io.grpc.StatusException; @@ -70,7 +71,6 @@ import io.grpc.internal.ClientStreamListener; import io.grpc.internal.ClientTransport; import io.grpc.internal.GrpcUtil; import io.grpc.internal.ManagedClientTransport; -import io.grpc.internal.ProxyParameters; import io.grpc.internal.TransportTracer; import io.grpc.okhttp.OkHttpClientTransport.ClientFrameHandler; import io.grpc.okhttp.internal.ConnectionSpec; @@ -1573,8 +1573,8 @@ public class OkHttpClientTransportTest { ConnectionSpec.CLEARTEXT, DEFAULT_MAX_MESSAGE_SIZE, INITIAL_WINDOW_SIZE, - new ProxyParameters( - (InetSocketAddress) serverSocket.getLocalSocketAddress(), NO_USER, NO_PW), + ProxyParameters.forAddress( + (InetSocketAddress) serverSocket.getLocalSocketAddress()).build(), tooManyPingsRunnable, DEFAULT_MAX_INBOUND_METADATA_SIZE, transportTracer); @@ -1625,8 +1625,8 @@ public class OkHttpClientTransportTest { ConnectionSpec.CLEARTEXT, DEFAULT_MAX_MESSAGE_SIZE, INITIAL_WINDOW_SIZE, - new ProxyParameters( - (InetSocketAddress) serverSocket.getLocalSocketAddress(), NO_USER, NO_PW), + ProxyParameters.forAddress( + (InetSocketAddress) serverSocket.getLocalSocketAddress()).build(), tooManyPingsRunnable, DEFAULT_MAX_INBOUND_METADATA_SIZE, transportTracer); @@ -1676,8 +1676,8 @@ public class OkHttpClientTransportTest { ConnectionSpec.CLEARTEXT, DEFAULT_MAX_MESSAGE_SIZE, INITIAL_WINDOW_SIZE, - new ProxyParameters( - (InetSocketAddress) serverSocket.getLocalSocketAddress(), NO_USER, NO_PW), + ProxyParameters.forAddress( + (InetSocketAddress) serverSocket.getLocalSocketAddress()).build(), tooManyPingsRunnable, DEFAULT_MAX_INBOUND_METADATA_SIZE, transportTracer);