Exemplo n.º 1
0
        private static bool CanBindQueryStringVariable(HttpApiServerCallContext serverCallContext, string variable)
        {
            if (serverCallContext.DescriptorInfo.BodyDescriptor != null)
            {
                if (serverCallContext.DescriptorInfo.BodyFieldDescriptors == null || serverCallContext.DescriptorInfo.BodyFieldDescriptors.Count == 0)
                {
                    return(false);
                }

                if (variable == serverCallContext.DescriptorInfo.BodyFieldDescriptorsPath)
                {
                    return(false);
                }

                if (variable.StartsWith(serverCallContext.DescriptorInfo.BodyFieldDescriptorsPath !, StringComparison.Ordinal))
                {
                    return(false);
                }
            }

            if (serverCallContext.DescriptorInfo.RouteParameterDescriptors.ContainsKey(variable))
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 2
0
        public static async Task SendMessage <TResponse>(HttpApiServerCallContext serverCallContext, JsonSerializerOptions serializerOptions, TResponse message) 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);

                GrpcServerLog.SerializedMessage(serverCallContext.Logger, responseType);
                GrpcServerLog.MessageSent(serverCallContext.Logger);
            }
            catch (Exception ex)
            {
                GrpcServerLog.ErrorSendingMessage(serverCallContext.Logger, ex);
                throw;
            }
        }
Exemplo n.º 3
0
 private static List <FieldDescriptor>?GetPathDescriptors(HttpApiServerCallContext serverCallContext, IMessage requestMessage, string path)
 {
     return(serverCallContext.DescriptorInfo.PathDescriptorsCache.GetOrAdd(path, p =>
     {
         ServiceDescriptorHelpers.TryResolveDescriptors(requestMessage.Descriptor, p, out var pathDescriptors);
         return pathDescriptors;
     }));
 }
Exemplo n.º 4
0
        public static async Task <TRequest> ReadMessage <TRequest>(HttpApiServerCallContext serverCallContext, JsonSerializerOptions serializerOptions) where TRequest : class
        {
            try
            {
                GrpcServerLog.ReadingMessage(serverCallContext.Logger);

                IMessage requestMessage;
                if (serverCallContext.DescriptorInfo.BodyDescriptor != null)
                {
                    if (!serverCallContext.IsJsonRequestContent)
                    {
                        GrpcServerLog.UnsupportedRequestContentType(serverCallContext.Logger, serverCallContext.HttpContext.Request.ContentType);
                        throw new RpcException(new Status(StatusCode.InvalidArgument, "Request content-type of application/json is required."));
                    }

                    var(stream, usesTranscodingStream) = GetStream(serverCallContext.HttpContext.Request.Body, serverCallContext.RequestEncoding);

                    try
                    {
                        if (serverCallContext.DescriptorInfo.BodyDescriptorRepeated)
                        {
                            requestMessage = (IMessage)Activator.CreateInstance <TRequest>();

                            // TODO: JsonSerializer currently doesn't support deserializing values onto an existing object or collection.
                            // Either update this to use new functionality in JsonSerializer or improve work-around perf.
                            var type     = JsonConverterHelper.GetFieldType(serverCallContext.DescriptorInfo.BodyFieldDescriptors !.Last());
                            var listType = typeof(List <>).MakeGenericType(type);

                            GrpcServerLog.DeserializingMessage(serverCallContext.Logger, listType);
                            var repeatedContent = (IList)(await JsonSerializer.DeserializeAsync(stream, listType, serializerOptions)) !;

                            ServiceDescriptorHelpers.RecursiveSetValue(requestMessage, serverCallContext.DescriptorInfo.BodyFieldDescriptors !, repeatedContent);
                        }
                        else
                        {
                            IMessage bodyContent;

                            try
                            {
                                GrpcServerLog.DeserializingMessage(serverCallContext.Logger, serverCallContext.DescriptorInfo.BodyDescriptor.ClrType);
                                bodyContent = (IMessage)(await JsonSerializer.DeserializeAsync(stream, serverCallContext.DescriptorInfo.BodyDescriptor.ClrType, serializerOptions)) !;
                            }
                            catch (JsonException)
                            {
                                throw new RpcException(new Status(StatusCode.InvalidArgument, "Request JSON payload is not correctly formatted."));
                            }
                            catch (Exception exception)
                            {
                                throw new RpcException(new Status(StatusCode.InvalidArgument, exception.Message));
                            }

                            if (serverCallContext.DescriptorInfo.BodyFieldDescriptors != null)
                            {
                                requestMessage = (IMessage)Activator.CreateInstance <TRequest>();
                                ServiceDescriptorHelpers.RecursiveSetValue(requestMessage, serverCallContext.DescriptorInfo.BodyFieldDescriptors, bodyContent !); // TODO - check nullability
                            }
                            else
                            {
                                requestMessage = bodyContent;
                            }
                        }
                    }
                    finally
                    {
                        if (usesTranscodingStream)
                        {
                            await stream.DisposeAsync();
                        }
                    }
                }
                else
                {
                    requestMessage = (IMessage)Activator.CreateInstance <TRequest>();
                }

                foreach (var parameterDescriptor in serverCallContext.DescriptorInfo.RouteParameterDescriptors)
                {
                    var routeValue = serverCallContext.HttpContext.Request.RouteValues[parameterDescriptor.Key];
                    if (routeValue != null)
                    {
                        ServiceDescriptorHelpers.RecursiveSetValue(requestMessage, parameterDescriptor.Value, routeValue);
                    }
                }

                foreach (var item in serverCallContext.HttpContext.Request.Query)
                {
                    if (CanBindQueryStringVariable(serverCallContext, item.Key))
                    {
                        var pathDescriptors = GetPathDescriptors(serverCallContext, requestMessage, item.Key);

                        if (pathDescriptors != null)
                        {
                            object value = item.Value.Count == 1 ? (object)item.Value[0] : item.Value;
                            ServiceDescriptorHelpers.RecursiveSetValue(requestMessage, pathDescriptors, value);
                        }
                    }
                }

                GrpcServerLog.ReceivedMessage(serverCallContext.Logger);
                return((TRequest)requestMessage);
            }
            catch (Exception ex)
            {
                GrpcServerLog.ErrorReadingMessage(serverCallContext.Logger, ex);
                throw;
            }
        }
Exemplo n.º 5
0
 public HttpContextStreamWriter(HttpApiServerCallContext context, JsonSerializerOptions serializerOptions)
 {
     _context           = context;
     _serializerOptions = serializerOptions;
     _writeLock         = new object();
 }