Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#region Copyright notice and license
#region Copyright notice and license

// Copyright 2019 The gRPC Authors
//
Expand Down Expand Up @@ -83,7 +83,8 @@ public void GlobalSetup()
compressionProviders: CompressionProviders,
responseCompressionAlgorithm: ResponseCompressionAlgorithm,
interceptors: Interceptors),
new TestGrpcServiceActivator<TestService>(new TestService())),
new TestGrpcServiceActivator<TestService>(new TestService()),
new InterceptorActivators(serviceProvider)),
NullLoggerFactory.Instance);

_trailers = new HeaderDictionary();
Expand Down
18 changes: 10 additions & 8 deletions src/Grpc.AspNetCore.Server/Grpc.AspNetCore.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@
<Compile Include="..\Shared\CommonGrpcProtocolHelpers.cs" Link="Internal\CommonGrpcProtocolHelpers.cs" />
<Compile Include="..\Shared\NonDisposableMemoryStream.cs" Link="Internal\NonDisposableMemoryStream.cs" />
<Compile Include="..\Shared\DefaultDeserializationContext.cs" Link="Internal\DefaultDeserializationContext.cs" />
<Compile Include="..\Shared\Server\BindMethodFinder.cs" Link="Model\Internal\BindMethodFinder.cs" />
<Compile Include="..\Shared\Server\ClientStreamingServerMethodInvoker.cs" Link="Model\Internal\ClientStreamingServerMethodInvoker.cs" />
<Compile Include="..\Shared\Server\DuplexStreamingServerMethodInvoker.cs" Link="Model\Internal\DuplexStreamingServerMethodInvoker.cs" />
<Compile Include="..\Shared\Server\InterceptorPipelineBuilder.cs" Link="Model\Internal\InterceptorPipelineBuilder.cs" />
<Compile Include="..\Shared\Server\MethodOptions.cs" Link="Model\Internal\MethodOptions.cs" />
<Compile Include="..\Shared\Server\ServerMethodInvokerBase.cs" Link="Model\Internal\ServerMethodInvokerBase.cs" />
<Compile Include="..\Shared\Server\ServerStreamingServerMethodInvoker.cs" Link="Model\Internal\ServerStreamingServerMethodInvoker.cs" />
<Compile Include="..\Shared\Server\UnaryServerMethodInvoker.cs" Link="Model\Internal\UnaryServerMethodInvoker.cs" />
<Compile Include="..\Shared\Server\BindMethodFinder.cs" Link="Model\Internal\Server\BindMethodFinder.cs" />
<Compile Include="..\Shared\Server\ClientStreamingServerMethodInvoker.cs" Link="Model\Internal\Server\ClientStreamingServerMethodInvoker.cs" />
<Compile Include="..\Shared\Server\DuplexStreamingServerMethodInvoker.cs" Link="Model\Internal\Server\DuplexStreamingServerMethodInvoker.cs" />
<Compile Include="..\Shared\Server\InterceptorPipelineBuilder.cs" Link="Model\Internal\Server\InterceptorPipelineBuilder.cs" />
<Compile Include="..\Shared\Server\MethodOptions.cs" Link="Model\Internal\Server\MethodOptions.cs" />
<Compile Include="..\Shared\Server\ServerMethodInvokerBase.cs" Link="Model\Internal\Server\ServerMethodInvokerBase.cs" />
<Compile Include="..\Shared\Server\ServerStreamingServerMethodInvoker.cs" Link="Model\Internal\Server\ServerStreamingServerMethodInvoker.cs" />
<Compile Include="..\Shared\Server\UnaryServerMethodInvoker.cs" Link="Model\Internal\Server\UnaryServerMethodInvoker.cs" />
<Compile Include="..\Shared\Server\ServerDynamicAccessConstants.cs" Link="Model\Internal\Server\ServerDynamicAccessConstants.cs" />
<Compile Include="..\Shared\Server\InterceptorActivators.cs" Link="Model\Internal\Server\InterceptorActivators.cs" />
<Compile Include="..\Shared\NullableAttributes.cs" Link="Internal\NullableAttributes.cs" />
<Compile Include="..\Shared\CodeAnalysisAttributes.cs" Link="Internal\CodeAnalysisAttributes.cs" />
<Compile Include="..\Shared\NonCapturingTimer.cs" Link="Internal\NonCapturingTimer.cs" />
Expand Down
2 changes: 2 additions & 0 deletions src/Grpc.AspNetCore.Server/GrpcServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using Grpc.AspNetCore.Server.Model;
using Grpc.AspNetCore.Server.Model.Internal;
using Grpc.Shared;
using Grpc.Shared.Server;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
Expand Down Expand Up @@ -69,6 +70,7 @@ public static IGrpcServerBuilder AddGrpc(this IServiceCollection services)
services.AddOptions();
services.TryAddSingleton<GrpcMarkerService>();
services.TryAddSingleton(typeof(ServerCallHandlerFactory<>));
services.TryAddSingleton<InterceptorActivators>();
services.TryAddSingleton(typeof(IGrpcServiceActivator<>), typeof(DefaultGrpcServiceActivator<>));
services.TryAddSingleton(typeof(IGrpcInterceptorActivator<>), typeof(DefaultGrpcInterceptorActivator<>));
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<GrpcServiceOptions>, GrpcServiceOptionsSetup>());
Expand Down
47 changes: 42 additions & 5 deletions src/Grpc.AspNetCore.Server/GrpcServiceOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ namespace Grpc.AspNetCore.Server;
public class GrpcServiceOptions
{
internal IList<ICompressionProvider>? _compressionProviders;
internal bool _maxReceiveMessageSizeConfigured;
internal int? _maxReceiveMessageSize;
internal bool _maxSendMessageSizeConfigured;
internal int? _maxSendMessageSize;
internal bool _maxSendMessageSizeSpecified;
internal bool _maxReceiveMessageSizeSpecified;

/// <summary>
/// Gets or sets the maximum message size in bytes that can be sent from the server.
Expand All @@ -45,7 +45,24 @@ public int? MaxSendMessageSize
set
{
_maxSendMessageSize = value;
_maxSendMessageSizeConfigured = true;
MaxSendMessageSizeSpecified = true;
}
}

