Configuration: Handle upstream server's limited lifetime
Origin configuration
Most popular proxy cache server such as Nginx or Varnish Cache do not support
the Sunset
header by default. Therefore, additional configuration is
required in Unified Origin to generate the Expires
or Cache-Control
headers responses. In the following sections we describe how to
create these configurations.
Note
Cache-Control
takes precedence over Expires
HTTP header.
Apache
You can generate the Expires
response header dynamically based on the
Sunset
header value. This can be achieved by adding the following
LocationMatch
directive which copies the Sunset
value to the
Expires
header:
# Create Expires header from Sunset header if matches the specific
# Sunset date format example: `Tue, 08 Mar 2022 14:42:47 GMT`.
<LocationMatch ".*\.(?i:isml)">
Header setifempty Expires "expr=%{resp:Sunset}" \
"expr=%{resp:Sunset} =~ m#^[a-zA-Z]+,\s[0-9]{0,2}\s[a-zA-Z]+\s[0-9]{0,4}\s[0-9]{0,2}:[0-9]{0,2}:[0-9]{0,2}\sGMT$#"
</LocationMatch>
Origin shield configuration
Nginx
Nginx reads by default the Expires
header. If the Expires
header was
created based on the Sunset
header as previously explained, the object will
stay in cache only for the duration of the archive length
(--archive_length). Therefore, if you require an Origin shield cache
or the CDN to keep the object for a longer period you may need to configure your
cache control headers differently.
Note
Nginx sets the cache TTL on objects based on the following precedence:
# Higher priority ----> Lower priority
X-Accel-Expires -> Cache-Control -> Expires -> proxy_cache_valid
Varnish Cache
Varnish Cache can be configured to generate the Expires
and
Cache-Control
headers based on the Sunset
header. The following
VCL snippet is an example of how to generate this behavior.
import std;
sub vcl_backend_response {
# Set the object's TTL by using Sunset header if Cache-Control=max-age"..."
# and Expires not found.
if(beresp.http.Cache-Control !~ "max-age"
&& !beresp.http.Expires && bereq.url ~ ".*.[m3u8|m4s|mpd|dash]")
{
if(beresp.http.Sunset)
{
# beresp.ttl -> delta time between Sunset and now
set beresp.ttl = std.time(beresp.http.Sunset, now) - now;
set beresp.http.x-max-age = beresp.ttl;
# We round to an integer the max-age value in seconds
# to comply with [RFC7234] and set Cache-Control: max-age='...'
set beresp.http.x-max-age = std.integer(beresp.http.x-max-age, 0);
set beresp.http.Cache-Control = "max-age=" + beresp.http.x-max-age;
# Remove x-max-age header from response
unset beresp.http.x-max-age;
# Add Expires header equals to Sunset header
set beresp.http.Expires = beresp.http.Sunset;
}
}
# Otherwise use Cache-Control header from backend
else{
if(beresp.http.Cache-Control)
{
std.log("Use default Cache-Control Header from backend");
}
if(beresp.http.Expires)
{
std.log("Use default Expires Header from backend");
}
}
}