Skip to content

Commit

Permalink
Multi-target .NET 5 (#987)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNK authored Aug 20, 2020
1 parent 6df196c commit ef77760
Show file tree
Hide file tree
Showing 128 changed files with 887 additions and 343 deletions.
3 changes: 2 additions & 1 deletion build/dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
<GrpcDotNetPackageVersion>2.30.0</GrpcDotNetPackageVersion> <!-- Used by example projects -->
<GrpcPackageVersion>2.31.0-pre2</GrpcPackageVersion>
<MicrosoftAspNetCoreAppPackageVersion>3.1.3</MicrosoftAspNetCoreAppPackageVersion>
<MicrosoftAspNetCoreBlazorPackageVersion>3.2.0</MicrosoftAspNetCoreBlazorPackageVersion>
<MicrosoftAspNetCoreBlazorPackageVersion>5.0.0-rc.1.20381.8</MicrosoftAspNetCoreBlazorPackageVersion>
<MicrosoftAspNetCoreBlazor31PackageVersion>3.2.0</MicrosoftAspNetCoreBlazor31PackageVersion>
<MicrosoftBuildLocatorPackageVersion>1.2.2</MicrosoftBuildLocatorPackageVersion>
<MicrosoftBuildPackageVersion>16.0.461</MicrosoftBuildPackageVersion>
<MicrosoftCodeAnalysisFxCopAnalyzersPackageVersion>3.0.0</MicrosoftCodeAnalysisFxCopAnalyzersPackageVersion>
Expand Down
4 changes: 4 additions & 0 deletions build/get-dotnet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ echo "Downloading install script: $install_script_url => $install_script_path"
curl -sSL -o $install_script_path $install_script_url
chmod +x $install_script_path

# Install .NET Core 3.x SDK to run 3.x test targets
$install_script_path -v 3.1.300 -i $dotnet_install_path

# Install .NET version specified by global.json
$install_script_path -v $sdk_version -i $dotnet_install_path
23 changes: 4 additions & 19 deletions build_and_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@ example_solutions=( $( ls examples/**/*.sln ) )

for example_solution in "${example_solutions[@]}"
do
# dotnet build uses msbuild, and attempts to speed consecutive builds by reusing processes.
# This can become a problem when multiple versions of Grpc.Tools are used between builds.
# The different versions will conflict. Shutdown build processes between builds to avoid conflicts.
# Will be fixed in msbuild 16.5 - https://github.com/microsoft/msbuild/issues/1754
dotnet build-server shutdown

dotnet build $example_solution -c Release
done

Expand All @@ -42,20 +36,11 @@ test_projects=( $( ls test/**/*Tests.csproj ) )

for test_project in "${test_projects[@]}"
do
# "dotnet test" is hanging when it writes to console for an unknown reason
# Tracking issue at https://github.com/microsoft/vstest/issues/2080
# Write test output to a text file and then write the text file to console as a workaround
{
dotnet test $test_project -c Release -v n --no-build &> ${test_project##*/}.log.txt &&
echo "Success" &&
cat ${test_project##*/}.log.txt
} || {
echo "Failure" &&
cat ${test_project##*/}.log.txt &&
exit 1
}
# https://github.com/microsoft/vstest/issues/2080#issuecomment-539879345
dotnet test $test_project -c Release -v n --no-build < /dev/null
done

echo "Tests finished"

source grpcweb_interoptests.sh
# Temporarily disable while using nightly .NET SDK build
# source grpcweb_interoptests.sh
6 changes: 3 additions & 3 deletions examples/Blazor/Client/Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="$(MicrosoftAspNetCoreBlazorPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="$(MicrosoftAspNetCoreBlazorPackageVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="$(MicrosoftAspNetCoreBlazorPackageVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="$(MicrosoftAspNetCoreBlazor31PackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="$(MicrosoftAspNetCoreBlazor31PackageVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="$(MicrosoftAspNetCoreBlazor31PackageVersion)" PrivateAssets="all" />

<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufPackageVersion)" />
<PackageReference Include="Grpc.Tools" Version="$(GrpcPackageVersion)" PrivateAssets="All" />
Expand Down
2 changes: 1 addition & 1 deletion examples/Blazor/Server/Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<Protobuf Include="..\Proto\count.proto" GrpcServices="Server" Link="Protos\count.proto" />

<PackageReference Include="Microsoft.AspNetCore.Components" Version="$(MicrosoftAspNetCoreAppPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="$(MicrosoftAspNetCoreBlazorPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="$(MicrosoftAspNetCoreBlazor31PackageVersion)" />
<PackageReference Include="Grpc.AspNetCore" Version="$(GrpcDotNetPackageVersion)" />
<PackageReference Include="Grpc.AspNetCore.Web" Version="$(GrpcDotNetPackageVersion)" />
</ItemGroup>
Expand Down
8 changes: 6 additions & 2 deletions examples/Worker/Client/Client.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">

<Project Sdk="Microsoft.NET.Sdk.Web">
<!--
TODO(JamesNK): SDK temporarily changed from Microsoft.NET.Sdk.Worker to Microsoft.NET.Sdk.Web
because of .NET 5 bug.
-->

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UserSecretsId>dotnet-Client-33BD397C-6A11-40D0-AF85-24B9610F7517</UserSecretsId>
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "3.1.300"
"version": "5.0.100-rc.1.20419.15"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void GlobalSetup()

var handler = TestHttpMessageHandler.Create(async r =>
{
await r.Content.CopyToAsync(Stream.Null);
await r.Content!.CopyToAsync(Stream.Null);
var content = new ByteArrayContent(requestMessage);
content.Headers.ContentType = new MediaTypeHeaderValue("application/grpc");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ namespace Grpc.AspNetCore.Microbenchmarks.Internal
{
public class TestHttpResponseTrailersFeature : IHttpResponseTrailersFeature
{
public IHeaderDictionary? Trailers { get; set; }
public IHeaderDictionary Trailers { get; set; } = default!;
}
}
2 changes: 1 addition & 1 deletion perf/benchmarkapps/BenchmarkClient/BenchmarkClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<DisableAspNetCoreDefaultClientTypeOverride>true</DisableAspNetCoreDefaultClientTypeOverride>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework Condition="'$(BenchmarksTargetFramework)' != ''">$(BenchmarksTargetFramework)</TargetFramework>
<OutputType>Exe</OutputType>
<!-- Uncomment line below to enable gRPC-Web on the server -->
Expand Down
2 changes: 1 addition & 1 deletion perf/benchmarkapps/GrpcClient/GrpcClient.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework Condition="'$(BenchmarksTargetFramework)' != ''">$(BenchmarksTargetFramework)</TargetFramework>
<OutputType>Exe</OutputType>
<!-- Enable server GC to more closely simulate a microservice app making calls -->
Expand Down
2 changes: 1 addition & 1 deletion perf/benchmarkapps/GrpcCoreServer/GrpcCoreServer.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework Condition="'$(BenchmarksTargetFramework)' != ''">$(BenchmarksTargetFramework)</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<IsGrpcPublishedPackage>true</IsGrpcPublishedPackage>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFrameworks>netcoreapp3.0;net5.0</TargetFrameworks>

<!-- Disable analysis for ConfigureAwait(false) -->
<WarningsNotAsErrors>$(WarningsNotAsErrors);CA2007</WarningsNotAsErrors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<IsGrpcPublishedPackage>true</IsGrpcPublishedPackage>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFrameworks>netcoreapp3.0;net5.0</TargetFrameworks>

<!-- Disable analysis for ConfigureAwait(false) -->
<WarningsNotAsErrors>$(WarningsNotAsErrors);CA2007</WarningsNotAsErrors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<IsGrpcPublishedPackage>true</IsGrpcPublishedPackage>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFrameworks>netcoreapp3.0;net5.0</TargetFrameworks>

<!-- Disable analysis for ConfigureAwait(false) -->
<WarningsNotAsErrors>$(WarningsNotAsErrors);CA2007</WarningsNotAsErrors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static IServiceCollection AddGrpcReflection(this IServiceCollection servi
var grpcEndpointMetadata = endpointDataSource.Endpoints
.Select(ep => ep.Metadata.GetMetadata<GrpcMethodMetadata>())
.Where(m => m != null)
.OfType<GrpcMethodMetadata>()
.ToList();
var serviceTypes = grpcEndpointMetadata.Select(m => m.ServiceType).Distinct().ToList();
Expand Down
2 changes: 1 addition & 1 deletion src/Grpc.AspNetCore.Server/Grpc.AspNetCore.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<IsGrpcPublishedPackage>true</IsGrpcPublishedPackage>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFrameworks>netcoreapp3.0;net5.0</TargetFrameworks>

<!-- Disable analysis for ConfigureAwait(false) -->
<WarningsNotAsErrors>$(WarningsNotAsErrors);CA2007</WarningsNotAsErrors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,32 +51,12 @@ public Task HandleCallAsync(HttpContext httpContext)
{
if (GrpcProtocolHelpers.IsInvalidContentType(httpContext, out var error))
{
// This might be a CORS preflight request and CORS middleware hasn't been configured
if (GrpcProtocolHelpers.IsCorsPreflightRequest(httpContext))
{
GrpcServerLog.UnhandledCorsPreflightRequest(Logger);

GrpcProtocolHelpers.BuildHttpErrorResponse(httpContext.Response, StatusCodes.Status405MethodNotAllowed, StatusCode.Internal, "Unhandled CORS preflight request received. CORS may not be configured correctly in the application.");
httpContext.Response.Headers[HeaderNames.Allow] = HttpMethods.Post;
return Task.CompletedTask;
}
else
{
GrpcServerLog.UnsupportedRequestContentType(Logger, httpContext.Request.ContentType);

GrpcProtocolHelpers.BuildHttpErrorResponse(httpContext.Response, StatusCodes.Status415UnsupportedMediaType, StatusCode.Internal, error);
return Task.CompletedTask;
}
return ProcessInvalidContentTypeRequest(httpContext, error);
}
if (httpContext.Request.Protocol != GrpcProtocolConstants.Http2Protocol &&
httpContext.Request.Protocol != GrpcProtocolConstants.Http20Protocol)
{
GrpcServerLog.UnsupportedRequestProtocol(Logger, httpContext.Request.Protocol);

var protocolError = $"Request protocol '{httpContext.Request.Protocol}' is not supported.";
GrpcProtocolHelpers.BuildHttpErrorResponse(httpContext.Response, StatusCodes.Status426UpgradeRequired, StatusCode.Internal, protocolError);
httpContext.Response.Headers[HeaderNames.Upgrade] = GrpcProtocolConstants.Http2Protocol;
return Task.CompletedTask;
if (!GrpcProtocolConstants.IsHttp2(httpContext.Request.Protocol))
{
return ProcessNonHttp2Request(httpContext);
}

var serverCallContext = new HttpContextServerCallContext(httpContext, MethodInvoker.Options, typeof(TRequest), typeof(TResponse), Logger);
Expand Down Expand Up @@ -147,5 +127,35 @@ protected void DisableMinRequestBodyDataRateAndMaxRequestBodySize(HttpContext ht
}
}
}

private Task ProcessNonHttp2Request(HttpContext httpContext)
{
GrpcServerLog.UnsupportedRequestProtocol(Logger, httpContext.Request.Protocol);

var protocolError = $"Request protocol '{httpContext.Request.Protocol}' is not supported.";
GrpcProtocolHelpers.BuildHttpErrorResponse(httpContext.Response, StatusCodes.Status426UpgradeRequired, StatusCode.Internal, protocolError);
httpContext.Response.Headers[HeaderNames.Upgrade] = GrpcProtocolConstants.Http2Protocol;
return Task.CompletedTask;
}

private Task ProcessInvalidContentTypeRequest(HttpContext httpContext, string error)
{
// This might be a CORS preflight request and CORS middleware hasn't been configured
if (GrpcProtocolHelpers.IsCorsPreflightRequest(httpContext))
{
GrpcServerLog.UnhandledCorsPreflightRequest(Logger);

GrpcProtocolHelpers.BuildHttpErrorResponse(httpContext.Response, StatusCodes.Status405MethodNotAllowed, StatusCode.Internal, "Unhandled CORS preflight request received. CORS may not be configured correctly in the application.");
httpContext.Response.Headers[HeaderNames.Allow] = HttpMethods.Post;
return Task.CompletedTask;
}
else
{
GrpcServerLog.UnsupportedRequestContentType(Logger, httpContext.Request.ContentType);

GrpcProtocolHelpers.BuildHttpErrorResponse(httpContext.Response, StatusCodes.Status415UnsupportedMediaType, StatusCode.Internal, error);
return Task.CompletedTask;
}
}
}
}
47 changes: 46 additions & 1 deletion src/Grpc.AspNetCore.Server/Internal/GrpcProtocolConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;
using Microsoft.Net.Http.Headers;

namespace Grpc.AspNetCore.Server.Internal
Expand All @@ -28,17 +30,44 @@ internal static class GrpcProtocolConstants
internal const string GrpcWebContentType = "application/grpc-web";
internal const string GrpcWebTextContentType = "application/grpc-web-text";

internal const string Http2Protocol = "HTTP/2"; // This is what Kestrel sets
#if NET5_0
internal static readonly string Http2Protocol = HttpProtocol.Http2;
#else
internal const string Http2Protocol = "HTTP/2";
#endif
internal const string Http20Protocol = "HTTP/2.0"; // This is what IIS sets

#if NET5_0
internal static readonly string TimeoutHeader = HeaderNames.GrpcTimeout;
#else
internal const string TimeoutHeader = "grpc-timeout";
#endif

#if NET5_0
internal static readonly string MessageEncodingHeader = HeaderNames.GrpcEncoding;
#else
internal const string MessageEncodingHeader = "grpc-encoding";
#endif

#if NET5_0
internal static readonly string MessageAcceptEncodingHeader = HeaderNames.GrpcAcceptEncoding;
#else
internal const string MessageAcceptEncodingHeader = "grpc-accept-encoding";
#endif

internal const string CompressionRequestAlgorithmHeader = "grpc-internal-encoding-request";

#if NET5_0
internal static readonly string StatusTrailer = HeaderNames.GrpcStatus;
#else
internal const string StatusTrailer = "grpc-status";
#endif

#if NET5_0
internal static readonly string MessageTrailer = HeaderNames.GrpcMessage;
#else
internal const string MessageTrailer = "grpc-message";
#endif

internal const string IdentityGrpcEncoding = "identity";
internal const int ResetStreamNoError = 0;
Expand All @@ -61,5 +90,21 @@ internal static class GrpcProtocolConstants
// Maxmimum deadline of 99999999s is consistent with Grpc.Core
// https://github.com/grpc/grpc/blob/907a1313a87723774bf59d04ed432602428245c3/src/core/lib/transport/timeout_encoding.h#L32-L34
internal const long MaxDeadlineTicks = 99999999 * TimeSpan.TicksPerSecond;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsHttp2(string protocol)
{
#if NET5_0
return HttpProtocol.IsHttp2(protocol);
#else
return protocol == Http2Protocol || protocol == Http20Protocol;
#endif
}

internal static bool IsGrpcEncodingIdentity(string encoding)
{
return ReferenceEquals(encoding, IdentityGrpcEncoding) ||
string.Equals(encoding, IdentityGrpcEncoding, StringComparison.Ordinal);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void Reset()

var canCompress =
GrpcProtocolHelpers.CanWriteCompressed(_serverCallContext.WriteOptions) &&
!string.Equals(_serverCallContext.ResponseGrpcEncoding, GrpcProtocolConstants.IdentityGrpcEncoding, StringComparison.Ordinal);
!GrpcProtocolConstants.IsGrpcEncodingIdentity(_serverCallContext.ResponseGrpcEncoding);

if (canCompress)
{
Expand Down
Loading

0 comments on commit ef77760

Please sign in to comment.