Improve HTTP header handling and error resilience
Enhance InvokeRecActionViewCommandHandler to robustly handle invalid or non-strict HTTP header values. "Content-Type" and "Authorization" headers are now set using strict parsing with fallback to TryAddWithoutValidation on failure, logging warnings for easier debugging. General headers and API key headers also use this strict-then-fallback approach, making HTTP request construction more tolerant of malformed values and reducing runtime errors.
This commit is contained in:
@@ -59,10 +59,21 @@ public class InvokeRecActionViewCommandHandler(
|
||||
using var httpReq = CreateHttpRequestMessage(restType, action.EndpointUri);
|
||||
|
||||
if (action.Body is not null)
|
||||
{
|
||||
httpReq.Content = new StringContent(action.Body);
|
||||
|
||||
var contentType = action.Headers?.FirstOrDefault(h => h.Key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase));
|
||||
if (contentType is not null && !string.IsNullOrWhiteSpace(contentType.Value.Value))
|
||||
try { httpReq.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType.Value.Value); }
|
||||
catch (FormatException ex)
|
||||
{
|
||||
logger?.LogWarning(ex, "Content-Type '{Value}' could not be parsed with strict validation, falling back to TryAddWithoutValidation. ActionId: {ActionId}, ProfileId: {ProfileId}", contentType.Value.Value, action.Id, action.ProfileId);
|
||||
httpReq.Content.Headers.TryAddWithoutValidation("Content-Type", contentType.Value.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (action.Headers is not null)
|
||||
foreach (var header in action.Headers)
|
||||
foreach (var header in action.Headers.Where(h => !h.Key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)))
|
||||
try { httpReq.Headers.Add(header.Key, header.Value); }
|
||||
catch (FormatException ex)
|
||||
{
|
||||
@@ -81,7 +92,12 @@ public class InvokeRecActionViewCommandHandler(
|
||||
switch (action.EndpointAuthApiKeyAddTo)
|
||||
{
|
||||
case ApiKeyLocation.Header:
|
||||
httpReq.Headers.Add(apiKey, apiValue);
|
||||
try { httpReq.Headers.Add(apiKey, apiValue); }
|
||||
catch (FormatException ex)
|
||||
{
|
||||
logger?.LogWarning(ex, "ApiKey header '{Key}' could not be added with strict validation, falling back to TryAddWithoutValidation. ActionId: {ActionId}, ProfileId: {ProfileId}", apiKey, action.Id, action.ProfileId);
|
||||
httpReq.Headers.TryAddWithoutValidation(apiKey, apiValue);
|
||||
}
|
||||
break;
|
||||
case ApiKeyLocation.Query:
|
||||
var uriBuilder = new UriBuilder(httpReq.RequestUri!);
|
||||
@@ -104,14 +120,24 @@ public class InvokeRecActionViewCommandHandler(
|
||||
case EndpointAuthType.JwtBearer:
|
||||
case EndpointAuthType.OAuth2:
|
||||
if (action.EndpointAuthToken is string authToken)
|
||||
httpReq.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
try { httpReq.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken); }
|
||||
catch (FormatException ex)
|
||||
{
|
||||
logger?.LogWarning(ex, "Bearer token could not be set with strict validation, falling back to TryAddWithoutValidation. ActionId: {ActionId}, ProfileId: {ProfileId}", action.Id, action.ProfileId);
|
||||
httpReq.Headers.TryAddWithoutValidation("Authorization", $"Bearer {authToken}");
|
||||
}
|
||||
break;
|
||||
|
||||
case EndpointAuthType.BasicAuth:
|
||||
if (action.EndpointAuthUsername is string authUsername && action.EndpointAuthPassword is string authPassword)
|
||||
{
|
||||
var basicAuth = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{authUsername}:{authPassword}"));
|
||||
httpReq.Headers.Authorization = new AuthenticationHeaderValue("Basic", basicAuth);
|
||||
try { httpReq.Headers.Authorization = new AuthenticationHeaderValue("Basic", basicAuth); }
|
||||
catch (FormatException ex)
|
||||
{
|
||||
logger?.LogWarning(ex, "Basic auth could not be set with strict validation, falling back to TryAddWithoutValidation. ActionId: {ActionId}, ProfileId: {ProfileId}", action.Id, action.ProfileId);
|
||||
httpReq.Headers.TryAddWithoutValidation("Authorization", $"Basic {basicAuth}");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user