Skip to content

Commit 06fa6c2

Browse files
authored
Fix GrpcWebHandler not always resetting HTTP version back to 2.0 (#810)
1 parent 0b37fb3 commit 06fa6c2

File tree

4 files changed

+37
-17
lines changed

4 files changed

+37
-17
lines changed

examples/Blazor/Server/Program.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,23 @@
1616

1717
#endregion
1818

19-
using Microsoft.AspNetCore;
2019
using Microsoft.AspNetCore.Hosting;
21-
using Microsoft.Extensions.Configuration;
20+
using Microsoft.Extensions.Hosting;
2221

2322
namespace Server
2423
{
2524
public class Program
2625
{
2726
public static void Main(string[] args)
2827
{
29-
BuildWebHost(args).Run();
28+
CreateHostBuilder(args).Build().Run();
3029
}
3130

32-
public static IWebHost BuildWebHost(string[] args) =>
33-
WebHost.CreateDefaultBuilder(args)
34-
.UseConfiguration(new ConfigurationBuilder()
35-
.AddCommandLine(args)
36-
.Build())
37-
.UseStartup<Startup>()
38-
.Build();
31+
public static IHostBuilder CreateHostBuilder(string[] args) =>
32+
Host.CreateDefaultBuilder(args)
33+
.ConfigureWebHostDefaults(webBuilder =>
34+
{
35+
webBuilder.UseStartup<Startup>();
36+
});
3937
}
4038
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Debug",
5+
"System": "Information",
6+
"Grpc": "Information",
7+
"Microsoft": "Information"
8+
}
9+
}
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information"
5+
}
6+
},
7+
"AllowedHosts": "*"
8+
}

src/Grpc.Net.Client.Web/GrpcWebHandler.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,27 @@ private async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request
113113
request.Content = new GrpcWebRequestContent(request.Content, _mode);
114114
if (_httpVersion != null)
115115
{
116+
// This doesn't guarantee that the specified version is used. Some handlers will ignore it.
117+
// For example, version in the browser always negotiated by the browser and HttpClient
118+
// uses what the browser has negotiated.
116119
request.Version = _httpVersion;
117120
}
118121

119122
var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
120123

121-
if (_httpVersion != null)
122-
{
123-
// If a HTTP version has been specified then we need to reset it back to 2.0.
124-
// The gRPC client validates HTTP version 2.0.
125-
response.Version = HttpVersion.Version20;
126-
}
127-
128124
if (IsMatchingResponseContentType(_mode, response.Content.Headers.ContentType?.MediaType))
129125
{
130126
response.Content = new GrpcWebResponseContent(response.Content, _mode, response.TrailingHeaders);
131127
}
132128

129+
// The gRPC client validates HTTP version 2.0 and will error if it isn't. Always set
130+
// the version to 2.0, even for non-gRPC content type. The client maps HTTP status codes
131+
// to gRPC statuses, e.g. HTTP 404 -> gRPC unimplemented.
132+
//
133+
// Note: Some handlers don't correctly set HttpResponseMessage.Version.
134+
// We can't rely on it being set correctly. It is safest to always set it to 2.0.
135+
response.Version = HttpVersion.Version20;
136+
133137
return response;
134138
}
135139

0 commit comments

Comments
 (0)