Skip to content

Commit 4deb756

Browse files
committed
Adds variation by the header name Accept-Language to the delivery API output cache policy (#19709)
* Adds variation by the header name Accept-Language to the develivery API output cache policy * Removed obsolete constructor (not necessary as the class is internal). * Introduce contants for header names.
1 parent 543b644 commit 4deb756

File tree

9 files changed

+67
-21
lines changed

9 files changed

+67
-21
lines changed

src/Umbraco.Cms.Api.Delivery/Caching/DeliveryApiOutputCachePolicy.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
using Microsoft.AspNetCore.OutputCaching;
1+
using Microsoft.AspNetCore.OutputCaching;
22
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.Extensions.Primitives;
34
using Umbraco.Cms.Core.DeliveryApi;
45

56
namespace Umbraco.Cms.Api.Delivery.Caching;
67

78
internal sealed class DeliveryApiOutputCachePolicy : IOutputCachePolicy
89
{
910
private readonly TimeSpan _duration;
11+
private readonly StringValues _varyByHeaderNames;
1012

11-
public DeliveryApiOutputCachePolicy(TimeSpan duration)
12-
=> _duration = duration;
13+
public DeliveryApiOutputCachePolicy(TimeSpan duration, StringValues varyByHeaderNames)
14+
{
15+
_duration = duration;
16+
_varyByHeaderNames = varyByHeaderNames;
17+
}
1318

1419
ValueTask IOutputCachePolicy.CacheRequestAsync(OutputCacheContext context, CancellationToken cancellationToken)
1520
{
@@ -20,6 +25,7 @@ ValueTask IOutputCachePolicy.CacheRequestAsync(OutputCacheContext context, Cance
2025

2126
context.EnableOutputCaching = requestPreviewService.IsPreview() is false;
2227
context.ResponseExpirationTimeSpan = _duration;
28+
context.CacheVaryByRules.HeaderNames = _varyByHeaderNames;
2329

2430
return ValueTask.CompletedTask;
2531
}

src/Umbraco.Cms.Api.Delivery/DependencyInjection/UmbracoBuilderExtensions.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Microsoft.AspNetCore.Routing;
66
using Microsoft.Extensions.Configuration;
77
using Microsoft.Extensions.DependencyInjection;
8+
using Microsoft.Extensions.Primitives;
89
using Umbraco.Cms.Api.Common.DependencyInjection;
910
using Umbraco.Cms.Api.Delivery.Accessors;
1011
using Umbraco.Cms.Api.Delivery.Caching;
@@ -110,12 +111,20 @@ private static IUmbracoBuilder AddOutputCache(this IUmbracoBuilder builder)
110111

111112
if (outputCacheSettings.ContentDuration.TotalSeconds > 0)
112113
{
113-
options.AddPolicy(Constants.DeliveryApi.OutputCache.ContentCachePolicy, new DeliveryApiOutputCachePolicy(outputCacheSettings.ContentDuration));
114+
options.AddPolicy(
115+
Constants.DeliveryApi.OutputCache.ContentCachePolicy,
116+
new DeliveryApiOutputCachePolicy(
117+
outputCacheSettings.ContentDuration,
118+
new StringValues([Constants.DeliveryApi.HeaderNames.AcceptLanguage, Constants.DeliveryApi.HeaderNames.AcceptSegment, Constants.DeliveryApi.HeaderNames.StartItem])));
114119
}
115120

116121
if (outputCacheSettings.MediaDuration.TotalSeconds > 0)
117122
{
118-
options.AddPolicy(Constants.DeliveryApi.OutputCache.MediaCachePolicy, new DeliveryApiOutputCachePolicy(outputCacheSettings.MediaDuration));
123+
options.AddPolicy(
124+
Constants.DeliveryApi.OutputCache.MediaCachePolicy,
125+
new DeliveryApiOutputCachePolicy(
126+
outputCacheSettings.MediaDuration,
127+
Constants.DeliveryApi.HeaderNames.StartItem));
119128
}
120129
});
121130

src/Umbraco.Cms.Api.Delivery/Filters/SwaggerContentDocumentationFilter.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Microsoft.OpenApi.Any;
1+
using Microsoft.OpenApi.Any;
22
using Microsoft.OpenApi.Models;
33
using Swashbuckle.AspNetCore.SwaggerGen;
44
using Umbraco.Cms.Api.Delivery.Configuration;
@@ -21,7 +21,7 @@ protected override void ApplyOperation(OpenApiOperation operation, OperationFilt
2121

2222
operation.Parameters.Add(new OpenApiParameter
2323
{
24-
Name = "Accept-Language",
24+
Name = Core.Constants.DeliveryApi.HeaderNames.AcceptLanguage,
2525
In = ParameterLocation.Header,
2626
Required = false,
2727
Description = "Defines the language to return. Use this when querying language variant content items.",
@@ -35,7 +35,7 @@ protected override void ApplyOperation(OpenApiOperation operation, OperationFilt
3535

3636
operation.Parameters.Add(new OpenApiParameter
3737
{
38-
Name = "Accept-Segment",
38+
Name = Core.Constants.DeliveryApi.HeaderNames.AcceptSegment,
3939
In = ParameterLocation.Header,
4040
Required = false,
4141
Description = "Defines the segment to return. Use this when querying segment variant content items.",
@@ -51,7 +51,7 @@ protected override void ApplyOperation(OpenApiOperation operation, OperationFilt
5151

5252
operation.Parameters.Add(new OpenApiParameter
5353
{
54-
Name = "Preview",
54+
Name = Core.Constants.DeliveryApi.HeaderNames.Preview,
5555
In = ParameterLocation.Header,
5656
Required = false,
5757
Description = "Whether to request draft content.",
@@ -60,7 +60,7 @@ protected override void ApplyOperation(OpenApiOperation operation, OperationFilt
6060

6161
operation.Parameters.Add(new OpenApiParameter
6262
{
63-
Name = "Start-Item",
63+
Name = Core.Constants.DeliveryApi.HeaderNames.StartItem,
6464
In = ParameterLocation.Header,
6565
Required = false,
6666
Description = "URL segment or GUID of a root content item.",

src/Umbraco.Cms.Api.Delivery/Filters/SwaggerDocumentationFilterBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Microsoft.AspNetCore.Mvc;
1+
using Microsoft.AspNetCore.Mvc;
22
using Microsoft.OpenApi.Any;
33
using Microsoft.OpenApi.Models;
44
using Swashbuckle.AspNetCore.SwaggerGen;
@@ -63,7 +63,7 @@ protected void AddFields(OpenApiOperation operation, OperationFilterContext cont
6363
protected void AddApiKey(OpenApiOperation operation) =>
6464
operation.Parameters.Add(new OpenApiParameter
6565
{
66-
Name = "Api-Key",
66+
Name = Core.Constants.DeliveryApi.HeaderNames.ApiKey,
6767
In = ParameterLocation.Header,
6868
Required = false,
6969
Description = "API key specified through configuration to authorize access to the API.",

src/Umbraco.Cms.Api.Delivery/Services/ApiAccessService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Microsoft.AspNetCore.Http;
1+
using Microsoft.AspNetCore.Http;
22
using Microsoft.Extensions.Options;
33
using Umbraco.Cms.Core.Configuration.Models;
44
using Umbraco.Cms.Core.DeliveryApi;
@@ -29,7 +29,7 @@ public ApiAccessService(IHttpContextAccessor httpContextAccessor, IOptionsMonito
2929
private bool IfEnabled(Func<bool> condition) => _deliveryApiSettings.Enabled && condition();
3030

3131
private bool HasValidApiKey() => _deliveryApiSettings.ApiKey.IsNullOrWhiteSpace() == false
32-
&& _deliveryApiSettings.ApiKey.Equals(GetHeaderValue("Api-Key"));
32+
&& _deliveryApiSettings.ApiKey.Equals(GetHeaderValue(Core.Constants.DeliveryApi.HeaderNames.ApiKey));
3333

3434
private bool IfMediaEnabled(Func<bool> condition) => _deliveryApiSettings is { Enabled: true, Media.Enabled: true } && condition();
3535
}

src/Umbraco.Cms.Api.Delivery/Services/RequestPreviewService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ public RequestPreviewService(IHttpContextAccessor httpContextAccessor)
1111
}
1212

1313
/// <inheritdoc />
14-
public bool IsPreview() => string.Equals(GetHeaderValue("Preview"), "true", StringComparison.OrdinalIgnoreCase);
14+
public bool IsPreview() => string.Equals(GetHeaderValue(Core.Constants.DeliveryApi.HeaderNames.Preview), "true", StringComparison.OrdinalIgnoreCase);
1515
}

src/Umbraco.Cms.Api.Delivery/Services/RequestSegmentService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Microsoft.AspNetCore.Http;
1+
using Microsoft.AspNetCore.Http;
22
using Umbraco.Cms.Core.DeliveryApi;
33

44
namespace Umbraco.Cms.Api.Delivery.Services;
@@ -12,5 +12,5 @@ public RequestSegmentService(IHttpContextAccessor httpContextAccessor)
1212

1313
/// <inheritdoc />
1414
public string? GetRequestedSegment()
15-
=> GetHeaderValue("Accept-Segment");
15+
=> GetHeaderValue(Core.Constants.DeliveryApi.HeaderNames.AcceptSegment);
1616
}

src/Umbraco.Cms.Api.Delivery/Services/RequestStartItemProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,5 @@ public RequestStartItemProvider(
6060
}
6161

6262
/// <inheritdoc/>
63-
public string? RequestedStartItem() => GetHeaderValue("Start-Item");
63+
public string? RequestedStartItem() => GetHeaderValue(Constants.DeliveryApi.HeaderNames.StartItem);
6464
}

src/Umbraco.Core/Constants-DeliveryApi.cs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Umbraco.Cms.Core;
1+
namespace Umbraco.Cms.Core;
22

33
public static partial class Constants
44
{
@@ -24,14 +24,45 @@ public static class Routing
2424
public static class OutputCache
2525
{
2626
/// <summary>
27-
/// Output cache policy name for content
27+
/// Output cache policy name for content.
2828
/// </summary>
2929
public const string ContentCachePolicy = "DeliveryApiContent";
3030

3131
/// <summary>
32-
/// Output cache policy name for media
32+
/// Output cache policy name for media.
3333
/// </summary>
3434
public const string MediaCachePolicy = "DeliveryApiMedia";
3535
}
36+
37+
/// <summary>
38+
/// Constants for Delivery API header names.
39+
/// </summary>
40+
public static class HeaderNames
41+
{
42+
/// <summary>
43+
/// Header name for accept language.
44+
/// </summary>
45+
public const string AcceptLanguage = "Accept-Language";
46+
47+
/// <summary>
48+
/// Header name for accept segment.
49+
/// </summary>
50+
public const string AcceptSegment = "Accept-Segment";
51+
52+
/// <summary>
53+
/// Header name for API key.
54+
/// </summary>
55+
public const string ApiKey = "Api-Key";
56+
57+
/// <summary>
58+
/// Header name for preview.
59+
/// </summary>
60+
public const string Preview = "Preview";
61+
62+
/// <summary>
63+
/// Header name for start item.
64+
/// </summary>
65+
public const string StartItem = "Start-Item";
66+
}
3667
}
3768
}

0 commit comments

Comments
 (0)