in src/WebJobs.Script.Grpc/MessageExtensions/GrpcMessageConversionExtensions.cs [102:222]
internal static async Task<TypedData> ToRpcHttp(this HttpRequest request, ILogger logger, GrpcCapabilities capabilities)
{
bool requiresRouteParams = !string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.RequiresRouteParameters));
bool isHttpProxying = !string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.HttpUri));
bool shouldUseNullableValueDictionary = ShouldUseNullableValueDictionary(capabilities);
// If proxying the http request to the worker and
// worker requesting route params, send an empty rpc http object with only params populated.
if (isHttpProxying && requiresRouteParams)
{
var typedDataWithRouteParams = new TypedData
{
Http = new RpcHttp()
};
PopulateHttpRouteDataAsParams(request, typedDataWithRouteParams.Http, shouldUseNullableValueDictionary);
return typedDataWithRouteParams;
}
// If proxying the http request to the worker, keep the grpc message minimal
if (isHttpProxying)
{
return EmptyRpcHttp;
}
var http = new RpcHttp()
{
Url = $"{(request.IsHttps ? "https" : "http")}://{request.Host}{request.Path}{request.QueryString}",
Method = request.Method,
RawBody = null
};
var typedData = new TypedData
{
Http = http
};
foreach (var pair in request.Query)
{
var value = pair.Value.ToString();
if (shouldUseNullableValueDictionary)
{
http.NullableQuery.Add(pair.Key, new NullableString { Value = value });
}
else
{
if (!string.IsNullOrEmpty(value))
{
http.Query.Add(pair.Key, value);
}
}
}
foreach (var pair in request.Headers)
{
if (shouldUseNullableValueDictionary)
{
http.NullableHeaders.Add(pair.Key.ToLowerInvariant(), new NullableString { Value = pair.Value.ToString() });
}
else
{
if (ShouldIgnoreEmptyHeaderValues(capabilities) && string.IsNullOrEmpty(pair.Value.ToString()))
{
continue;
}
http.Headers.Add(pair.Key.ToLowerInvariant(), pair.Value.ToString());
}
}
PopulateHttpRouteDataAsParams(request, http, shouldUseNullableValueDictionary);
// 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;
}