public static TypedData ToRpc(this object value, ILogger logger, Capabilities capabilities) { 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 rawBodyString = null; byte[] bytes = RequestBodyToBytes(request); 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); rawBodyString = jsonReader.ReadToEnd(); try { body = JsonConvert.DeserializeObject(rawBodyString); } catch (JsonException) { body = rawBodyString; } } else if (string.Equals(mediaType.MediaType, "application/octet-stream", StringComparison.OrdinalIgnoreCase) || mediaType.MediaType.IndexOf("multipart/", StringComparison.OrdinalIgnoreCase) >= 0) { body = bytes; if (!IsRawBodyBytesRequested(capabilities)) { rawBodyString = Encoding.UTF8.GetString(bytes); } } } // default if content-tye not found or recognized if (body == null && rawBodyString == null) { var reader = new StreamReader(request.Body, Encoding.UTF8); body = rawBodyString = reader.ReadToEnd(); } request.Body.Position = 0; http.Body = body.ToRpc(logger, capabilities); if (IsRawBodyBytesRequested(capabilities)) { http.RawBody = bytes.ToRpc(logger, capabilities); } else { http.RawBody = rawBodyString.ToRpc(logger, capabilities); } } } else { // attempt POCO / array of pocos try { typedData.Json = JsonConvert.SerializeObject(value); } catch { typedData.String = value.ToString(); } } return(typedData); }
private static bool IsTypedDataCollectionSupported(Capabilities capabilities) { return(!string.IsNullOrEmpty(capabilities.GetCapabilityState(LanguageWorkerConstants.TypedDataCollection))); }
private static bool IsRawBodyBytesRequested(Capabilities capabilities) { return(capabilities.GetCapabilityState(LanguageWorkerConstants.RawHttpBodyBytes) != null); }
private static bool IsRawBodyBytesRequested(Capabilities capabilities) { return(!string.IsNullOrEmpty(capabilities.GetCapabilityState(LanguageWorkerConstants.RawHttpBodyBytes))); }
private static bool IsBodyOnlySupported(Capabilities capabilities) { return(!string.IsNullOrEmpty(capabilities.GetCapabilityState(LanguageWorkerConstants.RpcHttpBodyOnly))); }
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); } }
internal static TypedData ToRpcHttp(this HttpRequest request, ILogger logger, Capabilities capabilities) { TypedData typedData = new TypedData(); 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) { if (IsBodyOnlySupported(capabilities)) { PopulateBody(request, http, capabilities, logger); } else { PopulateBodyAndRawBody(request, http, capabilities, logger); } } return(typedData); }
public static InvocationRequest ToRpcInvocationRequest(this ScriptInvocationContext context, bool isTriggerMetadataPopulatedByWorker, ILogger logger, Capabilities capabilities) { InvocationRequest invocationRequest = new InvocationRequest() { FunctionId = context.FunctionMetadata.FunctionId, InvocationId = context.ExecutionContext.InvocationId.ToString(), TraceContext = GetRpcTraceContext(context.Traceparent, context.Tracestate, context.Attributes, logger), }; foreach (var pair in context.BindingData) { if (pair.Value != null) { if ((pair.Value is HttpRequest) && isTriggerMetadataPopulatedByWorker) { continue; } invocationRequest.TriggerMetadata.Add(pair.Key, pair.Value.ToRpc(logger, capabilities)); } } foreach (var input in context.Inputs) { invocationRequest.InputData.Add(new ParameterBinding() { Name = input.name, Data = input.val.ToRpc(logger, capabilities) }); } return(invocationRequest); }