|
|
|
|
@ -16,6 +16,7 @@
@@ -16,6 +16,7 @@
|
|
|
|
|
|
|
|
|
|
package org.springframework.http; |
|
|
|
|
|
|
|
|
|
import java.time.Duration; |
|
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
|
|
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
|
@ -50,7 +51,8 @@ import org.springframework.util.StringUtils;
@@ -50,7 +51,8 @@ import org.springframework.util.StringUtils;
|
|
|
|
|
*/ |
|
|
|
|
public class CacheControl { |
|
|
|
|
|
|
|
|
|
private long maxAge = -1; |
|
|
|
|
@Nullable |
|
|
|
|
private Duration maxAge = null; |
|
|
|
|
|
|
|
|
|
private boolean noCache = false; |
|
|
|
|
|
|
|
|
|
@ -66,12 +68,14 @@ public class CacheControl {
@@ -66,12 +68,14 @@ public class CacheControl {
|
|
|
|
|
|
|
|
|
|
private boolean proxyRevalidate = false; |
|
|
|
|
|
|
|
|
|
private long staleWhileRevalidate = -1; |
|
|
|
|
|
|
|
|
|
private long staleIfError = -1; |
|
|
|
|
@Nullable |
|
|
|
|
private Duration staleWhileRevalidate = null; |
|
|
|
|
|
|
|
|
|
private long sMaxAge = -1; |
|
|
|
|
@Nullable |
|
|
|
|
private Duration staleIfError = null; |
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
|
private Duration sMaxAge = null; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Create an empty CacheControl instance. |
|
|
|
|
@ -106,8 +110,25 @@ public class CacheControl {
@@ -106,8 +110,25 @@ public class CacheControl {
|
|
|
|
|
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.8">rfc7234 section 5.2.2.8</a> |
|
|
|
|
*/ |
|
|
|
|
public static CacheControl maxAge(long maxAge, TimeUnit unit) { |
|
|
|
|
return maxAge(Duration.ofSeconds(unit.toSeconds(maxAge))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Add a "max-age=" directive. |
|
|
|
|
* <p>This directive is well suited for publicly caching resources, knowing that |
|
|
|
|
* they won't change within the configured amount of time. Additional directives |
|
|
|
|
* can be also used, in case resources shouldn't be cached ({@link #cachePrivate()}) |
|
|
|
|
* or transformed ({@link #noTransform()}) by shared caches. |
|
|
|
|
* <p>In order to prevent caches to reuse the cached response even when it has |
|
|
|
|
* become stale (i.e. the "max-age" delay is passed), the "must-revalidate" |
|
|
|
|
* directive should be set ({@link #mustRevalidate()} |
|
|
|
|
* @param maxAge the maximum time the response should be cached |
|
|
|
|
* @return {@code this}, to facilitate method chaining |
|
|
|
|
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.8">rfc7234 section 5.2.2.8</a> |
|
|
|
|
*/ |
|
|
|
|
public static CacheControl maxAge(Duration maxAge) { |
|
|
|
|
CacheControl cc = new CacheControl(); |
|
|
|
|
cc.maxAge = unit.toSeconds(maxAge); |
|
|
|
|
cc.maxAge = maxAge; |
|
|
|
|
return cc; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -216,7 +237,19 @@ public class CacheControl {
@@ -216,7 +237,19 @@ public class CacheControl {
|
|
|
|
|
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.9">rfc7234 section 5.2.2.9</a> |
|
|
|
|
*/ |
|
|
|
|
public CacheControl sMaxAge(long sMaxAge, TimeUnit unit) { |
|
|
|
|
this.sMaxAge = unit.toSeconds(sMaxAge); |
|
|
|
|
return sMaxAge(Duration.ofSeconds(unit.toSeconds(sMaxAge))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Add an "s-maxage" directive. |
|
|
|
|
* <p>This directive indicates that, in shared caches, the maximum age specified |
|
|
|
|
* by this directive overrides the maximum age specified by other directives. |
|
|
|
|
* @param sMaxAge the maximum time the response should be cached |
|
|
|
|
* @return {@code this}, to facilitate method chaining |
|
|
|
|
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.9">rfc7234 section 5.2.2.9</a> |
|
|
|
|
*/ |
|
|
|
|
public CacheControl sMaxAge(Duration sMaxAge) { |
|
|
|
|
this.sMaxAge = sMaxAge; |
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -233,7 +266,22 @@ public class CacheControl {
@@ -233,7 +266,22 @@ public class CacheControl {
|
|
|
|
|
* @see <a href="https://tools.ietf.org/html/rfc5861#section-3">rfc5861 section 3</a> |
|
|
|
|
*/ |
|
|
|
|
public CacheControl staleWhileRevalidate(long staleWhileRevalidate, TimeUnit unit) { |
|
|
|
|
this.staleWhileRevalidate = unit.toSeconds(staleWhileRevalidate); |
|
|
|
|
return staleWhileRevalidate(Duration.ofSeconds(unit.toSeconds(staleWhileRevalidate))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Add a "stale-while-revalidate" directive. |
|
|
|
|
* <p>This directive indicates that caches MAY serve the response in which it |
|
|
|
|
* appears after it becomes stale, up to the indicated number of seconds. |
|
|
|
|
* If a cached response is served stale due to the presence of this extension, |
|
|
|
|
* the cache SHOULD attempt to revalidate it while still serving stale responses |
|
|
|
|
* (i.e. without blocking). |
|
|
|
|
* @param staleWhileRevalidate the maximum time the response should be used while being revalidated |
|
|
|
|
* @return {@code this}, to facilitate method chaining |
|
|
|
|
* @see <a href="https://tools.ietf.org/html/rfc5861#section-3">rfc5861 section 3</a> |
|
|
|
|
*/ |
|
|
|
|
public CacheControl staleWhileRevalidate(Duration staleWhileRevalidate) { |
|
|
|
|
this.staleWhileRevalidate = staleWhileRevalidate; |
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -247,10 +295,21 @@ public class CacheControl {
@@ -247,10 +295,21 @@ public class CacheControl {
|
|
|
|
|
* @see <a href="https://tools.ietf.org/html/rfc5861#section-4">rfc5861 section 4</a> |
|
|
|
|
*/ |
|
|
|
|
public CacheControl staleIfError(long staleIfError, TimeUnit unit) { |
|
|
|
|
this.staleIfError = unit.toSeconds(staleIfError); |
|
|
|
|
return this; |
|
|
|
|
return staleIfError(Duration.ofSeconds(unit.toSeconds(staleIfError))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Add a "stale-if-error" directive. |
|
|
|
|
* <p>This directive indicates that when an error is encountered, a cached stale response |
|
|
|
|
* MAY be used to satisfy the request, regardless of other freshness information. |
|
|
|
|
* @param staleIfError the maximum time the response should be used when errors are encountered |
|
|
|
|
* @return {@code this}, to facilitate method chaining |
|
|
|
|
* @see <a href="https://tools.ietf.org/html/rfc5861#section-4">rfc5861 section 4</a> |
|
|
|
|
*/ |
|
|
|
|
public CacheControl staleIfError(Duration staleIfError) { |
|
|
|
|
this.staleIfError = staleIfError; |
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Return the "Cache-Control" header value, if any. |
|
|
|
|
@ -268,8 +327,8 @@ public class CacheControl {
@@ -268,8 +327,8 @@ public class CacheControl {
|
|
|
|
|
*/ |
|
|
|
|
private String toHeaderValue() { |
|
|
|
|
StringBuilder headerValue = new StringBuilder(); |
|
|
|
|
if (this.maxAge != -1) { |
|
|
|
|
appendDirective(headerValue, "max-age=" + this.maxAge); |
|
|
|
|
if (this.maxAge != null) { |
|
|
|
|
appendDirective(headerValue, "max-age=" + this.maxAge.getSeconds()); |
|
|
|
|
} |
|
|
|
|
if (this.noCache) { |
|
|
|
|
appendDirective(headerValue, "no-cache"); |
|
|
|
|
@ -292,14 +351,14 @@ public class CacheControl {
@@ -292,14 +351,14 @@ public class CacheControl {
|
|
|
|
|
if (this.proxyRevalidate) { |
|
|
|
|
appendDirective(headerValue, "proxy-revalidate"); |
|
|
|
|
} |
|
|
|
|
if (this.sMaxAge != -1) { |
|
|
|
|
appendDirective(headerValue, "s-maxage=" + this.sMaxAge); |
|
|
|
|
if (this.sMaxAge != null) { |
|
|
|
|
appendDirective(headerValue, "s-maxage=" + this.sMaxAge.getSeconds()); |
|
|
|
|
} |
|
|
|
|
if (this.staleIfError != -1) { |
|
|
|
|
appendDirective(headerValue, "stale-if-error=" + this.staleIfError); |
|
|
|
|
if (this.staleIfError != null) { |
|
|
|
|
appendDirective(headerValue, "stale-if-error=" + this.staleIfError.getSeconds()); |
|
|
|
|
} |
|
|
|
|
if (this.staleWhileRevalidate != -1) { |
|
|
|
|
appendDirective(headerValue, "stale-while-revalidate=" + this.staleWhileRevalidate); |
|
|
|
|
if (this.staleWhileRevalidate != null) { |
|
|
|
|
appendDirective(headerValue, "stale-while-revalidate=" + this.staleWhileRevalidate.getSeconds()); |
|
|
|
|
} |
|
|
|
|
return headerValue.toString(); |
|
|
|
|
} |
|
|
|
|
|