/// <summary>
/// Gets or sets a flag indicating whether <see cref="MaxSendMessageSize"/> is specified.
/// This flag is automatically set to true when <see cref="MaxSendMessageSize"/> is configured.
/// </summary>
public bool MaxSendMessageSizeSpecified
{
get => _maxSendMessageSizeSpecified;
set
{
_maxSendMessageSizeSpecified = value;
if (!_maxSendMessageSizeSpecified)
{
_maxSendMessageSize = null;
}
}
}

Expand All @@ -62,7 +79,24 @@ public int? MaxReceiveMessageSize
set
{
_maxReceiveMessageSize = value;
_maxReceiveMessageSizeConfigured = true;
MaxReceiveMessageSizeSpecified = true;
}
}

/// <summary>
/// Gets or sets a flag indicating whether <see cref="MaxReceiveMessageSize"/> is specified.
/// This flag is automatically set to true when <see cref="MaxReceiveMessageSize"/> is configured.
/// </summary>
public bool MaxReceiveMessageSizeSpecified
{
get => _maxReceiveMessageSizeSpecified;
set
{
_maxReceiveMessageSizeSpecified = value;
if (!_maxReceiveMessageSizeSpecified)
{
_maxReceiveMessageSize = null;
}
}
}

Expand Down Expand Up @@ -113,7 +147,10 @@ public IList<ICompressionProvider> CompressionProviders
/// </summary>
public InterceptorCollection Interceptors { get; } = new InterceptorCollection();

internal bool SuppressCreatingService { get; set; }
/// <summary>
/// Gets or sets a value indicating whether creating a service is suppressed when handling a gRPC call.
/// </summary>
public bool SuppressCreatingService { get; set; }
}

