Use named HttpClients (#15375)
* Use named HttpClients * Register as named client * Set headers on request message. * Add User agent header to http client * Add headers within Try-catch * Add using for HttpResponseMessage * Update src/Umbraco.Infrastructure/BackgroundJobs/Jobs/WebhookFiring.cs Co-authored-by: Ronald Barendse <ronald@barend.se> * Update src/Umbraco.Infrastructure/BackgroundJobs/Jobs/WebhookFiring.cs Co-authored-by: Kenn Jacobsen <kja@umbraco.dk> * Log key instead of entire webhook * Update src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs Co-authored-by: Ronald Barendse <ronald@barend.se> * Create constant for User agent header name * Update src/Umbraco.Infrastructure/BackgroundJobs/Jobs/WebhookFiring.cs Co-authored-by: Ronald Barendse <ronald@barend.se> * Use datetime.now --------- Co-authored-by: Zeegaan <nge@umbraco.dk> Co-authored-by: Ronald Barendse <ronald@barend.se> Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
This commit is contained in:
@@ -14,5 +14,18 @@ public static partial class Constants
|
||||
/// Name for http client which ignores certificate errors.
|
||||
/// </summary>
|
||||
public const string IgnoreCertificateErrors = "Umbraco:HttpClients:IgnoreCertificateErrors";
|
||||
|
||||
/// <summary>
|
||||
/// Name for http client which sends webhook requests.
|
||||
/// </summary>
|
||||
public const string WebhookFiring = "Umbraco:HttpClients:WebhookFiring";
|
||||
|
||||
public static class Headers
|
||||
{
|
||||
/// <summary>
|
||||
/// User agent name for the product name.
|
||||
/// </summary>
|
||||
public const string UserAgentProductName = "Umbraco-Cms";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public abstract class OEmbedProviderBase : IEmbedProvider
|
||||
if (_httpClient == null)
|
||||
{
|
||||
_httpClient = new HttpClient();
|
||||
_httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd("Umbraco-CMS");
|
||||
_httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd(Constants.HttpClients.Headers.UserAgentProductName);
|
||||
}
|
||||
|
||||
using (var request = new HttpRequestMessage(HttpMethod.Get, url))
|
||||
|
||||
@@ -6,7 +6,6 @@ using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Serialization;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.BackgroundJobs.Jobs;
|
||||
@@ -15,11 +14,11 @@ public class WebhookFiring : IRecurringBackgroundJob
|
||||
{
|
||||
private readonly ILogger<WebhookFiring> _logger;
|
||||
private readonly IWebhookRequestService _webhookRequestService;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IWebhookLogFactory _webhookLogFactory;
|
||||
private readonly IWebhookLogService _webhookLogService;
|
||||
private readonly IWebhookService _webHookService;
|
||||
private readonly ICoreScopeProvider _coreScopeProvider;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private WebhookSettings _webhookSettings;
|
||||
|
||||
public TimeSpan Period => _webhookSettings.Period;
|
||||
@@ -32,20 +31,20 @@ public class WebhookFiring : IRecurringBackgroundJob
|
||||
public WebhookFiring(
|
||||
ILogger<WebhookFiring> logger,
|
||||
IWebhookRequestService webhookRequestService,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IWebhookLogFactory webhookLogFactory,
|
||||
IWebhookLogService webhookLogService,
|
||||
IWebhookService webHookService,
|
||||
IOptionsMonitor<WebhookSettings> webhookSettings,
|
||||
ICoreScopeProvider coreScopeProvider)
|
||||
ICoreScopeProvider coreScopeProvider,
|
||||
IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_webhookRequestService = webhookRequestService;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_webhookLogFactory = webhookLogFactory;
|
||||
_webhookLogService = webhookLogService;
|
||||
_webHookService = webHookService;
|
||||
_coreScopeProvider = coreScopeProvider;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_webhookSettings = webhookSettings.CurrentValue;
|
||||
webhookSettings.OnChange(x => _webhookSettings = x);
|
||||
}
|
||||
@@ -72,8 +71,7 @@ public class WebhookFiring : IRecurringBackgroundJob
|
||||
return;
|
||||
}
|
||||
|
||||
HttpResponseMessage? response = await SendRequestAsync(webhook, request.EventAlias, request.RequestObject, request.RetryCount, CancellationToken.None);
|
||||
|
||||
using HttpResponseMessage? response = await SendRequestAsync(webhook, request.EventAlias, request.RequestObject, request.RetryCount, CancellationToken.None);
|
||||
if ((response?.IsSuccessStatusCode ?? false) || request.RetryCount >= _webhookSettings.MaximumRetries)
|
||||
{
|
||||
await _webhookRequestService.DeleteAsync(request);
|
||||
@@ -90,24 +88,36 @@ public class WebhookFiring : IRecurringBackgroundJob
|
||||
|
||||
private async Task<HttpResponseMessage?> SendRequestAsync(IWebhook webhook, string eventName, string? serializedObject, int retryCount, CancellationToken cancellationToken)
|
||||
{
|
||||
using var httpClient = new HttpClient();
|
||||
using HttpClient httpClient = _httpClientFactory.CreateClient(Constants.HttpClients.WebhookFiring);
|
||||
|
||||
var stringContent = new StringContent(serializedObject ?? string.Empty, Encoding.UTF8, MediaTypeNames.Application.Json);
|
||||
stringContent.Headers.TryAddWithoutValidation("Umb-Webhook-Event", eventName);
|
||||
|
||||
foreach (KeyValuePair<string, string> header in webhook.Headers)
|
||||
using var request = new HttpRequestMessage(HttpMethod.Post, webhook.Url)
|
||||
{
|
||||
stringContent.Headers.TryAddWithoutValidation(header.Key, header.Value);
|
||||
}
|
||||
Version = httpClient.DefaultRequestVersion,
|
||||
VersionPolicy = httpClient.DefaultVersionPolicy,
|
||||
};
|
||||
|
||||
HttpResponseMessage? response = null;
|
||||
try
|
||||
{
|
||||
response = await httpClient.PostAsync(webhook.Url, stringContent, cancellationToken);
|
||||
// Add headers
|
||||
request.Headers.Add("Umb-Webhook-Event", eventName);
|
||||
request.Headers.Add("Umb-Webhook-RetryCount", retryCount.ToString());
|
||||
request.Headers.Add("Umb-Webhook-Date", DateTime.Now.ToString("R"));
|
||||
|
||||
foreach (KeyValuePair<string, string> header in webhook.Headers)
|
||||
{
|
||||
request.Headers.Add(header.Key, header.Value);
|
||||
}
|
||||
|
||||
// Set content
|
||||
request.Content = new StringContent(serializedObject ?? string.Empty, Encoding.UTF8, MediaTypeNames.Application.Json);
|
||||
|
||||
// Send request
|
||||
response = await httpClient.SendAsync(request, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error while sending webhook request for webhook {WebhookKey}.", webhook);
|
||||
_logger.LogError(ex, "Error while sending webhook request for webhook {WebhookKey}.", webhook.Key);
|
||||
}
|
||||
|
||||
var webhookResponseModel = new WebhookResponseModel
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Data.Common;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Reflection;
|
||||
using Dazinator.Extensions.FileProviders.GlobPatternFilter;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
@@ -10,7 +11,6 @@ using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Serilog.Extensions.Logging;
|
||||
@@ -23,6 +23,7 @@ using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Blocks;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Diagnostics;
|
||||
@@ -261,6 +262,11 @@ public static partial class UmbracoBuilderExtensions
|
||||
ServerCertificateCustomValidationCallback =
|
||||
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator,
|
||||
});
|
||||
builder.Services.AddHttpClient(Constants.HttpClients.WebhookFiring, (services, client) =>
|
||||
{
|
||||
var productVersion = services.GetRequiredService<IUmbracoVersion>().SemanticVersion.ToSemanticStringWithoutBuild();
|
||||
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(Constants.HttpClients.Headers.UserAgentProductName, productVersion));
|
||||
});
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user