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.
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
Most helpful comment
Argh. I just needed that switch on the client side. All working now, thanks @JamesNK
https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0#call-insecure-grpc-services-with-net-core-client