/// <summary>
Expand Down
16 changes: 0 additions & 16 deletions src/Grpc.AspNetCore.Server/InterceptorRegistration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,8 @@ internal InterceptorRegistration([DynamicallyAccessedMembers(InterceptorAccessib
/// </summary>
public IReadOnlyList<object> Arguments => _args;

private IGrpcInterceptorActivator? _interceptorActivator;
private ObjectFactory? _factory;

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern",
Justification = "Type parameter members are preserved with DynamicallyAccessedMembers on InterceptorRegistration.Type property.")]
[UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode",
Justification = "Type definition is explicitly specified and type argument is always an Interceptor type.")]
internal IGrpcInterceptorActivator GetActivator(IServiceProvider serviceProvider)
{
// Not thread safe. Side effect is resolving the service twice.
if (_interceptorActivator == null)
{
_interceptorActivator = (IGrpcInterceptorActivator)serviceProvider.GetRequiredService(typeof(IGrpcInterceptorActivator<>).MakeGenericType(Type));
}

return _interceptorActivator;
}

internal ObjectFactory GetFactory()
{
// Not thread safe. Side effect is resolving the factory twice.
Expand Down
3 changes: 2 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,7 @@

using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Grpc.Shared.Server;
using Microsoft.AspNetCore.Http;
using Microsoft.Net.Http.Headers;

Expand Down Expand Up @@ -82,5 +83,5 @@ internal static int GetCancelErrorCode(string protocol)
return IsHttp3(protocol) ? Http3ResetStreamCancel : Http2ResetStreamCancel;
}

internal const DynamicallyAccessedMemberTypes ServiceAccessibility = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods;
internal const DynamicallyAccessedMemberTypes ServiceAccessibility = ServerDynamicAccessConstants.ServiceAccessibility;
}
18 changes: 9 additions & 9 deletions src/Grpc.AspNetCore.Server/Internal/GrpcServiceOptionsSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,19 @@

using System.IO.Compression;
using Grpc.Net.Compression;
using Grpc.Shared.Server;
using Microsoft.Extensions.Options;

namespace Grpc.AspNetCore.Server.Internal;

