Skip to content

Commit b81a92d

Browse files
authored
Don't warn about Android native handler with grpc-web (#2020)
1 parent 4c07771 commit b81a92d

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

src/Grpc.Net.Client/GrpcChannel.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -431,13 +431,15 @@ private HttpMessageInvoker CreateInternalHttpInvoker(HttpMessageHandler? handler
431431
// in advanced gRPC scenarios. We want Android to use SocketsHttpHandler. Throw an error if:
432432
// 1. Client is running on Android.
433433
// 2. Channel is created with HttpClientHandler.
434-
// 3. UseNativeHttpHandler switch is true.
434+
// 3. Channel is not using GrpcWebHandler. grpc-web is compatible with the native handler.
435+
// 4. UseNativeHttpHandler switch is true.
435436
if (OperatingSystem.IsAndroid)
436437
{
437438
// GetHttpHandlerType recurses through DelegatingHandlers that may wrap the HttpClientHandler.
438439
var httpClientHandler = HttpRequestHelpers.GetHttpHandlerType<HttpClientHandler>(handler);
440+
var grpcWebHandler = HttpRequestHelpers.GetHttpHandlerType(handler, "Grpc.Net.Client.Web.GrpcWebHandler");
439441

440-
if (httpClientHandler != null && RuntimeHelpers.QueryRuntimeSettingSwitch("System.Net.Http.UseNativeHttpHandler", defaultValue: false))
442+
if (httpClientHandler != null && grpcWebHandler == null && RuntimeHelpers.QueryRuntimeSettingSwitch("System.Net.Http.UseNativeHttpHandler", defaultValue: false))
441443
{
442444
throw new InvalidOperationException("The channel configuration isn't valid on Android devices. " +
443445
"The channel is configured to use HttpClientHandler and Android's native HTTP/2 library. " +

test/Grpc.Net.Client.Tests/Grpc.Net.Client.Tests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
<ItemGroup>
3232
<ProjectReference Include="..\..\src\Grpc.Net.Client\Grpc.Net.Client.csproj" />
33+
<ProjectReference Include="..\..\src\Grpc.Net.Client.Web\Grpc.Net.Client.Web.csproj" />
3334

3435
<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufPackageVersion)" />
3536
<PackageReference Include="Grpc.Tools" Version="$(GrpcToolsPackageVersion)" PrivateAssets="All" />

test/Grpc.Net.Client.Tests/GrpcChannelTests.cs

+41-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
using Microsoft.Extensions.Logging.Testing;
2727
using NUnit.Framework;
2828
using Grpc.Net.Client.Internal;
29-
using System.Net;
29+
using Grpc.Net.Client.Web;
3030
#if SUPPORT_LOAD_BALANCING
3131
using Grpc.Net.Client.Balancer;
3232
using Grpc.Net.Client.Balancer.Internal;
@@ -402,7 +402,7 @@ public async Task Dispose_CalledWhileActiveCalls_ActiveCallsDisposed()
402402
Assert.AreEqual(0, channel.ActiveCalls.Count);
403403
}
404404

405-
[TestCase(null)]
405+
[TestCase(true)]
406406
[TestCase(false)]
407407
public void HttpHandler_HttpClientHandlerOverNativeOnAndroid_ThrowError(bool useDelegatingHandlers)
408408
{
@@ -415,6 +415,8 @@ public void HttpHandler_HttpClientHandlerOverNativeOnAndroid_ThrowError(bool use
415415
services.AddSingleton<IOperatingSystem>(new TestOperatingSystem { IsAndroid = true });
416416

417417
HttpMessageHandler handler = new HttpClientHandler();
418+
419+
// Add an extra handler to verify that test successfully recurses down custom handlers.
418420
if (useDelegatingHandlers)
419421
{
420422
handler = new TestDelegatingHandler(handler);
@@ -443,6 +445,43 @@ public void HttpHandler_HttpClientHandlerOverNativeOnAndroid_ThrowError(bool use
443445
}
444446
}
445447

448+
[TestCase(true)]
449+
[TestCase(false)]
450+
public void HttpHandler_HttpClientHandlerOverNativeOnAndroid_HasGrpcWebHandler_ThrowError(bool useDelegatingHandlers)
451+
{
452+
// Arrange
453+
AppContext.SetSwitch("System.Net.Http.UseNativeHttpHandler", true);
454+
455+
try
456+
{
457+
var services = new ServiceCollection();
458+
services.AddSingleton<IOperatingSystem>(new TestOperatingSystem { IsAndroid = true });
459+
460+
HttpMessageHandler handler = new HttpClientHandler();
461+
handler = new GrpcWebHandler(handler);
462+
463+
// Add an extra handler to verify that test successfully recurses down custom handlers.
464+
if (useDelegatingHandlers)
465+
{
466+
handler = new TestDelegatingHandler(handler);
467+
}
468+
469+
var channel = GrpcChannel.ForAddress("https://localhost", new GrpcChannelOptions
470+
{
471+
HttpHandler = handler,
472+
ServiceProvider = services.BuildServiceProvider()
473+
});
474+
475+
// Assert
476+
Assert.IsTrue(channel.OperatingSystem.IsAndroid);
477+
}
478+
finally
479+
{
480+
// Reset switch for other tests.
481+
AppContext.SetSwitch("System.Net.Http.UseNativeHttpHandler", false);
482+
}
483+
}
484+
446485
private class TestDelegatingHandler : DelegatingHandler
447486
{
448487
public TestDelegatingHandler(HttpMessageHandler innerHandler) : base(innerHandler)

0 commit comments

Comments
 (0)