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); }
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); }
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); }
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)); }
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); } }
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); } }
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); }
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>()); }); }
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); }
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")); }
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)); }
public GrpcHttpRequestData(RpcHttp httpData) { this.httpData = httpData; }