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");
}
}
}