The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#) https://grpc.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

108 lines
3.9 KiB

#region Copyright notice and license
// Copyright 2021 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Grpc.Core.Internal
{
/// <summary>
/// Helps constructing the grpc-csharp component of the user agent string.
/// </summary>
internal class UserAgentStringProvider
{
static readonly UserAgentStringProvider defaultInstance;
readonly string userAgentString;
static UserAgentStringProvider()
{
defaultInstance = new UserAgentStringProvider(VersionInfo.CurrentVersion, PlatformApis.FrameworkDescription, PlatformApis.ClrVersion, PlatformApis.GetGrpcCoreTargetFrameworkMoniker(), PlatformApis.ProcessArchitecture);
}
public static UserAgentStringProvider DefaultInstance => defaultInstance;
public string GrpcCsharpUserAgentString => userAgentString;
public UserAgentStringProvider(string grpcCsharpVersion, string frameworkDescription, string clrVersion, string tfm, CommonPlatformDetection.CpuArchitecture arch)
{
var detailComponents = new List<string>();
string sanitizedFrameworkDescription = SanitizeFrameworkDescription(frameworkDescription);
if (sanitizedFrameworkDescription != null)
{
detailComponents.Add(sanitizedFrameworkDescription);
}
if (clrVersion != null)
{
detailComponents.Add($"CLR {clrVersion}");
}
if (tfm != null)
{
detailComponents.Add(tfm);
}
string architectureString = TryGetArchitectureString(arch);
if (architectureString != null)
{
detailComponents.Add(architectureString);
}
// TODO(jtattermusch): consider adding details about running under unity / xamarin etc.
var details = string.Join("; ", detailComponents);
userAgentString = $"grpc-csharp/{grpcCsharpVersion} ({details})";
}
static string TryGetArchitectureString(CommonPlatformDetection.CpuArchitecture arch)
{
if (arch == CommonPlatformDetection.CpuArchitecture.Unknown)
{
return null;
}
return arch.ToString().ToLowerInvariant();
}
static string SanitizeFrameworkDescription(string frameworkDescription)
{
if (frameworkDescription == null)
{
return null;
}
// Some platforms return more details in the FrameworkDescription string than we want.
// e.g. on mono, we will get something like "Mono 6.12.0.93 (2020-02/620cf538206 Tue Aug 25 14:04:52 EDT 2020)"
// For user agent string, we only want basic info on framework name and its version.
var parts = new List<string>(frameworkDescription.Split(' '));
int i = 0;
for (; i < parts.Count; i++)
{
var part = parts[i];
if (!Regex.IsMatch(part, @"^[-.,+@A-Za-z0-9]*$"))
{
// stop once we find first part that's not framework name or version
break;
}
}
var result = string.Join(" ", parts.GetRange(0, i));
return !string.IsNullOrEmpty(result) ? result : null;
}
}
}