mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
#20042: Cache invalidation by user defined request headers
Work Item: 20042
This commit is contained in:

committed by
Sebastien Ros

parent
4a6daa9ffa
commit
a8ff9e218a
@@ -85,6 +85,7 @@ namespace Orchard.OutputCache.Controllers {
|
||||
DefaultCacheDuration = settings.DefaultCacheDuration,
|
||||
DefaultMaxAge = settings.DefaultMaxAge,
|
||||
VaryQueryStringParameters = settings.VaryQueryStringParameters,
|
||||
VaryRequestHeaders = settings.VaryRequestHeaders,
|
||||
IgnoredUrls = settings.IgnoredUrls,
|
||||
DebugMode = settings.DebugMode,
|
||||
ApplyCulture = settings.ApplyCulture,
|
||||
@@ -108,6 +109,7 @@ namespace Orchard.OutputCache.Controllers {
|
||||
settings.DefaultCacheDuration = model.DefaultCacheDuration;
|
||||
settings.DefaultMaxAge = model.DefaultMaxAge;
|
||||
settings.VaryQueryStringParameters = model.VaryQueryStringParameters;
|
||||
settings.VaryRequestHeaders = model.VaryRequestHeaders;
|
||||
settings.IgnoredUrls = model.IgnoredUrls;
|
||||
settings.DebugMode = model.DebugMode;
|
||||
settings.ApplyCulture = model.ApplyCulture;
|
||||
|
@@ -73,6 +73,7 @@ namespace Orchard.OutputCache.Filters {
|
||||
private string _actionName;
|
||||
private DateTime _now;
|
||||
private string[] _varyQueryStringParameters;
|
||||
private ISet<string> _varyRequestHeaders;
|
||||
|
||||
|
||||
private WorkContext _workContext;
|
||||
@@ -157,6 +158,27 @@ namespace Orchard.OutputCache.Filters {
|
||||
}
|
||||
);
|
||||
|
||||
var varyRequestHeadersFromSettings = _cacheManager.Get("CacheSettingsPart.VaryRequestHeaders",
|
||||
context => {
|
||||
context.Monitor(_signals.When(CacheSettingsPart.CacheKey));
|
||||
var varyRequestHeaders = _workContext.CurrentSite.As<CacheSettingsPart>().VaryRequestHeaders;
|
||||
|
||||
return string.IsNullOrWhiteSpace(varyRequestHeaders) ? null
|
||||
: varyRequestHeaders.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray();
|
||||
}
|
||||
);
|
||||
|
||||
_varyRequestHeaders = (varyRequestHeadersFromSettings == null) ? new HashSet<string>() : new HashSet<string>(varyRequestHeadersFromSettings);
|
||||
|
||||
// different tenants with the same urls have different entries
|
||||
_varyRequestHeaders.Add("HOST");
|
||||
|
||||
// Set the Vary: Accept-Encoding response header.
|
||||
// This instructs the proxies to cache two versions of the resource: one compressed, and one uncompressed.
|
||||
// The correct version of the resource is delivered based on the client request header.
|
||||
// This is a good choice for applications that are singly homed and depend on public proxies for user locality.
|
||||
_varyRequestHeaders.Add("Accept-Encoding");
|
||||
|
||||
// caches the ignored urls to prevent a query to the settings
|
||||
_ignoredUrls = _cacheManager.Get("CacheSettingsPart.IgnoredUrls",
|
||||
context => {
|
||||
@@ -187,6 +209,7 @@ namespace Orchard.OutputCache.Filters {
|
||||
}
|
||||
|
||||
var queryString = filterContext.RequestContext.HttpContext.Request.QueryString;
|
||||
var requestHeaders = filterContext.RequestContext.HttpContext.Request.Headers;
|
||||
var parameters = new Dictionary<string, object>(filterContext.ActionParameters);
|
||||
|
||||
foreach (var key in queryString.AllKeys) {
|
||||
@@ -195,6 +218,12 @@ namespace Orchard.OutputCache.Filters {
|
||||
parameters[key] = queryString[key];
|
||||
}
|
||||
|
||||
foreach (var varyByRequestHeader in _varyRequestHeaders) {
|
||||
if (requestHeaders.AllKeys.Contains(varyByRequestHeader)) {
|
||||
parameters["HEADER:" + varyByRequestHeader] = requestHeaders[varyByRequestHeader];
|
||||
}
|
||||
}
|
||||
|
||||
// compute the cache key
|
||||
_cacheKey = ComputeCacheKey(filterContext, parameters);
|
||||
|
||||
@@ -434,14 +463,9 @@ namespace Orchard.OutputCache.Filters {
|
||||
}
|
||||
}
|
||||
|
||||
// different tenants with the same urls have different entries
|
||||
response.Cache.VaryByHeaders["HOST"] = true;
|
||||
|
||||
// Set the Vary: Accept-Encoding response header.
|
||||
// This instructs the proxies to cache two versions of the resource: one compressed, and one uncompressed.
|
||||
// The correct version of the resource is delivered based on the client request header.
|
||||
// This is a good choice for applications that are singly homed and depend on public proxies for user locality.
|
||||
response.Cache.VaryByHeaders["Accept-Encoding"] = true;
|
||||
foreach (var varyRequestHeader in _varyRequestHeaders) {
|
||||
response.Cache.VaryByHeaders[varyRequestHeader] = true;
|
||||
}
|
||||
|
||||
// create a unique cache per browser, in case a Theme is rendered differently (e.g., mobile)
|
||||
// c.f. http://msdn.microsoft.com/en-us/library/aa478965.aspx
|
||||
|
@@ -10,6 +10,8 @@ namespace Orchard.OutputCache {
|
||||
.Column<int>("DefaultCacheDuration")
|
||||
.Column<int>("DefaultMaxAge")
|
||||
.Column<string>("IgnoredUrls", c => c.Unlimited())
|
||||
.Column<string>("VaryQueryStringParameters", c => c.Unlimited())
|
||||
.Column<string>("VaryRequestHeaders", c => c.Unlimited())
|
||||
.Column<bool>("DebugMode", c => c.WithDefault(false))
|
||||
.Column<bool>("ApplyCulture", c => c.WithDefault(false))
|
||||
);
|
||||
@@ -22,7 +24,7 @@ namespace Orchard.OutputCache {
|
||||
.Column<string>("RouteKey", c => c.WithLength(255))
|
||||
);
|
||||
|
||||
return 4;
|
||||
return 6;
|
||||
}
|
||||
|
||||
public int UpdateFrom1() {
|
||||
@@ -80,5 +82,15 @@ namespace Orchard.OutputCache {
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
public int UpdateFrom5() {
|
||||
|
||||
SchemaBuilder.AlterTable("CacheSettingsPartRecord",
|
||||
table => table
|
||||
.AddColumn<string>("VaryRequestHeaders", c => c.Unlimited())
|
||||
);
|
||||
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
}
|
@@ -19,6 +19,11 @@ namespace Orchard.OutputCache.Models {
|
||||
set { Record.VaryQueryStringParameters = value; }
|
||||
}
|
||||
|
||||
public string VaryRequestHeaders {
|
||||
get { return Record.VaryRequestHeaders; }
|
||||
set { Record.VaryRequestHeaders = value; }
|
||||
}
|
||||
|
||||
public string IgnoredUrls {
|
||||
get { return Record.IgnoredUrls; }
|
||||
set { Record.IgnoredUrls = value; }
|
||||
|
@@ -11,6 +11,9 @@ namespace Orchard.OutputCache.Models {
|
||||
[StringLengthMax]
|
||||
public virtual string VaryQueryStringParameters { get; set; }
|
||||
|
||||
[StringLengthMax]
|
||||
public virtual string VaryRequestHeaders { get; set; }
|
||||
|
||||
[StringLengthMax]
|
||||
public virtual string IgnoredUrls { get; set; }
|
||||
}
|
||||
|
@@ -12,5 +12,6 @@ namespace Orchard.OutputCache.ViewModels {
|
||||
public bool ApplyCulture { get; set; }
|
||||
public bool DebugMode { get; set; }
|
||||
public string VaryQueryStringParameters { get; set; }
|
||||
public string VaryRequestHeaders { get; set; }
|
||||
}
|
||||
}
|
@@ -31,6 +31,12 @@
|
||||
<span class="hint">@T("When defined, using comma separated values, sets caching to vary via specified query string parameters")</span>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<label>@T("Vary Request Headers")</label>
|
||||
@Html.TextBoxFor(m => m.VaryRequestHeaders, new { @class = "textMedium" })
|
||||
<span class="hint">@T("When defined, using comma separated values, sets caching to vary via specified request headers.")</span>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<label>@T("Ignored urls")</label>
|
||||
@Html.TextAreaFor(m => m.IgnoredUrls, new { @class = "textMedium" })
|
||||
|
Reference in New Issue
Block a user