private static RpcHttp ToRpcHttp(this HttpResponseContext httpResponseContext, PowerShellManager psHelper)
        {
            var rpcHttp = new RpcHttp
            {
                StatusCode = httpResponseContext.StatusCode.ToString("d")
            };

            if (httpResponseContext.Body != null)
            {
                rpcHttp.Body = httpResponseContext.Body.ToTypedData(psHelper);
            }

            // Add all the headers. ContentType is separated for convenience
            foreach (var item in httpResponseContext.Headers)
            {
                rpcHttp.Headers.Add(item.Key, item.Value);
            }

            // Allow the user to set content-type in the Headers
            if (!rpcHttp.Headers.ContainsKey("content-type"))
            {
                rpcHttp.Headers.Add("content-type", httpResponseContext.ContentType);
            }

            return(rpcHttp);
        }
Ejemplo n.º 2
0
        public static object ConvertFromHttpMessageToExpando(RpcHttp inputMessage)
        {
            if (inputMessage == null)
            {
                return(null);
            }

            dynamic expando = new ExpandoObject();

            expando.method     = inputMessage.Method;
            expando.query      = inputMessage.Query as IDictionary <string, string>;
            expando.statusCode = inputMessage.StatusCode;
            expando.headers    = inputMessage.Headers.ToDictionary(p => p.Key, p => (object)p.Value);
            expando.enableContentNegotiation = inputMessage.EnableContentNegotiation;

            expando.cookies = new List <Tuple <string, string, CookieOptions> >();
            foreach (RpcHttpCookie cookie in inputMessage.Cookies)
            {
                expando.cookies.Add(RpcHttpCookieConverter(cookie));
            }

            if (inputMessage.Body != null)
            {
                expando.body = inputMessage.Body.ToObject();
            }
            return(expando);
        }
Ejemplo n.º 3
0
        internal static TypedData ToRpcHttp(this HttpResponseData response)
        {
            var http = new RpcHttp()
            {
                StatusCode = ((int)response.StatusCode).ToString()
            };

            if (response.Body != null)
            {
                http.Body = response.Body.ToRpc();
            }
            else
            {
                // TODO: Is this correct? Passing a null body causes the entire
                //       response to become the body in functions. Need to investigate.
                http.Body = string.Empty.ToRpc();
            }

            if (response.Headers != null)
            {
                foreach (var pair in response.Headers)
                {
                    // maybe check or validate that the headers make sense?
                    http.Headers.Add(pair.Key.ToLowerInvariant(), pair.Value.ToString());
                }
            }
            var typedData = new TypedData
            {
                Http = http
            };

            return(typedData);
        }
        private static RpcHttp ToRpcHttp(this HttpResponseContext httpResponseContext)
        {
            var rpcHttp = new RpcHttp
            {
                StatusCode = httpResponseContext.StatusCode.ToString("d")
            };

            if (httpResponseContext.Body != null)
            {
                rpcHttp.Body = httpResponseContext.Body.ToTypedData();
            }

            rpcHttp.EnableContentNegotiation = httpResponseContext.EnableContentNegotiation;

            // Add all the headers. ContentType is separated for convenience
            if (httpResponseContext.Headers != null)
            {
                foreach (DictionaryEntry item in httpResponseContext.Headers)
                {
                    rpcHttp.Headers.Add(item.Key.ToString(), item.Value.ToString());
                }
            }

            // Allow the user to set content-type in the Headers
            if (!rpcHttp.Headers.ContainsKey(ContentTypeHeaderKey))
            {
                rpcHttp.Headers.Add(ContentTypeHeaderKey, DeriveContentType(httpResponseContext, rpcHttp));
            }

            return(rpcHttp);
        }
