Description
Describe the bug
When using grpc-dotnet and Blazor together to call a GRPC API, the User-Agent is set to "grpc-dotnet/$assemblyVersion" in Safari and Firefox. In Chrome and Edge it is the actual browser User-Agent.
https://docs.microsoft.com/en-us/aspnet/core/grpc/services?view=aspnetcore-5.0 for example describes how to read the User-Agent:
public override Task<ExampleResponse> UnaryCall(ExampleRequest request, ServerCallContext context)
{
var userAgent = context.RequestHeaders.GetValue("user-agent");
// ...
return Task.FromResult(new ExampleResponse());
}
(Migrated from dotnet/AspNetCore.Docs#21178)
To Reproduce
Use GRPC with Blazor as described at https://docs.microsoft.com/en-us/aspnet/core/grpc/browser?view=aspnetcore-5.0 and look at the traffic in Safari. The User-Agent will be for example "grpc-dotnet/2.34.0.0".
You can also check out https://our.gatekeeper.page in Safari or Firefox and look at the request to the "WhoAmI" endpoint to see the header being wrong. The code for this can be found at https://github.com/getgatekeeper/server.
The Blazor example from https://github.com/grpc/grpc-dotnet/tree/master/examples/Blazor should also have the same issue.
The issue seems potentially related to the following piece of code in Grpc.Net.Client/Internal/GrpcCall.cs
. I wonder if Chrome/Edge just ignore the header being overwritten whilst Safari and Firefox obeys it:
// User agent is optional but recommended.
headers.TryAddWithoutValidation(GrpcProtocolConstants.UserAgentHeader, GrpcProtocolConstants.UserAgentHeaderValue);
Test plan
Browser | Sends correct User-Agent | Screenshot |
---|---|---|
Safari | ❌ | ![]() |
Firefox | ❌ | ![]() |
Chrome | ✅ | ![]() |
Edge | ✅ | ![]() |