Skip to content

Commit

Permalink
Merge pull request #94 from novuhq/83-add-user-agent-header
Browse files Browse the repository at this point in the history
feat: add version to user-agent header #83
  • Loading branch information
jainpawan21 authored Feb 16, 2025
2 parents f54f0ee + 6cd3094 commit c361559
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 16 deletions.
32 changes: 32 additions & 0 deletions src/Novu.Domain/NovuConstants.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
using System.Reflection;

namespace Novu.Domain;

public static class NovuConstants
{
public static readonly int MaxPageSize = 100;

/// <summary>
/// Returns the properly formatted User-Agent header string for the `novu-dotnet` package,
/// including the version retrieved from the NuGet package version.
/// </summary>
/// <returns>
/// A string in the format `novu-dotnet/{version}`, where {version} is the version of the NuGet package.
/// If no version is found, it defaults to `novu-dotnet/0.0.0`.
/// </returns>
/// <remarks>
/// The version is retrieved from the assembly's <see cref="AssemblyInformationalVersionAttribute" />.
/// If the version is not specified in the assembly, it falls back to `0.0.0` as the default version.
/// This ensures compliance with the HTTP specification for the User-Agent header format, as outlined in RFC 7231.
/// </remarks>
/// <example>
/// Example usage:
/// <code>
/// string userAgent = NovuConstants.UserAgent();
/// Console.WriteLine(userAgent); // Outputs: novu-dotnet/1.2.3 (if version is 1.2.3)
/// </code>
/// </example>
public static string UserAgent()
{
// Add a User-Agent header if enabled
var version = Assembly
.GetExecutingAssembly()
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
.InformationalVersion ?? "0.0.0";
return $"novu-dotnet/{version}";
}
}
56 changes: 41 additions & 15 deletions src/Novu.Extensions/IocNovuRegistrationExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Net.Http;
using System.Reflection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Novu.Clients;
Expand All @@ -16,22 +17,11 @@ public static class IocNovuRegistrationExtensions
public static IServiceCollection RegisterNovuClients(
this IServiceCollection services,
IConfiguration configuration,
RefitSettings refitSettings = null)
RefitSettings refitSettings = null,
Action<HttpClient> configureHttpClient = null)
{
var novuConfiguration = configuration.GetNovuClientConfiguration();

Action<HttpClient> configureClient = client =>
{
client.BaseAddress = new Uri(novuConfiguration.Url);

// allow for multiple registrations—authorization cannot have multiple entries
if (client.DefaultRequestHeaders.Contains("Authorization"))
{
client.DefaultRequestHeaders.Remove("Authorization");
}

client.DefaultRequestHeaders.Add("Authorization", $"ApiKey {novuConfiguration.ApiKey}");
};
var configureClient = configureHttpClient ?? ConfigureClient(novuConfiguration);
var settings = RefitSettings(refitSettings);

services.AddRefitClient<ISubscriberClient>(settings).ConfigureHttpClient(configureClient);
Expand Down Expand Up @@ -60,6 +50,42 @@ public static IServiceCollection RegisterNovuClients(
}


/// <summary>
/// Configures an <see cref="HttpClient" /> with the necessary headers for Novu API communication.
/// </summary>
/// <remarks>
/// Hand this into the configuration with includeUserAgent as false to turn off
/// </remarks>
/// <param name="novuConfiguration">The configuration containing the Novu API base URL and API key.</param>
/// <param name="includeUserAgent">Indicates whether to include a custom User-Agent header. Default is true.</param>
/// <returns>
/// An <see cref="Action{HttpClient}" /> that applies the necessary configuration to an <see cref="HttpClient" />
/// instance.
/// </returns>
public static Action<HttpClient> ConfigureClient(
NovuClientConfiguration novuConfiguration,
bool includeUserAgent = true)
{
return client =>
{
// Set the base address for API requests
client.BaseAddress = new Uri(novuConfiguration.Url);

// Ensure only one Authorization header exists
if (client.DefaultRequestHeaders.Contains("Authorization"))
{
client.DefaultRequestHeaders.Remove("Authorization");
}

client.DefaultRequestHeaders.Add("Authorization", $"ApiKey {novuConfiguration.ApiKey}");
if (includeUserAgent)
{
var userAgent = NovuConstants.UserAgent();
client.DefaultRequestHeaders.Add("User-Agent", userAgent);
}
};
}

public static IServiceCollection RegisterNovuClient(
this IServiceCollection services,
IConfiguration configuration,
Expand All @@ -70,7 +96,7 @@ public static IServiceCollection RegisterNovuClient(
configuration.GetNovuClientConfiguration(),
refitSettings: RefitSettings(refitSettings)));
}

private static RefitSettings RefitSettings(RefitSettings refitSettings)
{
return refitSettings ?? new RefitSettings
Expand Down
4 changes: 3 additions & 1 deletion src/Novu/NovuClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Novu.Clients;
using System.Reflection;
using Novu.Clients;
using Novu.Domain;
using Refit;

Expand All @@ -16,6 +17,7 @@ public NovuClient(
var httpClient = client ?? new HttpClient();
httpClient.BaseAddress = new Uri(configuration.Url);
httpClient.DefaultRequestHeaders.Add(AuthorizationHeaderName, $"ApiKey {configuration.ApiKey}");
httpClient.DefaultRequestHeaders.Add("User-Agent", NovuConstants.UserAgent());

refitSettings ??= new RefitSettings
{
Expand Down

0 comments on commit c361559

Please sign in to comment.