Output cache vary by query string modes (#7509)

This commit is contained in:
Josh Berry 2017-01-13 10:02:25 -06:00 committed by Sébastien Ros
parent c679547a39
commit 079823c485
7 changed files with 55 additions and 5 deletions

View File

@ -87,6 +87,7 @@ namespace Orchard.OutputCache.Controllers {
DefaultCacheDuration = settings.DefaultCacheDuration,
DefaultCacheGraceTime = settings.DefaultCacheGraceTime,
DefaultMaxAge = settings.DefaultMaxAge,
VaryByQueryStringIsExclusive = settings.VaryByQueryStringIsExclusive,
VaryByQueryStringParameters = settings.VaryByQueryStringParameters,
VaryByRequestHeaders = settings.VaryByRequestHeaders,
VaryByRequestCookies = settings.VaryByRequestCookies,
@ -115,6 +116,7 @@ namespace Orchard.OutputCache.Controllers {
settings.DefaultCacheDuration = model.DefaultCacheDuration;
settings.DefaultCacheGraceTime = model.DefaultCacheGraceTime;
settings.DefaultMaxAge = model.DefaultMaxAge;
settings.VaryByQueryStringIsExclusive = model.VaryByQueryStringIsExclusive;
settings.VaryByQueryStringParameters = model.VaryByQueryStringParameters;
settings.VaryByRequestHeaders = model.VaryByRequestHeaders;
settings.VaryByRequestCookies = model.VaryByRequestCookies;

View File

@ -388,8 +388,17 @@ namespace Orchard.OutputCache.Filters {
// Vary by configured query string parameters.
var queryString = filterContext.RequestContext.HttpContext.Request.QueryString;
foreach (var key in queryString.AllKeys) {
if (key == null || (CacheSettings.VaryByQueryStringParameters != null && !CacheSettings.VaryByQueryStringParameters.Contains(key)))
if (key == null)
continue;
// In exclusive mode, don't vary if the key matches
if (CacheSettings.VaryByQueryStringIsExclusive && (CacheSettings.VaryByQueryStringParameters != null && CacheSettings.VaryByQueryStringParameters.Contains(key)))
continue;
// In inclusive mode, don't vary if the key doesn't match
if(!CacheSettings.VaryByQueryStringIsExclusive && (CacheSettings.VaryByQueryStringParameters == null || !CacheSettings.VaryByQueryStringParameters.Contains(key)))
continue;
result[key] = queryString[key];
}

View File

@ -1,7 +1,16 @@
using Orchard.Data.Migration;
using Orchard.ContentManagement;
using Orchard.Data.Migration;
using Orchard.OutputCache.Models;
namespace Orchard.OutputCache {
public class Migrations : DataMigrationImpl {
private readonly IOrchardServices _orchardServices;
public Migrations(IOrchardServices orchardServices) {
_orchardServices = orchardServices;
}
public int Create() {
SchemaBuilder.CreateTable("CacheParameterRecord",
@ -56,5 +65,17 @@ namespace Orchard.OutputCache {
return 7;
}
public int UpdateFrom7() {
var cacheSettings = _orchardServices.WorkContext.CurrentSite.As<CacheSettingsPart>();
if (!string.IsNullOrWhiteSpace(cacheSettings.VaryByQueryStringParameters)) {
// Prevent behavior from changing if vary on querystring was used prior to introduction of exclusive mode
cacheSettings.VaryByQueryStringIsExclusive = false;
}
else {
cacheSettings.VaryByQueryStringIsExclusive = true; // Default mode
};
return 8;
}
}
}

View File

@ -11,6 +11,7 @@ namespace Orchard.OutputCache.Models {
DefaultCacheDuration = part.DefaultCacheDuration;
DefaultCacheGraceTime = part.DefaultCacheGraceTime;
DefaultMaxAge = part.DefaultMaxAge;
VaryByQueryStringIsExclusive = part.VaryByQueryStringIsExclusive;
VaryByQueryStringParameters = String.IsNullOrWhiteSpace(part.VaryByQueryStringParameters) ? null : part.VaryByQueryStringParameters.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray();
VaryByRequestHeaders = String.IsNullOrWhiteSpace(part.VaryByRequestHeaders) ? new HashSet<string>() : new HashSet<string>(part.VaryByRequestHeaders.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray());
VaryByRequestHeaders.Add("HOST"); // Always vary by host name/tenant.
@ -26,6 +27,7 @@ namespace Orchard.OutputCache.Models {
public int DefaultCacheDuration { get; private set; }
public int DefaultCacheGraceTime { get; private set; }
public int DefaultMaxAge { get; private set; }
public bool VaryByQueryStringIsExclusive { get; private set; }
public IEnumerable<string> VaryByQueryStringParameters { get; private set; }
public ISet<string> VaryByRequestHeaders { get; private set; }
public ISet<string> VaryByRequestCookies { get; private set; }

View File

@ -18,6 +18,11 @@ namespace Orchard.OutputCache.Models {
set { this.Store(x => x.DefaultMaxAge, value); }
}
public bool VaryByQueryStringIsExclusive {
get { return this.Retrieve(x => x.VaryByQueryStringIsExclusive); }
set { this.Store(x => x.VaryByQueryStringIsExclusive, value); }
}
public string VaryByQueryStringParameters {
get {
return this.Retrieve(

View File

@ -9,6 +9,7 @@ namespace Orchard.OutputCache.ViewModels {
[Range(0, Int32.MaxValue), Required] public int DefaultCacheDuration { get; set; }
[Range(0, Int32.MaxValue), Required] public int DefaultCacheGraceTime { get; set; }
[Range(0, Int32.MaxValue), Required] public int DefaultMaxAge { get; set; }
public bool VaryByQueryStringIsExclusive { get; set; }
public string VaryByQueryStringParameters { get; set; }
public string VaryByRequestHeaders { get; set; }
public string VaryByRequestCookies { get; set; }

View File

@ -37,10 +37,20 @@
<fieldset>
<label>@T("Vary by Query String Parameters")</label>
@Html.TextBoxFor(m => m.VaryByQueryStringParameters, new { @class = "text medium" })
<span class="hint">@T("When defined, using comma separated values, sets caching to vary by the specified query string parameters. Leave empty to vary by all query string parameters.")</span>
<div>
@Html.RadioButtonFor(m => m.VaryByQueryStringIsExclusive, "False", new { Id = "varyByQueryStringExclusiveMode" })
<label for="varyByQueryStringExclusiveMode" class="forcheckbox">@T("Vary by only the following query string parameters")</label>
</div>
<div>
@Html.RadioButtonFor(m => m.VaryByQueryStringIsExclusive, "True", new { Id = "varyByQueryStringInclusiveMode" })
<label for="varyByQueryStringInclusiveMode" class="forcheckbox">@T("Vary by all except the following query string parameters")</label>
</div>
<div>
@Html.TextBoxFor(m => m.VaryByQueryStringParameters, new { @class = "text medium" })
<span class="hint">@T("Separate multiple query string parameters with a comma.")</span>
</div>
</fieldset>
<fieldset>
<label>@T("Vary by Request Headers")</label>
@Html.TextBoxFor(m => m.VaryByRequestHeaders, new { @class = "text medium" })