Ejemplo n.º 1
0
    public static async ValueTask SendMessage <TResponse>(JsonTranscodingServerCallContext serverCallContext, JsonSerializerOptions serializerOptions, TResponse message, CancellationToken cancellationToken) where TResponse : class
    {
        var response = serverCallContext.HttpContext.Response;

        try
        {
            GrpcServerLog.SendingMessage(serverCallContext.Logger);

            object responseBody;
            Type   responseType;

            if (serverCallContext.DescriptorInfo.ResponseBodyDescriptor != null)
            {
                // TODO: Support recursive response body?
                responseBody = serverCallContext.DescriptorInfo.ResponseBodyDescriptor.Accessor.GetValue((IMessage)message);
                responseType = JsonConverterHelper.GetFieldType(serverCallContext.DescriptorInfo.ResponseBodyDescriptor);
            }
            else
            {
                responseBody = message;
                responseType = message.GetType();
            }

            await JsonRequestHelpers.WriteResponseMessage(response, serverCallContext.RequestEncoding, responseBody, serializerOptions, cancellationToken);

            GrpcServerLog.SerializedMessage(serverCallContext.Logger, responseType);
            GrpcServerLog.MessageSent(serverCallContext.Logger);
        }
        catch (Exception ex)
        {
            GrpcServerLog.ErrorSendingMessage(serverCallContext.Logger, ex);
            throw;
        }
    }
Ejemplo n.º 2
0
    protected override async Task HandleCallAsyncCore(HttpContext httpContext, JsonTranscodingServerCallContext serverCallContext)
    {
        var request = await JsonRequestHelpers.ReadMessage <TRequest>(serverCallContext, SerializerOptions);

        var response = await _invoker.Invoke(httpContext, serverCallContext, request);

        if (serverCallContext.Status.StatusCode != StatusCode.OK)
        {
            throw new RpcException(serverCallContext.Status);
        }

        if (response == null)
        {
            // This is consistent with Grpc.Core when a null value is returned
            throw new RpcException(new Status(StatusCode.Cancelled, "No message returned from method."));
        }

        if (response is HttpBody httpBody)
        {
            serverCallContext.EnsureResponseHeaders(httpBody.ContentType);
            await serverCallContext.HttpContext.Response.Body.WriteAsync(httpBody.Data.Memory);
        }
        else
        {
            serverCallContext.EnsureResponseHeaders();
            await JsonRequestHelpers.SendMessage(serverCallContext, SerializerOptions, response, CancellationToken.None);
        }
    }
    internal async Task ProcessHandlerErrorAsync(Exception ex, string method, bool isStreaming, JsonSerializerOptions options)
    {
        Status status;

        if (ex is RpcException rpcException)
        {
            // RpcException is thrown by client code to modify the status returned from the server.
            // Log the status and detail. Don't log the exception to reduce log verbosity.
            GrpcServerLog.RpcConnectionError(Logger, rpcException.StatusCode, rpcException.Status.Detail);

            status = rpcException.Status;
        }
        else
        {
            GrpcServerLog.ErrorExecutingServiceMethod(Logger, method, ex);

            var message = ErrorMessageHelper.BuildErrorMessage("Exception was thrown by handler.", ex, Options.EnableDetailedErrors);

            // Note that the exception given to status won't be returned to the client.
            // It is still useful to set in case an interceptor accesses the status on the server.
            status = new Status(StatusCode.Unknown, message, ex);
        }

        await JsonRequestHelpers.SendErrorResponse(HttpContext.Response, RequestEncoding, status, options);

        if (isStreaming)
        {
            await HttpContext.Response.Body.WriteAsync(GrpcProtocolConstants.StreamingDelimiter);
        }
    }
    public void Initialize()
    {
        IsJsonRequestContent = JsonRequestHelpers.HasJsonContentType(HttpContext.Request, out var charset);
        RequestEncoding      = JsonRequestHelpers.GetEncodingFromCharset(charset) ?? Encoding.UTF8;

        // HttpContext.Items is publically exposed as ServerCallContext.UserState.
        // Because this is a custom ServerCallContext, HttpContext must be added to UserState so GetHttpContext() continues to work.
        // https://github.com/grpc/grpc-dotnet/blob/7ef184f3c4cd62fbc3cde55e4bb3e16b58258ca1/src/Grpc.AspNetCore.Server/ServerCallContextExtensions.cs#L53-L61
        HttpContext.Items["__HttpContext"] = HttpContext;
    }
Ejemplo n.º 5
0
        protected override async Task HandleCallAsyncCore(HttpContext httpContext, HttpApiServerCallContext serverCallContext)
        {
            // Decode request
            var request = await JsonRequestHelpers.ReadMessage <TRequest>(serverCallContext, SerializerOptions);

            var streamWriter = new HttpContextStreamWriter <TResponse>(serverCallContext, SerializerOptions);

            try
            {
                await _invoker.Invoke(httpContext, serverCallContext, request, streamWriter);
            }
            finally
            {
                streamWriter.Complete();
            }
        }
Ejemplo n.º 6
0
    public async Task Request_SupportedCharset_Success(string?charset)
    {
        // Arrange
        Task <HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
        {
            return(Task.FromResult(new HelloReply {
                Message = $"Hello {request.Name}!"
            }));
        }

        var method = Fixture.DynamicGrpc.AddUnaryMethod <HelloRequest, HelloReply>(
            UnaryMethod,
            Greeter.Descriptor.FindMethodByName("SayHelloPost"));

        var encoding    = JsonRequestHelpers.GetEncodingFromCharset(charset);
        var contentType = charset != null
            ? "application/json; charset=" + charset
            : "application/json";

        var client = new HttpClient(Fixture.Handler)
        {
            BaseAddress = new Uri("http://localhost")
        };

        var requestMessage = new HelloRequest {
            Name = "test"
        };
        var content = new ByteArrayContent((encoding ?? Encoding.UTF8).GetBytes(requestMessage.ToString()));

        content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);

        // Act
        var response = await client.PostAsync("/v1/greeter", content).DefaultTimeout();

        var responseText = await response.Content.ReadAsStringAsync();

        using var result = JsonDocument.Parse(responseText);

        // Assert
        Assert.Equal("application/json", response.Content.Headers.ContentType !.MediaType);
        Assert.Equal(encoding?.WebName ?? "utf-8", response.Content.Headers.ContentType !.CharSet);
        Assert.Equal("Hello test!", result.RootElement.GetProperty("message").GetString());
    }
Ejemplo n.º 7
0
        protected override async Task HandleCallAsyncCore(HttpContext httpContext, HttpApiServerCallContext serverCallContext)
        {
            var request = await JsonRequestHelpers.ReadMessage <TRequest>(serverCallContext, SerializerOptions);

            var response = await _invoker.Invoke(httpContext, serverCallContext, request);

            if (serverCallContext.Status.StatusCode != StatusCode.OK)
            {
                throw new RpcException(serverCallContext.Status);
            }

            if (response == null)
            {
                // This is consistent with Grpc.Core when a null value is returned
                throw new RpcException(new Status(StatusCode.Cancelled, "No message returned from method."));
            }

            httpContext.Response.StatusCode  = StatusCodes.Status200OK;
            httpContext.Response.ContentType = MediaType.ReplaceEncoding("application/json", serverCallContext.RequestEncoding);

            await JsonRequestHelpers.SendMessage(serverCallContext, SerializerOptions, response);
        }