Skip to content

Commit 54d7f29

Browse files
authored
Change proxy detection to log a message (#2087)
1 parent b82c0c7 commit 54d7f29

File tree

2 files changed

+44
-39
lines changed

2 files changed

+44
-39
lines changed

src/Grpc.Net.Client/GrpcChannel.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#region Copyright notice and license
1+
#region Copyright notice and license
22

33
// Copyright 2019 The gRPC Authors
44
//
@@ -114,14 +114,15 @@ internal GrpcChannel(Uri address, GrpcChannelOptions channelOptions) : base(addr
114114
LoggerFactory = channelOptions.LoggerFactory ?? channelOptions.ResolveService<ILoggerFactory>(NullLoggerFactory.Instance);
115115
OperatingSystem = channelOptions.ResolveService<IOperatingSystem>(Internal.OperatingSystem.Instance);
116116
RandomGenerator = channelOptions.ResolveService<IRandomGenerator>(new RandomGenerator());
117+
Logger = LoggerFactory.CreateLogger<GrpcChannel>();
117118

118119
#if SUPPORT_LOAD_BALANCING
119120
InitialReconnectBackoff = channelOptions.InitialReconnectBackoff;
120121
MaxReconnectBackoff = channelOptions.MaxReconnectBackoff;
121122

122123
var resolverFactory = GetResolverFactory(channelOptions);
123124
ResolveCredentials(channelOptions, out _isSecure, out _callCredentials);
124-
(HttpHandlerType, ConnectTimeout) = CalculateHandlerContext(address, _isSecure, channelOptions);
125+
(HttpHandlerType, ConnectTimeout) = CalculateHandlerContext(Logger, address, _isSecure, channelOptions);
125126

126127
SubchannelTransportFactory = channelOptions.ResolveService<ISubchannelTransportFactory>(new SubChannelTransportFactory(this));
127128

@@ -150,7 +151,7 @@ internal GrpcChannel(Uri address, GrpcChannelOptions channelOptions) : base(addr
150151
throw new ArgumentException($"Address '{address.OriginalString}' doesn't have a host. Address should include a scheme, host, and optional port. For example, 'https://localhost:5001'.");
151152
}
152153
ResolveCredentials(channelOptions, out _isSecure, out _callCredentials);
153-
(HttpHandlerType, ConnectTimeout) = CalculateHandlerContext(address, _isSecure, channelOptions);
154+
(HttpHandlerType, ConnectTimeout) = CalculateHandlerContext(Logger, address, _isSecure, channelOptions);
154155
#endif
155156

156157
HttpInvoker = channelOptions.HttpClient ?? CreateInternalHttpInvoker(channelOptions.HttpHandler);
@@ -161,7 +162,6 @@ internal GrpcChannel(Uri address, GrpcChannelOptions channelOptions) : base(addr
161162
MaxRetryBufferPerCallSize = channelOptions.MaxRetryBufferPerCallSize;
162163
CompressionProviders = ResolveCompressionProviders(channelOptions.CompressionProviders);
163164
MessageAcceptEncoding = GrpcProtocolHelpers.GetMessageAcceptEncoding(CompressionProviders);
164-
Logger = LoggerFactory.CreateLogger<GrpcChannel>();
165165
ThrowOperationCanceledOnCancellation = channelOptions.ThrowOperationCanceledOnCancellation;
166166
UnsafeUseInsecureChannelCallCredentials = channelOptions.UnsafeUseInsecureChannelCallCredentials;
167167
_createMethodInfoFunc = CreateMethodInfo;
@@ -220,7 +220,7 @@ private static bool IsHttpOrHttpsAddress(Uri address)
220220
return address.Scheme == Uri.UriSchemeHttps || address.Scheme == Uri.UriSchemeHttp;
221221
}
222222

223-
private static HttpHandlerContext CalculateHandlerContext(Uri address, bool isSecure, GrpcChannelOptions channelOptions)
223+
private static HttpHandlerContext CalculateHandlerContext(ILogger logger, Uri address, bool isSecure, GrpcChannelOptions channelOptions)
224224
{
225225
if (channelOptions.HttpHandler == null)
226226
{
@@ -267,10 +267,14 @@ private static HttpHandlerContext CalculateHandlerContext(Uri address, bool isSe
267267
// Proxy can be specified via:
268268
// - SocketsHttpHandler.Proxy. Set via app code.
269269
// - HttpClient.DefaultProxy. Set via environment variables, e.g. HTTPS_PROXY.
270-
if (IsProxied(socketsHttpHandler, address, isSecure))
270+
if (type == HttpHandlerType.SocketsHttpHandler)
271271
{
272-
type = HttpHandlerType.Custom;
273-
connectTimeout = null;
272+
if (IsProxied(socketsHttpHandler, address, isSecure))
273+
{
274+
logger.LogInformation("Proxy configuration is detected. How the gRPC client creates connections can cause unexpected behavior when a proxy is configured. " +
275+
"To ensure the client correctly uses a proxy, configure GrpcChannelOptions.HttpHandler to use HttpClientHandler. " +
276+
"Note that HttpClientHandler isn't compatible with load balancing.");
277+
}
274278
}
275279
#else
276280
type = HttpHandlerType.SocketsHttpHandler;

test/FunctionalTests/Client/ConnectionTests.cs

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#region Copyright notice and license
1+
#region Copyright notice and license
22

33
// Copyright 2019 The gRPC Authors
44
//
@@ -159,45 +159,46 @@ Task<HelloReply> Unary(HelloRequest request, ServerCallContext context)
159159
Assert.AreEqual("World", reply.Message);
160160
}
161161

162-
[Test]
163-
public async Task ConfiguredProxy_SslProxyTunnel()
164-
{
165-
using var proxyServer = LoopbackProxyServer.Create(new LoopbackProxyServer.Options());
166-
167-
Task<HelloReply> Unary(HelloRequest request, ServerCallContext context)
168-
{
169-
return Task.FromResult(new HelloReply { Message = request.Name });
170-
}
162+
[Test]
163+
[Ignore("Test disabled while figuring out the best solution for https://github.com/grpc/grpc-dotnet/issues/2075")]
164+
public async Task ConfiguredProxy_SslProxyTunnel()
165+
{
166+
using var proxyServer = LoopbackProxyServer.Create(new LoopbackProxyServer.Options());
171167

172-
// Arrange
173-
var method = Fixture.DynamicGrpc.AddUnaryMethod<HelloRequest, HelloReply>(Unary);
168+
Task<HelloReply> Unary(HelloRequest request, ServerCallContext context)
169+
{
170+
return Task.FromResult(new HelloReply { Message = request.Name });
171+
}
174172

175-
var http = Fixture.CreateHandler(TestServerEndpointName.Http2WithTls,
176-
configureHandler: handler =>
177-
{
178-
handler.Proxy = new WebProxy(proxyServer.Uri);
179-
});
173+
// Arrange
174+
var method = Fixture.DynamicGrpc.AddUnaryMethod<HelloRequest, HelloReply>(Unary);
180175

181-
using var channel = GrpcChannel.ForAddress(http.address, new GrpcChannelOptions
176+
var http = Fixture.CreateHandler(TestServerEndpointName.Http2WithTls,
177+
configureHandler: handler =>
182178
{
183-
LoggerFactory = LoggerFactory,
184-
HttpHandler = http.handler,
185-
DisposeHttpClient = true
179+
handler.Proxy = new WebProxy(proxyServer.Uri);
186180
});
187181

188-
var client = TestClientFactory.Create(channel, method);
182+
using var channel = GrpcChannel.ForAddress(http.address, new GrpcChannelOptions
183+
{
184+
LoggerFactory = LoggerFactory,
185+
HttpHandler = http.handler,
186+
DisposeHttpClient = true
187+
});
188+
189+
var client = TestClientFactory.Create(channel, method);
189190

190-
// Act
191-
var reply = await client.UnaryCall(new HelloRequest { Name = "World" }).ResponseAsync.DefaultTimeout();
191+
// Act
192+
var reply = await client.UnaryCall(new HelloRequest { Name = "World" }).ResponseAsync.DefaultTimeout();
192193

193-
// Assert
194-
Assert.AreEqual("World", reply.Message);
194+
// Assert
195+
Assert.AreEqual("World", reply.Message);
195196

196-
Assert.AreEqual(1, proxyServer.Connections);
197-
Assert.AreEqual(1, proxyServer.Requests.Count);
197+
Assert.AreEqual(1, proxyServer.Connections);
198+
Assert.AreEqual(1, proxyServer.Requests.Count);
198199

199-
var expected = $"CONNECT {http.address.Host}:{http.address.Port} HTTP/1.1";
200-
Assert.AreEqual(expected, proxyServer.Requests[0].RequestLine);
201-
}
200+
var expected = $"CONNECT {http.address.Host}:{http.address.Port} HTTP/1.1";
201+
Assert.AreEqual(expected, proxyServer.Requests[0].RequestLine);
202+
}
202203
#endif
203204
}

0 commit comments

Comments
 (0)