private ICompressionProvider?ResolveCompressionProvider() { if (_serverCallContext.ResponseGrpcEncoding != null && GrpcProtocolHelpers.CanWriteCompressed(_serverCallContext.WriteOptions) && _serverCallContext.Options.CompressionProviders.TryGetValue(_serverCallContext.ResponseGrpcEncoding, out var compressionProvider)) { return(compressionProvider); } return(null); }
private ICompressionProvider?ResolveCompressionProvider() { Debug.Assert( _serverCallContext.ResponseGrpcEncoding != null, "Response encoding should have been calculated at this point."); var canCompress = GrpcProtocolHelpers.CanWriteCompressed(_serverCallContext.WriteOptions) && !string.Equals(_serverCallContext.ResponseGrpcEncoding, GrpcProtocolConstants.IdentityGrpcEncoding, StringComparison.Ordinal); if (canCompress) { if (_serverCallContext.Options.CompressionProviders.TryGetValue(_serverCallContext.ResponseGrpcEncoding, out var compressionProvider)) { return(compressionProvider); } } return(null); }
public static async Task WriteMessageAsync <TResponse>(this PipeWriter pipeWriter, TResponse response, HttpContextServerCallContext serverCallContext, Action <TResponse, SerializationContext> serializer, bool canFlush) where TResponse : class { var logger = serverCallContext.Logger; try { GrpcServerLog.SendingMessage(logger); var serializationContext = serverCallContext.SerializationContext; serializer(response, serializationContext); var responsePayload = serializationContext.Payload; serializationContext.Payload = null; if (responsePayload == null) { throw new InvalidOperationException("Serialization did not return a payload."); } GrpcServerLog.SerializedMessage(serverCallContext.Logger, typeof(TResponse), responsePayload.Length); // Must call StartAsync before the first pipeWriter.GetSpan() in WriteHeader var httpResponse = serverCallContext.HttpContext.Response; if (!httpResponse.HasStarted) { await httpResponse.StartAsync(); } var canCompress = GrpcProtocolHelpers.CanWriteCompressed(serverCallContext.WriteOptions) && !string.Equals(serverCallContext.ResponseGrpcEncoding, GrpcProtocolConstants.IdentityGrpcEncoding, StringComparison.Ordinal); var isCompressed = false; if (canCompress) { Debug.Assert( serverCallContext.ServiceOptions.ResolvedCompressionProviders != null, "Compression providers should have been resolved for service."); if (TryCompressMessage( serverCallContext.Logger, serverCallContext.ResponseGrpcEncoding !, serverCallContext.ServiceOptions.ResponseCompressionLevel, serverCallContext.ServiceOptions.ResolvedCompressionProviders, responsePayload, out var result)) { responsePayload = result; isCompressed = true; } } if (responsePayload.Length > serverCallContext.ServiceOptions.MaxSendMessageSize) { throw new RpcException(SendingMessageExceedsLimitStatus); } WriteHeader(pipeWriter, responsePayload.Length, isCompressed); pipeWriter.Write(responsePayload); // Flush messages unless WriteOptions.Flags has BufferHint set var flush = canFlush && ((serverCallContext.WriteOptions?.Flags ?? default) & WriteFlags.BufferHint) != WriteFlags.BufferHint; if (flush) { serverCallContext.HasBufferedMessage = false; await pipeWriter.FlushAsync(); } else { // Set flag so buffered message will be written at the end serverCallContext.HasBufferedMessage = true; } GrpcServerLog.MessageSent(serverCallContext.Logger); GrpcEventSource.Log.MessageSent(); } catch (Exception ex) { GrpcServerLog.ErrorSendingMessage(logger, ex); throw; } }