Grpc-dotnet: gRPC doesn't work without HTTPS

Created on 10 Sep 2019  路  2Comments  路  Source: grpc/grpc-dotnet

Short version: gRPC services only work over https. Is this by design?

Longer version:

OK, so I have an ASP.NET Core 3.0 Preview 9 gRPC service and when I run it on an https URL it works fine, but when I run it on an http URL I get exceptions from the client:

System.Net.Http.HttpRequestException: An error occurred while sending the request.
 ---> System.IO.IOException: The response ended prematurely.
   at System.Net.Http.HttpConnection.FillAsync()
   at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean foldedHeadersAllowed)
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Grpc.Net.Client.Internal.GrpcCall`2.SendAsync(HttpRequestMessage request)
   at Grpc.Net.Client.Internal.GrpcCall`2.GetResponseAsync()
   at Grpc.Net.Client.Internal.GrpcCall`2.GetResponseHeadersAsync()
   at StockWeb.Controllers.HomeController.GetAsync(Int32 id) in D:\Book\code\Kubed\src\StockWeb\Controllers\HomeController.cs:line 39

(rest of stack trace elided)

I know gRPC uses HTTP/2, and HTTP/2 is supposed to use SSL/TLS, but per a conversation with @JamesNK that's not actually a hard requirement, so I'm wondering if there's a configuration setting I'm missing somewhere in the client or server that would let me run over plain old http.

Most helpful comment

Argh. I just needed that switch on the client side. All working now, thanks @JamesNK

AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0#call-insecure-grpc-services-with-net-core-client

All 2 comments

All the functional tests run without https so it certainly works. What is your Kestrel endpoint configured as? TLS is required for negotiation when an endpoint is HttpProtocols.Http1AndHttp2: https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0#unable-to-start-aspnet-core-grpc-app-on-macos

Argh. I just needed that switch on the client side. All working now, thanks @JamesNK

AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0#call-insecure-grpc-services-with-net-core-client

Was this page helpful?
0 / 5 - 0 ratings