Ejemplo n.º 5
0
        private static void PopulateBody(HttpRequest request, RpcHttp http, Capabilities capabilities, ILogger logger)
        {
            object body = null;

            if ((MediaTypeHeaderValue.TryParse(request.ContentType, out MediaTypeHeaderValue mediaType) && IsMediaTypeOctetOrMultipart(mediaType)) || IsRawBodyBytesRequested(capabilities))
            {
                body = RequestBodyToBytes(request);
            }
        /// <summary>
        /// The body should be deserialized from JSON automatically only if the HTTP request:
        ///   - does not have Content-Type header; or
        ///   - does have Content-Type header, and it contains 'application/json'.
        /// Any other Content-Type is interpreted as an instruction to *not* deserialize the body.
        /// In these cases, we should pass the body to the function code as is, without any attempt to deserialize.
        /// </summary>
        private static bool ShouldConvertBodyFromJson(RpcHttp rpcHttp)
        {
            var contentType = GetContentType(rpcHttp);

            if (contentType == null)
            {
                return(true);
            }

            return(MediaTypeHeaderValue.TryParse(contentType, out var mediaTypeHeaderValue) &&
                   mediaTypeHeaderValue.MediaType.Equals(ApplicationJsonMediaType, StringComparison.OrdinalIgnoreCase));
        }
Ejemplo n.º 7
0
        private static async Task PopulateBodyAndRawBody(HttpRequest request, RpcHttp http, Capabilities capabilities, ILogger logger)
        {
            object body          = null;
            string rawBodyString = null;

            if (MediaTypeHeaderValue.TryParse(request.ContentType, out MediaTypeHeaderValue mediaType))
            {
                if (string.Equals(mediaType.MediaType, "application/json", StringComparison.OrdinalIgnoreCase))
                {
                    rawBodyString = await request.ReadAsStringAsync();

                    try
                    {
                        // REVIEW: We are json deserializing this to a JObject only to serialze
                        // it back to string below. Why?
                        body = JsonConvert.DeserializeObject(rawBodyString);
                    }
                    catch (JsonException)
                    {
                        body = rawBodyString;
                    }
                }
                else if (request.IsMediaTypeOctetOrMultipart())
                {
                    byte[] bytes = await request.GetRequestBodyAsBytesAsync();

                    body = bytes;
                    if (!IsRawBodyBytesRequested(capabilities))
                    {
                        rawBodyString = Encoding.UTF8.GetString(bytes);
                    }
                }
            }

            // default if content-tye not found or recognized
            if (body == null && rawBodyString == null)
            {
                body = rawBodyString = await request.ReadAsStringAsync();
            }

            http.Body = await body.ToRpc(logger, capabilities);

            if (IsRawBodyBytesRequested(capabilities))
            {
                byte[] bytes = await request.GetRequestBodyAsBytesAsync();

                http.RawBody = await bytes.ToRpc(logger, capabilities);
            }
            else
            {
                http.RawBody = await rawBodyString.ToRpc(logger, capabilities);
            }
        }
Ejemplo n.º 8
0
        private static async Task PopulateBody(HttpRequest request, RpcHttp http, Capabilities capabilities, ILogger logger)
        {
            object body = null;

            if (request.IsMediaTypeOctetOrMultipart() || IsRawBodyBytesRequested(capabilities))
            {
                body = await request.GetRequestBodyAsBytesAsync();
            }
            else
            {
                body = await request.ReadAsStringAsync();
            }
            http.Body = await body.ToRpc(logger, capabilities);
        }
        private static HttpRequestContext ToHttpRequestContext(this RpcHttp rpcHttp)
        {
            var httpRequestContext = new HttpRequestContext
            {
                Method = rpcHttp.Method,
                Url    = rpcHttp.Url
            };

            if (rpcHttp.Headers != null)
            {
                foreach (var pair in rpcHttp.Headers)
                {
                    httpRequestContext.Headers.TryAdd(pair.Key, pair.Value);
                }
            }

            if (rpcHttp.Params != null)
            {
                foreach (var pair in rpcHttp.Params)
                {
                    httpRequestContext.Params.TryAdd(pair.Key, pair.Value);
                }
            }

            if (rpcHttp.Query != null)
            {
                foreach (var pair in rpcHttp.Query)
                {
                    httpRequestContext.Query.TryAdd(pair.Key, pair.Value);
                }
            }

            if (rpcHttp.Body != null)
            {
                httpRequestContext.Body = rpcHttp.Body.ToObject();
            }

            if (rpcHttp.RawBody != null)
            {
                object rawBody = rpcHttp.RawBody.DataCase == TypedData.DataOneofCase.String
                    ? rpcHttp.RawBody.String
                    : rpcHttp.RawBody.ToObject();

                httpRequestContext.RawBody = rawBody;
            }

            return(httpRequestContext);
        }
        private static string GetContentType(RpcHttp rpcHttp)
        {
            if (rpcHttp.Headers == null)
            {
                return(null);
            }

            foreach (var(key, value) in rpcHttp.Headers)
            {
                if (key.Equals(ContentTypeHeaderKey, StringComparison.OrdinalIgnoreCase))
                {
                    return(value);
                }
            }

            return(null);
        }
        private static void PopulateBodyAndRawBody(HttpRequest request, RpcHttp http, Capabilities capabilities, ILogger logger)
        {
            object body          = null;
            string rawBodyString = null;

            byte[] bytes = request.GetRequestBodyAsBytes();

            if (MediaTypeHeaderValue.TryParse(request.ContentType, out MediaTypeHeaderValue mediaType))
            {
                if (string.Equals(mediaType.MediaType, "application/json", StringComparison.OrdinalIgnoreCase))
                {
                    rawBodyString = request.ReadAsStringAsync().GetAwaiter().GetResult();
                    try
                    {
                        body = JsonConvert.DeserializeObject(rawBodyString);
                    }
                    catch (JsonException)
                    {
                        body = rawBodyString;
                    }
                }
                else if (request.IsMediaTypeOctetOrMultipart())
                {
                    body = bytes;
                    if (!IsRawBodyBytesRequested(capabilities))
                    {
                        rawBodyString = Encoding.UTF8.GetString(bytes);
                    }
                }
            }
            // default if content-tye not found or recognized
            if (body == null && rawBodyString == null)
            {
                body = rawBodyString = request.ReadAsStringAsync().GetAwaiter().GetResult();
            }

            http.Body = body.ToRpc(logger, capabilities);
            if (IsRawBodyBytesRequested(capabilities))
            {
                http.RawBody = bytes.ToRpc(logger, capabilities);
            }
            else
            {
                http.RawBody = rawBodyString.ToRpc(logger, capabilities);
            }
        }
Ejemplo n.º 12
0
        static HttpRequestContext ToHttpRequestContext(this RpcHttp rpcHttp)
        {
            var httpRequestContext = new HttpRequestContext
            {
                Method = rpcHttp.Method,
                Url    = rpcHttp.Url
            };

            if (rpcHttp.Headers != null)
            {
                foreach (var pair in rpcHttp.Headers)
                {
                    httpRequestContext.Headers.TryAdd(pair.Key, pair.Value);
                }
            }

            if (rpcHttp.Params != null)
            {
                foreach (var pair in rpcHttp.Params)
                {
                    httpRequestContext.Params.TryAdd(pair.Key, pair.Value);
                }
            }

            if (rpcHttp.Query != null)
            {
                foreach (var pair in rpcHttp.Query)
                {
                    httpRequestContext.Query.TryAdd(pair.Key, pair.Value);
                }
            }

            if (rpcHttp.Body != null)
            {
                httpRequestContext.Body = rpcHttp.Body.ToObject();
            }

            if (rpcHttp.RawBody != null)
            {
                httpRequestContext.RawBody = rpcHttp.RawBody.ToObject();
            }

            return(httpRequestContext);
        }
Ejemplo n.º 13
0
        internal void InvocationRequestHandler(StreamingMessage request)
        {
            StreamingMessage response = NewStreamingMessageTemplate(
                request.RequestId,
                StreamingMessage.ContentOneofCase.InvocationResponse,
                out StatusResult status);

            response.InvocationResponse.InvocationId = request.InvocationRequest.InvocationId;
            RpcHttp rpcHttp = new RpcHttp()
            {
                StatusCode = "200"
            };
            TypedData typedData = new TypedData();

            typedData.Http = rpcHttp;
            response.InvocationResponse.ReturnValue = typedData;

            _blockingCollectionQueue.Add(response);
        }
        public GrpcHttpRequestData(RpcHttp httpData, FunctionContext functionContext)
            : base(functionContext)
        {
            _httpData = httpData ?? throw new ArgumentNullException(nameof(httpData));
            _cookies  = new Lazy <IReadOnlyCollection <IHttpCookie> >(() =>
            {
                if (Headers is null)
                {
                    return(Array.Empty <IHttpCookie>());
                }

                var cookieString = Headers.FirstOrDefault(item => item.Key.Equals("Cookie", StringComparison.OrdinalIgnoreCase)).Value;

                if (cookieString != null && cookieString.Any())
                {
                    return(ToHttpCookies(cookieString.First()));
                }

                return(Array.Empty <IHttpCookie>());
            });
        }
Ejemplo n.º 15
0
        public static object ConvertFromHttpMessageToExpando(RpcHttp inputMessage)
        {
            if (inputMessage == null)
            {
                return(null);
            }

            dynamic expando = new ExpandoObject();

            expando.method     = inputMessage.Method;
            expando.query      = inputMessage.Query as IDictionary <string, string>;
            expando.statusCode = inputMessage.StatusCode;
            expando.headers    = inputMessage.Headers.ToDictionary(p => p.Key, p => (object)p.Value);
            expando.enableContentNegotiation = inputMessage.EnableContentNegotiation;

            if (inputMessage.Body != null)
            {
                expando.body = inputMessage.Body.ToObject();
            }
            return(expando);
        }
Ejemplo n.º 16
0
        internal static async Task <TypedData> ToRpcHttp(this HttpRequest request, ILogger logger, Capabilities capabilities)
        {
            var http = new RpcHttp()
            {
                Url     = $"{(request.IsHttps ? "https" : "http")}://{request.Host}{request.Path}{request.QueryString}",
                Method  = request.Method.ToString(),
                RawBody = null
            };
            var typedData = new TypedData
            {
                Http = http
            };

            foreach (var pair in request.Query)
            {
                var value = pair.Value.ToString();
                if (!string.IsNullOrEmpty(value))
                {
                    http.Query.Add(pair.Key, value);
                }
            }

            foreach (var pair in request.Headers)
            {
                if (ShouldIgnoreEmptyHeaderValues(capabilities) && string.IsNullOrEmpty(pair.Value.ToString()))
                {
                    continue;
                }

                http.Headers.Add(pair.Key.ToLowerInvariant(), pair.Value.ToString());
            }

            if (request.HttpContext.Items.TryGetValue(HttpExtensionConstants.AzureWebJobsHttpRouteDataKey, out object routeData))
            {
                Dictionary <string, object> parameters = (Dictionary <string, object>)routeData;
                foreach (var pair in parameters)
                {
                    if (pair.Value != null)
                    {
                        http.Params.Add(pair.Key, pair.Value.ToString());
                    }
                }
            }

            // parse ClaimsPrincipal if exists
            if (request.HttpContext?.User?.Identities != null)
            {
                logger.LogTrace("HttpContext has ClaimsPrincipal; parsing to gRPC.");
                foreach (var id in request.HttpContext.User.Identities)
                {
                    var rpcClaimsIdentity = new RpcClaimsIdentity();
                    if (id.AuthenticationType != null)
                    {
                        rpcClaimsIdentity.AuthenticationType = new NullableString {
                            Value = id.AuthenticationType
                        };
                    }

                    if (id.NameClaimType != null)
                    {
                        rpcClaimsIdentity.NameClaimType = new NullableString {
                            Value = id.NameClaimType
                        };
                    }

                    if (id.RoleClaimType != null)
                    {
                        rpcClaimsIdentity.RoleClaimType = new NullableString {
                            Value = id.RoleClaimType
                        };
                    }

                    foreach (var claim in id.Claims)
                    {
                        if (claim.Type != null && claim.Value != null)
                        {
                            rpcClaimsIdentity.Claims.Add(new RpcClaim {
                                Value = claim.Value, Type = claim.Type
                            });
                        }
                    }

                    http.Identities.Add(rpcClaimsIdentity);
                }
            }

            // parse request body as content-type
            if (request.Body != null && request.ContentLength > 0)
            {
                if (IsBodyOnlySupported(capabilities))
                {
                    await PopulateBody(request, http, capabilities, logger);
                }
                else
                {
                    await PopulateBodyAndRawBody(request, http, capabilities, logger);
                }
            }

            return(typedData);
        }
        public static TypedData ToRpc(this object value)
        {
            TypedData typedData = new TypedData();

            if (value == null)
            {
                return(typedData);
            }

            if (value is byte[] arr)
            {
                typedData.Bytes = ByteString.CopyFrom(arr);
            }
            else if (value is JObject jobj)
            {
                typedData.Json = jobj.ToString();
            }
            else if (value is string str)
            {
                typedData.String = str;
            }
            else if (value is HttpRequest request)
            {
                var http = new RpcHttp()
                {
                    Url    = $"{(request.IsHttps ? "https" : "http")}://{request.Host.ToString()}{request.Path.ToString()}{request.QueryString.ToString()}", // [http|https]://{url}{path}{query}
                    Method = request.Method.ToString()
                };
                typedData.Http = http;

                http.RawBody = null;

                foreach (var pair in request.Query)
                {
                    http.Query.Add(pair.Key, pair.Value.ToString());
                }

                foreach (var pair in request.Headers)
                {
                    http.Headers.Add(pair.Key.ToLowerInvariant(), pair.Value.ToString());
                }

                if (request.HttpContext.Items.TryGetValue(HttpExtensionConstants.AzureWebJobsHttpRouteDataKey, out object routeData))
                {
                    Dictionary <string, object> parameters = (Dictionary <string, object>)routeData;
                    foreach (var pair in parameters)
                    {
                        http.Params.Add(pair.Key, pair.Value.ToString());
                    }
                }

                if (request.Body != null && request.ContentLength > 0)
                {
                    object body    = null;
                    string rawBody = null;

                    switch (request.ContentType)
                    {
                    case "application/json":
                        var jsonReader = new StreamReader(request.Body, Encoding.UTF8);
                        rawBody = jsonReader.ReadToEnd();
                        body    = JsonConvert.DeserializeObject(rawBody);
                        break;

                    case "application/octet-stream":
                    case string contentType when contentType.IndexOf("multipart/", StringComparison.OrdinalIgnoreCase) >= 0:
                        var length = Convert.ToInt32(request.ContentLength);

                        var bytes = new byte[length];
                        request.Body.Read(bytes, 0, length);
                        body    = bytes;
                        rawBody = Encoding.UTF8.GetString(bytes);
                        break;

                    default:
                        var reader = new StreamReader(request.Body, Encoding.UTF8);
                        body = rawBody = reader.ReadToEnd();
                        break;
                    }
                    request.Body.Position = 0;

                    http.Body    = body.ToRpc();
                    http.RawBody = rawBody.ToRpc();
                }
            }
            else
            {
                // attempt POCO / array of pocos
                try
                {
                    typedData.Json = JsonConvert.SerializeObject(value);
                }
                catch
                {
                    typedData.String = value.ToString();
                }
            }
            return(typedData);
        }
        public static TypedData ToRpc(this object value, ILogger logger)
        {
            TypedData typedData = new TypedData();

            if (value == null)
            {
                return(typedData);
            }

            if (value is byte[] arr)
            {
                typedData.Bytes = ByteString.CopyFrom(arr);
            }
            else if (value is JObject jobj)
            {
                typedData.Json = jobj.ToString();
            }
            else if (value is string str)
            {
                typedData.String = str;
            }
            else if (value is HttpRequest request)
            {
                var http = new RpcHttp()
                {
                    Url    = $"{(request.IsHttps ? "https" : "http")}://{request.Host.ToString()}{request.Path.ToString()}{request.QueryString.ToString()}", // [http|https]://{url}{path}{query}
                    Method = request.Method.ToString()
                };
                typedData.Http = http;

                http.RawBody = null;
                foreach (var pair in request.Query)
                {
                    if (!string.IsNullOrEmpty(pair.Value.ToString()))
                    {
                        http.Query.Add(pair.Key, pair.Value.ToString());
                    }
                }

                foreach (var pair in request.Headers)
                {
                    http.Headers.Add(pair.Key.ToLowerInvariant(), pair.Value.ToString());
                }

                if (request.HttpContext.Items.TryGetValue(HttpExtensionConstants.AzureWebJobsHttpRouteDataKey, out object routeData))
                {
                    Dictionary <string, object> parameters = (Dictionary <string, object>)routeData;
                    foreach (var pair in parameters)
                    {
                        if (pair.Value != null)
                        {
                            http.Params.Add(pair.Key, pair.Value.ToString());
                        }
                    }
                }

                // parse ClaimsPrincipal if exists
                if (request.HttpContext?.User?.Identities != null)
                {
                    logger.LogDebug("HttpContext has ClaimsPrincipal; parsing to gRPC.");
                    foreach (var id in request.HttpContext.User.Identities)
                    {
                        var rpcClaimsIdentity = new RpcClaimsIdentity();
                        if (id.AuthenticationType != null)
                        {
                            rpcClaimsIdentity.AuthenticationType = new NullableString {
                                Value = id.AuthenticationType
                            };
                        }

                        if (id.NameClaimType != null)
                        {
                            rpcClaimsIdentity.NameClaimType = new NullableString {
                                Value = id.NameClaimType
                            };
                        }

                        if (id.RoleClaimType != null)
                        {
                            rpcClaimsIdentity.RoleClaimType = new NullableString {
                                Value = id.RoleClaimType
                            };
                        }

                        foreach (var claim in id.Claims)
                        {
                            if (claim.Type != null && claim.Value != null)
                            {
                                rpcClaimsIdentity.Claims.Add(new RpcClaim {
                                    Value = claim.Value, Type = claim.Type
                                });
                            }
                        }

                        http.Identities.Add(rpcClaimsIdentity);
                    }
                }

                // parse request body as content-type
                if (request.Body != null && request.ContentLength > 0)
                {
                    object body    = null;
                    string rawBody = null;

                    MediaTypeHeaderValue mediaType = null;
                    if (MediaTypeHeaderValue.TryParse(request.ContentType, out mediaType))
                    {
                        if (string.Equals(mediaType.MediaType, "application/json", StringComparison.OrdinalIgnoreCase))
                        {
                            var jsonReader = new StreamReader(request.Body, Encoding.UTF8);
                            rawBody = jsonReader.ReadToEnd();
                            try
                            {
                                body = JsonConvert.DeserializeObject(rawBody);
                            }
                            catch (JsonException)
                            {
                                body = rawBody;
                            }
                        }
                        else if (string.Equals(mediaType.MediaType, "application/octet-stream", StringComparison.OrdinalIgnoreCase) ||
                                 mediaType.MediaType.IndexOf("multipart/", StringComparison.OrdinalIgnoreCase) >= 0)
                        {
                            var length = Convert.ToInt32(request.ContentLength);
                            var bytes  = new byte[length];
                            request.Body.Read(bytes, 0, length);
                            body    = bytes;
                            rawBody = Encoding.UTF8.GetString(bytes);
                        }
                    }
                    // default if content-tye not found or recognized
                    if (body == null && rawBody == null)
                    {
                        var reader = new StreamReader(request.Body, Encoding.UTF8);
                        body = rawBody = reader.ReadToEnd();
                    }

                    request.Body.Position = 0;
                    http.Body             = body.ToRpc(logger);
                    http.RawBody          = rawBody.ToRpc(logger);
                }
            }
            else
            {
                // attempt POCO / array of pocos
                try
                {
                    typedData.Json = JsonConvert.SerializeObject(value);
                }
                catch
                {
                    typedData.String = value.ToString();
                }
            }
            return(typedData);
        }
 private static string DeriveContentType(HttpResponseContext httpResponseContext, RpcHttp rpcHttp)
 {
     return(httpResponseContext.ContentType ??
            (rpcHttp.Body.DataCase == TypedData.DataOneofCase.Json
                             ? "application/json"
                             : "text/plain"));
 }
Ejemplo n.º 20
0
 public GrpcHttpRequestData(RpcHttp httpData, FunctionContext functionContext)
     : base(functionContext)
 {
     _httpData = httpData ?? throw new ArgumentNullException(nameof(httpData));
 }
 private static string DeriveContentType(HttpResponseContext httpResponseContext, RpcHttp rpcHttp)
 {
     return(httpResponseContext.ContentType ??
            (rpcHttp.Body.DataCase == TypedData.DataOneofCase.Json
                             ? ApplicationJsonMediaType
                             : TextPlainMediaType));
 }
Ejemplo n.º 22
0
 public GrpcHttpRequestData(RpcHttp httpData)
 {
     this.httpData = httpData;
 }