internal sealed class GrpcServiceOptionsSetup : IConfigureOptions<GrpcServiceOptions>
{
// Default to no send limit and 4mb receive limit.
// Matches the gRPC C impl defaults
// https://github.com/grpc/grpc/blob/977df7208a6e3f9a62a6369af5cd6e4b69b4fdec/include/grpc/impl/codegen/grpc_types.h#L413-L416
internal const int DefaultReceiveMaxMessageSize = 4 * 1024 * 1024;

public void Configure(GrpcServiceOptions options)
{
if (!options._maxReceiveMessageSizeConfigured)
if (!options.MaxReceiveMessageSizeSpecified)
{
// Only default MaxReceiveMessageSize if it was not configured
options._maxReceiveMessageSize = DefaultReceiveMaxMessageSize;
options._maxReceiveMessageSize = MethodOptions.DefaultReceiveMaxMessageSize;
}
if (options._compressionProviders == null || options._compressionProviders.Count == 0)
{
Expand All @@ -56,8 +52,12 @@ public GrpcServiceOptionsSetup(IOptions<GrpcServiceOptions> options)

public void Configure(GrpcServiceOptions<TService> options)
{
options.MaxReceiveMessageSize = _options.MaxReceiveMessageSize;
options.MaxSendMessageSize = _options.MaxSendMessageSize;
// Copy internal fields to avoid running logic in property setters.
options._maxReceiveMessageSize = _options._maxReceiveMessageSize;
options._maxReceiveMessageSizeSpecified = _options._maxReceiveMessageSizeSpecified;
options._maxSendMessageSize = _options._maxSendMessageSize;
options._maxSendMessageSizeSpecified = _options._maxSendMessageSizeSpecified;

options.EnableDetailedErrors = _options.EnableDetailedErrors;
options.ResponseCompressionAlgorithm = _options.ResponseCompressionAlgorithm;
options.ResponseCompressionLevel = _options.ResponseCompressionLevel;
Expand Down
13 changes: 8 additions & 5 deletions src/Grpc.AspNetCore.Server/Internal/ServerCallHandlerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,20 @@ internal sealed partial class ServerCallHandlerFactory<[DynamicallyAccessedMembe
{
private readonly ILoggerFactory _loggerFactory;
private readonly IGrpcServiceActivator<TService> _serviceActivator;
private readonly InterceptorActivators _interceptorActivators;
private readonly GrpcServiceOptions _globalOptions;
private readonly GrpcServiceOptions<TService> _serviceOptions;

public ServerCallHandlerFactory(
ILoggerFactory loggerFactory,
IOptions<GrpcServiceOptions> globalOptions,
IOptions<GrpcServiceOptions<TService>> serviceOptions,
IGrpcServiceActivator<TService> serviceActivator)
IGrpcServiceActivator<TService> serviceActivator,
InterceptorActivators interceptorActivators)
{
_loggerFactory = loggerFactory;
_serviceActivator = serviceActivator;
_interceptorActivators = interceptorActivators;
_serviceOptions = serviceOptions.Value;
_globalOptions = globalOptions.Value;
}
Expand All @@ -61,7 +64,7 @@ public UnaryServerCallHandler<TService, TRequest, TResponse> CreateUnary<TReques
where TResponse : class
{
var options = CreateMethodOptions();
var methodInvoker = new UnaryServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, options, _serviceActivator);
var methodInvoker = new UnaryServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, options, _serviceActivator, _interceptorActivators);

return new UnaryServerCallHandler<TService, TRequest, TResponse>(methodInvoker, _loggerFactory);
}
Expand All @@ -71,7 +74,7 @@ public ClientStreamingServerCallHandler<TService, TRequest, TResponse> CreateCli
where TResponse : class
{
var options = CreateMethodOptions();
var methodInvoker = new ClientStreamingServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, options, _serviceActivator);
var methodInvoker = new ClientStreamingServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, options, _serviceActivator, _interceptorActivators);

return new ClientStreamingServerCallHandler<TService, TRequest, TResponse>(methodInvoker, _loggerFactory);
}
Expand All @@ -81,7 +84,7 @@ public DuplexStreamingServerCallHandler<TService, TRequest, TResponse> CreateDup
where TResponse : class
{
var options = CreateMethodOptions();
var methodInvoker = new DuplexStreamingServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, options, _serviceActivator);
var methodInvoker = new DuplexStreamingServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, options, _serviceActivator, _interceptorActivators);

return new DuplexStreamingServerCallHandler<TService, TRequest, TResponse>(methodInvoker, _loggerFactory);
}
Expand All @@ -91,7 +94,7 @@ public ServerStreamingServerCallHandler<TService, TRequest, TResponse> CreateSer
where TResponse : class
{
var options = CreateMethodOptions();
var methodInvoker = new ServerStreamingServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, options, _serviceActivator);
var methodInvoker = new ServerStreamingServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, options, _serviceActivator, _interceptorActivators);

return new ServerStreamingServerCallHandler<TService, TRequest, TResponse>(methodInvoker, _loggerFactory);
}
Expand Down
3 changes: 1 addition & 2 deletions src/Grpc.Core.Api/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

#endregion

using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Grpc.Core,PublicKey=" +
Expand Down Expand Up @@ -48,4 +47,4 @@
"00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" +
"0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" +
"27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" +
"71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")]
"71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")]
9 changes: 5 additions & 4 deletions src/Shared/Server/ClientStreamingServerMethodInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

