mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +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,
|
DefaultCacheDuration = settings.DefaultCacheDuration,
|
||||||
DefaultMaxAge = settings.DefaultMaxAge,
|
DefaultMaxAge = settings.DefaultMaxAge,
|
||||||
VaryQueryStringParameters = settings.VaryQueryStringParameters,
|
VaryQueryStringParameters = settings.VaryQueryStringParameters,
|
||||||
|
VaryRequestHeaders = settings.VaryRequestHeaders,
|
||||||
IgnoredUrls = settings.IgnoredUrls,
|
IgnoredUrls = settings.IgnoredUrls,
|
||||||
DebugMode = settings.DebugMode,
|
DebugMode = settings.DebugMode,
|
||||||
ApplyCulture = settings.ApplyCulture,
|
ApplyCulture = settings.ApplyCulture,
|
||||||
@@ -108,6 +109,7 @@ namespace Orchard.OutputCache.Controllers {
|
|||||||
settings.DefaultCacheDuration = model.DefaultCacheDuration;
|
settings.DefaultCacheDuration = model.DefaultCacheDuration;
|
||||||
settings.DefaultMaxAge = model.DefaultMaxAge;
|
settings.DefaultMaxAge = model.DefaultMaxAge;
|
||||||
settings.VaryQueryStringParameters = model.VaryQueryStringParameters;
|
settings.VaryQueryStringParameters = model.VaryQueryStringParameters;
|
||||||
|
settings.VaryRequestHeaders = model.VaryRequestHeaders;
|
||||||
settings.IgnoredUrls = model.IgnoredUrls;
|
settings.IgnoredUrls = model.IgnoredUrls;
|
||||||
settings.DebugMode = model.DebugMode;
|
settings.DebugMode = model.DebugMode;
|
||||||
settings.ApplyCulture = model.ApplyCulture;
|
settings.ApplyCulture = model.ApplyCulture;
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ namespace Orchard.OutputCache.Filters {
|
|||||||
private string _actionName;
|
private string _actionName;
|
||||||
private DateTime _now;
|
private DateTime _now;
|
||||||
private string[] _varyQueryStringParameters;
|
private string[] _varyQueryStringParameters;
|
||||||
|
private ISet<string> _varyRequestHeaders;
|
||||||
|
|
||||||
|
|
||||||
private WorkContext _workContext;
|
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
|
// caches the ignored urls to prevent a query to the settings
|
||||||
_ignoredUrls = _cacheManager.Get("CacheSettingsPart.IgnoredUrls",
|
_ignoredUrls = _cacheManager.Get("CacheSettingsPart.IgnoredUrls",
|
||||||
context => {
|
context => {
|
||||||
@@ -187,6 +209,7 @@ namespace Orchard.OutputCache.Filters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var queryString = filterContext.RequestContext.HttpContext.Request.QueryString;
|
var queryString = filterContext.RequestContext.HttpContext.Request.QueryString;
|
||||||
|
var requestHeaders = filterContext.RequestContext.HttpContext.Request.Headers;
|
||||||
var parameters = new Dictionary<string, object>(filterContext.ActionParameters);
|
var parameters = new Dictionary<string, object>(filterContext.ActionParameters);
|
||||||
|
|
||||||
foreach (var key in queryString.AllKeys) {
|
foreach (var key in queryString.AllKeys) {
|
||||||
@@ -195,6 +218,12 @@ namespace Orchard.OutputCache.Filters {
|
|||||||
parameters[key] = queryString[key];
|
parameters[key] = queryString[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var varyByRequestHeader in _varyRequestHeaders) {
|
||||||
|
if (requestHeaders.AllKeys.Contains(varyByRequestHeader)) {
|
||||||
|
parameters["HEADER:" + varyByRequestHeader] = requestHeaders[varyByRequestHeader];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// compute the cache key
|
// compute the cache key
|
||||||
_cacheKey = ComputeCacheKey(filterContext, parameters);
|
_cacheKey = ComputeCacheKey(filterContext, parameters);
|
||||||
|
|
||||||
@@ -434,14 +463,9 @@ namespace Orchard.OutputCache.Filters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// different tenants with the same urls have different entries
|
foreach (var varyRequestHeader in _varyRequestHeaders) {
|
||||||
response.Cache.VaryByHeaders["HOST"] = true;
|
response.Cache.VaryByHeaders[varyRequestHeader] = 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;
|
|
||||||
|
|
||||||
// create a unique cache per browser, in case a Theme is rendered differently (e.g., mobile)
|
// 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
|
// c.f. http://msdn.microsoft.com/en-us/library/aa478965.aspx
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ namespace Orchard.OutputCache {
|
|||||||
.Column<int>("DefaultCacheDuration")
|
.Column<int>("DefaultCacheDuration")
|
||||||
.Column<int>("DefaultMaxAge")
|
.Column<int>("DefaultMaxAge")
|
||||||
.Column<string>("IgnoredUrls", c => c.Unlimited())
|
.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>("DebugMode", c => c.WithDefault(false))
|
||||||
.Column<bool>("ApplyCulture", 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))
|
.Column<string>("RouteKey", c => c.WithLength(255))
|
||||||
);
|
);
|
||||||
|
|
||||||
return 4;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int UpdateFrom1() {
|
public int UpdateFrom1() {
|
||||||
@@ -80,5 +82,15 @@ namespace Orchard.OutputCache {
|
|||||||
|
|
||||||
return 5;
|
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; }
|
set { Record.VaryQueryStringParameters = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string VaryRequestHeaders {
|
||||||
|
get { return Record.VaryRequestHeaders; }
|
||||||
|
set { Record.VaryRequestHeaders = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public string IgnoredUrls {
|
public string IgnoredUrls {
|
||||||
get { return Record.IgnoredUrls; }
|
get { return Record.IgnoredUrls; }
|
||||||
set { Record.IgnoredUrls = value; }
|
set { Record.IgnoredUrls = value; }
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ namespace Orchard.OutputCache.Models {
|
|||||||
[StringLengthMax]
|
[StringLengthMax]
|
||||||
public virtual string VaryQueryStringParameters { get; set; }
|
public virtual string VaryQueryStringParameters { get; set; }
|
||||||
|
|
||||||
|
[StringLengthMax]
|
||||||
|
public virtual string VaryRequestHeaders { get; set; }
|
||||||
|
|
||||||
[StringLengthMax]
|
[StringLengthMax]
|
||||||
public virtual string IgnoredUrls { get; set; }
|
public virtual string IgnoredUrls { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,5 +12,6 @@ namespace Orchard.OutputCache.ViewModels {
|
|||||||
public bool ApplyCulture { get; set; }
|
public bool ApplyCulture { get; set; }
|
||||||
public bool DebugMode { get; set; }
|
public bool DebugMode { get; set; }
|
||||||
public string VaryQueryStringParameters { 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>
|
<span class="hint">@T("When defined, using comma separated values, sets caching to vary via specified query string parameters")</span>
|
||||||
</fieldset>
|
</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>
|
<fieldset>
|
||||||
<label>@T("Ignored urls")</label>
|
<label>@T("Ignored urls")</label>
|
||||||
@Html.TextAreaFor(m => m.IgnoredUrls, new { @class = "textMedium" })
|
@Html.TextAreaFor(m => m.IgnoredUrls, new { @class = "textMedium" })
|
||||||
|
|||||||
Reference in New Issue
Block a user