using System.Diagnostics.CodeAnalysis;
using Grpc.AspNetCore.Server;
using Grpc.AspNetCore.Server.Internal;
using Grpc.AspNetCore.Server.Model;
using Grpc.Core;
using Microsoft.AspNetCore.Http;
Expand All @@ -31,7 +30,7 @@ namespace Grpc.Shared.Server;
/// <typeparam name="TService">Service type for this method.</typeparam>
/// <typeparam name="TRequest">Request message type for this method.</typeparam>
/// <typeparam name="TResponse">Response message type for this method.</typeparam>
internal sealed class ClientStreamingServerMethodInvoker<[DynamicallyAccessedMembers(GrpcProtocolConstants.ServiceAccessibility)] TService, TRequest, TResponse> : ServerMethodInvokerBase<TService, TRequest, TResponse>
internal sealed class ClientStreamingServerMethodInvoker<[DynamicallyAccessedMembers(ServerDynamicAccessConstants.ServiceAccessibility)] TService, TRequest, TResponse> : ServerMethodInvokerBase<TService, TRequest, TResponse>
where TRequest : class
where TResponse : class
where TService : class
Expand All @@ -46,18 +45,20 @@ internal sealed class ClientStreamingServerMethodInvoker<[DynamicallyAccessedMem
/// <param name="method">The description of the gRPC method.</param>
/// <param name="options">The options used to execute the method.</param>
/// <param name="serviceActivator">The service activator used to create service instances.</param>
/// <param name="interceptorActivators">The interceptor activators used to create interceptor instances.</param>
public ClientStreamingServerMethodInvoker(
ClientStreamingServerMethod<TService, TRequest, TResponse> invoker,
Method<TRequest, TResponse> method,
MethodOptions options,
IGrpcServiceActivator<TService> serviceActivator)
IGrpcServiceActivator<TService> serviceActivator,
InterceptorActivators interceptorActivators)
: base(method, options, serviceActivator)
{
_invoker = invoker;

if (Options.HasInterceptors)
{
var interceptorPipeline = new InterceptorPipelineBuilder<TRequest, TResponse>(Options.Interceptors);
var interceptorPipeline = new InterceptorPipelineBuilder<TRequest, TResponse>(Options.Interceptors, interceptorActivators);
_pipelineInvoker = interceptorPipeline.ClientStreamingPipeline(ResolvedInterceptorInvoker);
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/Shared/Server/DuplexStreamingServerMethodInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

using System.Diagnostics.CodeAnalysis;
using Grpc.AspNetCore.Server;
using Grpc.AspNetCore.Server.Internal;
using Grpc.AspNetCore.Server.Model;
using Grpc.Core;
using Microsoft.AspNetCore.Http;
Expand All @@ -31,7 +30,7 @@ namespace Grpc.Shared.Server;
/// <typeparam name="TService">Service type for this method.</typeparam>
/// <typeparam name="TRequest">Request message type for this method.</typeparam>
/// <typeparam name="TResponse">Response message type for this method.</typeparam>
internal sealed class DuplexStreamingServerMethodInvoker<[DynamicallyAccessedMembers(GrpcProtocolConstants.ServiceAccessibility)] TService, TRequest, TResponse> : ServerMethodInvokerBase<TService, TRequest, TResponse>
internal sealed class DuplexStreamingServerMethodInvoker<[DynamicallyAccessedMembers(ServerDynamicAccessConstants.ServiceAccessibility)] TService, TRequest, TResponse> : ServerMethodInvokerBase<TService, TRequest, TResponse>
where TRequest : class
where TResponse : class
where TService : class
Expand All @@ -46,18 +45,20 @@ internal sealed class DuplexStreamingServerMethodInvoker<[DynamicallyAccessedMem
/// <param name="method">The description of the gRPC method.</param>
/// <param name="options">The options used to execute the method.</param>
/// <param name="serviceActivator">The service activator used to create service instances.</param>
/// <param name="interceptorActivators">The interceptor activators used to create interceptor instances.</param>
public DuplexStreamingServerMethodInvoker(
DuplexStreamingServerMethod<TService, TRequest, TResponse> invoker,
Method<TRequest, TResponse> method,
MethodOptions options,
IGrpcServiceActivator<TService> serviceActivator)
IGrpcServiceActivator<TService> serviceActivator,
InterceptorActivators interceptorActivators)
: base(method, options, serviceActivator)
{
_invoker = invoker;

if (Options.HasInterceptors)
{
var interceptorPipeline = new InterceptorPipelineBuilder<TRequest, TResponse>(Options.Interceptors);
var interceptorPipeline = new InterceptorPipelineBuilder<TRequest, TResponse>(Options.Interceptors, interceptorActivators);
_pipelineInvoker = interceptorPipeline.DuplexStreamingPipeline(ResolvedInterceptorInvoker);
}
}
Expand Down
Loading