1
1
/*
2
- * Copyright 2002-2024 the original author or authors.
2
+ * Copyright 2002-2023 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
23
23
import org .springframework .util .StringUtils ;
24
24
25
25
/**
26
- * A builder for creating "Cache-Control" HTTP response headers. As of Spring
27
- * Framework 6.2, this class is immutable.
26
+ * A builder for creating "Cache-Control" HTTP response headers.
28
27
*
29
28
* <p>Adding Cache-Control directives to HTTP responses can significantly improve the client
30
29
* experience when interacting with a web application. This builder creates opinionated
52
51
*/
53
52
public class CacheControl {
54
53
55
- private static final CacheControl EMPTY = new CacheControl ();
56
-
57
54
@ Nullable
58
- private final Duration maxAge ;
55
+ private Duration maxAge ;
59
56
60
- private final boolean noCache ;
57
+ private boolean noCache = false ;
61
58
62
- private final boolean noStore ;
59
+ private boolean noStore = false ;
63
60
64
- private final boolean mustRevalidate ;
61
+ private boolean mustRevalidate = false ;
65
62
66
- private final boolean noTransform ;
63
+ private boolean noTransform = false ;
67
64
68
- private final boolean cachePublic ;
65
+ private boolean cachePublic = false ;
69
66
70
- private final boolean cachePrivate ;
67
+ private boolean cachePrivate = false ;
71
68
72
- private final boolean proxyRevalidate ;
69
+ private boolean proxyRevalidate = false ;
73
70
74
71
@ Nullable
75
- private final Duration staleWhileRevalidate ;
72
+ private Duration staleWhileRevalidate ;
76
73
77
74
@ Nullable
78
- private final Duration staleIfError ;
75
+ private Duration staleIfError ;
79
76
80
77
@ Nullable
81
- private final Duration sMaxAge ;
78
+ private Duration sMaxAge ;
79
+
80
+ private boolean immutable = false ;
82
81
83
- private final boolean immutable ;
84
82
85
83
/**
86
84
* Create an empty CacheControl instance.
87
85
* @see #empty()
88
86
*/
89
87
protected CacheControl () {
90
- this (null , false , false , false , false , false , false , false , null , null , null , false );
91
88
}
92
89
93
- private CacheControl (@ Nullable Duration maxAge , boolean noCache , boolean noStore ,
94
- boolean mustRevalidate , boolean noTransform , boolean cachePublic ,
95
- boolean cachePrivate , boolean proxyRevalidate , @ Nullable Duration staleWhileRevalidate ,
96
- @ Nullable Duration staleIfError , @ Nullable Duration sMaxAge , boolean immutable ) {
97
- this .maxAge = maxAge ;
98
- this .noCache = noCache ;
99
- this .noStore = noStore ;
100
- this .mustRevalidate = mustRevalidate ;
101
- this .noTransform = noTransform ;
102
- this .cachePublic = cachePublic ;
103
- this .cachePrivate = cachePrivate ;
104
- this .proxyRevalidate = proxyRevalidate ;
105
- this .staleWhileRevalidate = staleWhileRevalidate ;
106
- this .staleIfError = staleIfError ;
107
- this .sMaxAge = sMaxAge ;
108
- this .immutable = immutable ;
109
- }
110
90
111
91
/**
112
92
* Return an empty directive.
113
93
* <p>This is well suited for using other optional directives without "max-age",
114
94
* "no-cache" or "no-store".
115
- * @return an empty directive
95
+ * @return {@code this}, to facilitate method chaining
116
96
*/
117
97
public static CacheControl empty () {
118
- return EMPTY ;
98
+ return new CacheControl () ;
119
99
}
120
100
121
101
/**
122
- * Return a "max-age=" directive.
102
+ * Add a "max-age=" directive.
123
103
* <p>This directive is well suited for publicly caching resources, knowing that
124
104
* they won't change within the configured amount of time. Additional directives
125
105
* can be also used, in case resources shouldn't be cached ({@link #cachePrivate()})
@@ -129,7 +109,7 @@ public static CacheControl empty() {
129
109
* directive should be set ({@link #mustRevalidate()}
130
110
* @param maxAge the maximum time the response should be cached
131
111
* @param unit the time unit of the {@code maxAge} argument
132
- * @return a CacheControl instance with a "max-age" directive
112
+ * @return {@code this}, to facilitate method chaining
133
113
* @see #maxAge(Duration)
134
114
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.8">rfc7234 section 5.2.2.8</a>
135
115
*/
@@ -138,7 +118,7 @@ public static CacheControl maxAge(long maxAge, TimeUnit unit) {
138
118
}
139
119
140
120
/**
141
- * Return a "max-age=" directive.
121
+ * Add a "max-age=" directive.
142
122
* <p>This directive is well suited for publicly caching resources, knowing that
143
123
* they won't change within the configured amount of time. Additional directives
144
124
* can be also used, in case resources shouldn't be cached ({@link #cachePrivate()})
@@ -147,120 +127,118 @@ public static CacheControl maxAge(long maxAge, TimeUnit unit) {
147
127
* become stale (i.e. the "max-age" delay is passed), the "must-revalidate"
148
128
* directive should be set ({@link #mustRevalidate()}
149
129
* @param maxAge the maximum time the response should be cached
150
- * @return a CacheControl instance with a "max-age" directive
130
+ * @return {@code this}, to facilitate method chaining
151
131
* @since 5.2
152
132
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.8">rfc7234 section 5.2.2.8</a>
153
133
*/
154
134
public static CacheControl maxAge (Duration maxAge ) {
155
- return new CacheControl (maxAge , false , false , false , false , false , false , false ,
156
- null , null , null , false );
135
+ CacheControl cc = new CacheControl ();
136
+ cc .maxAge = maxAge ;
137
+ return cc ;
157
138
}
158
139
159
140
/**
160
- * Return a "no-cache" directive.
141
+ * Add a "no-cache" directive.
161
142
* <p>This directive is well suited for telling caches that the response
162
143
* can be reused only if the client revalidates it with the server.
163
144
* This directive won't disable cache altogether and may result with clients
164
145
* sending conditional requests (with "ETag", "If-Modified-Since" headers)
165
146
* and the server responding with "304 - Not Modified" status.
166
147
* <p>In order to disable caching and minimize requests/responses exchanges,
167
148
* the {@link #noStore()} directive should be used instead of {@code #noCache()}.
168
- * @return a CacheControl instance with a "no-cache" directive
149
+ * @return {@code this}, to facilitate method chaining
169
150
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.2">rfc7234 section 5.2.2.2</a>
170
151
*/
171
152
public static CacheControl noCache () {
172
- return new CacheControl (null , true , false , false , false , false , false , false ,
173
- null , null , null , false );
153
+ CacheControl cc = new CacheControl ();
154
+ cc .noCache = true ;
155
+ return cc ;
174
156
}
175
157
176
158
/**
177
- * Return a "no-store" directive.
159
+ * Add a "no-store" directive.
178
160
* <p>This directive is well suited for preventing caches (browsers and proxies)
179
161
* to cache the content of responses.
180
- * @return a CacheControl instance with a "no-store" directive
162
+ * @return {@code this}, to facilitate method chaining
181
163
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.3">rfc7234 section 5.2.2.3</a>
182
164
*/
183
165
public static CacheControl noStore () {
184
- return new CacheControl (null , false , true , false , false , false , false , false ,
185
- null , null , null , false );
166
+ CacheControl cc = new CacheControl ();
167
+ cc .noStore = true ;
168
+ return cc ;
186
169
}
187
170
188
171
189
172
/**
190
- * Return a new instance with an additional "must-revalidate" directive.
173
+ * Add a "must-revalidate" directive.
191
174
* <p>This directive indicates that once it has become stale, a cache MUST NOT
192
175
* use the response to satisfy subsequent requests without successful validation
193
176
* on the origin server.
194
- * @return a new CacheControl instance with an additional "must-revalidate" directive
177
+ * @return {@code this}, to facilitate method chaining
195
178
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.1">rfc7234 section 5.2.2.1</a>
196
179
*/
197
180
public CacheControl mustRevalidate () {
198
- return new CacheControl (this .maxAge , this .noCache , this .noStore , true , this .noTransform ,
199
- this .cachePublic , this .cachePrivate , this .proxyRevalidate , this .staleWhileRevalidate ,
200
- this .staleIfError , this .sMaxAge , this .immutable );
181
+ this .mustRevalidate = true ;
182
+ return this ;
201
183
}
202
184
203
185
/**
204
- * Return a new instance with an additional "no-transform" directive.
186
+ * Add a "no-transform" directive.
205
187
* <p>This directive indicates that intermediaries (caches and others) should
206
188
* not transform the response content. This can be useful to force caches and
207
189
* CDNs not to automatically gzip or optimize the response content.
208
- * @return a new CacheControl instance with an additional "no-transform" directive
190
+ * @return {@code this}, to facilitate method chaining
209
191
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.4">rfc7234 section 5.2.2.4</a>
210
192
*/
211
193
public CacheControl noTransform () {
212
- return new CacheControl (this .maxAge , this .noCache , this .noStore , this .mustRevalidate , true ,
213
- this .cachePublic , this .cachePrivate , this .proxyRevalidate , this .staleWhileRevalidate ,
214
- this .staleIfError , this .sMaxAge , this .immutable );
194
+ this .noTransform = true ;
195
+ return this ;
215
196
}
216
197
217
198
/**
218
- * Return a new instance with an additional "public" directive.
199
+ * Add a "public" directive.
219
200
* <p>This directive indicates that any cache MAY store the response,
220
201
* even if the response would normally be non-cacheable or cacheable
221
202
* only within a private cache.
222
- * @return a new CacheControl instance with an additional "public" directive
203
+ * @return {@code this}, to facilitate method chaining
223
204
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.5">rfc7234 section 5.2.2.5</a>
224
205
*/
225
206
public CacheControl cachePublic () {
226
- return new CacheControl (this .maxAge , this .noCache , this .noStore , this .mustRevalidate , this .noTransform ,
227
- true , this .cachePrivate , this .proxyRevalidate , this .staleWhileRevalidate ,
228
- this .staleIfError , this .sMaxAge , this .immutable );
207
+ this .cachePublic = true ;
208
+ return this ;
229
209
}
230
210
231
211
/**
232
- * Return a new instance with an additional "private" directive.
212
+ * Add a "private" directive.
233
213
* <p>This directive indicates that the response message is intended
234
214
* for a single user and MUST NOT be stored by a shared cache.
235
- * @return a new CacheControl instance with an additional "private" directive
215
+ * @return {@code this}, to facilitate method chaining
236
216
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.6">rfc7234 section 5.2.2.6</a>
237
217
*/
238
218
public CacheControl cachePrivate () {
239
- return new CacheControl (this .maxAge , this .noCache , this .noStore , this .mustRevalidate , this .noTransform ,
240
- this .cachePublic , true , this .proxyRevalidate , this .staleWhileRevalidate ,
241
- this .staleIfError , this .sMaxAge , this .immutable );
219
+ this .cachePrivate = true ;
220
+ return this ;
242
221
}
243
222
244
223
/**
245
- * Return a new instance with an additional "proxy-revalidate" directive.
224
+ * Add a "proxy-revalidate" directive.
246
225
* <p>This directive has the same meaning as the "must-revalidate" directive,
247
226
* except that it does not apply to private caches (i.e. browsers, HTTP clients).
248
- * @return a new CacheControl instance with an additional "proxy-revalidate" directive
227
+ * @return {@code this}, to facilitate method chaining
249
228
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.7">rfc7234 section 5.2.2.7</a>
250
229
*/
251
230
public CacheControl proxyRevalidate () {
252
- return new CacheControl (this .maxAge , this .noCache , this .noStore , this .mustRevalidate , this .noTransform ,
253
- this .cachePublic , this .cachePrivate , true , this .staleWhileRevalidate ,
254
- this .staleIfError , this .sMaxAge , this .immutable );
231
+ this .proxyRevalidate = true ;
232
+ return this ;
255
233
}
256
234
257
235
/**
258
- * Return a new instance with an additional "s-maxage" directive.
236
+ * Add an "s-maxage" directive.
259
237
* <p>This directive indicates that, in shared caches, the maximum age specified
260
238
* by this directive overrides the maximum age specified by other directives.
261
239
* @param sMaxAge the maximum time the response should be cached
262
240
* @param unit the time unit of the {@code sMaxAge} argument
263
- * @return a new CacheControl instance with an additional "s-maxage" directive
241
+ * @return {@code this}, to facilitate method chaining
264
242
* @see #sMaxAge(Duration)
265
243
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.9">rfc7234 section 5.2.2.9</a>
266
244
*/
@@ -269,30 +247,29 @@ public CacheControl sMaxAge(long sMaxAge, TimeUnit unit) {
269
247
}
270
248
271
249
/**
272
- * Return a new instance with an additional "s-maxage" directive.
250
+ * Add an "s-maxage" directive.
273
251
* <p>This directive indicates that, in shared caches, the maximum age specified
274
252
* by this directive overrides the maximum age specified by other directives.
275
253
* @param sMaxAge the maximum time the response should be cached
276
- * @return a new CacheControl instance with an additional "s-maxage" directive
254
+ * @return {@code this}, to facilitate method chaining
277
255
* @since 5.2
278
256
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2.2.9">rfc7234 section 5.2.2.9</a>
279
257
*/
280
258
public CacheControl sMaxAge (Duration sMaxAge ) {
281
- return new CacheControl (this .maxAge , this .noCache , this .noStore , this .mustRevalidate , this .noTransform ,
282
- this .cachePublic , this .cachePrivate , this .proxyRevalidate , this .staleWhileRevalidate ,
283
- this .staleIfError , sMaxAge , this .immutable );
259
+ this .sMaxAge = sMaxAge ;
260
+ return this ;
284
261
}
285
262
286
263
/**
287
- * Return a new instance with an additional "stale-while-revalidate" directive.
264
+ * Add a "stale-while-revalidate" directive.
288
265
* <p>This directive indicates that caches MAY serve the response in which it
289
266
* appears after it becomes stale, up to the indicated number of seconds.
290
267
* If a cached response is served stale due to the presence of this extension,
291
268
* the cache SHOULD attempt to revalidate it while still serving stale responses
292
269
* (i.e. without blocking).
293
270
* @param staleWhileRevalidate the maximum time the response should be used while being revalidated
294
271
* @param unit the time unit of the {@code staleWhileRevalidate} argument
295
- * @return a new CacheControl instance with an additional "stale-while-revalidate" directive
272
+ * @return {@code this}, to facilitate method chaining
296
273
* @see #staleWhileRevalidate(Duration)
297
274
* @see <a href="https://tools.ietf.org/html/rfc5861#section-3">rfc5861 section 3</a>
298
275
*/
@@ -301,30 +278,29 @@ public CacheControl staleWhileRevalidate(long staleWhileRevalidate, TimeUnit uni
301
278
}
302
279
303
280
/**
304
- * Return a new instance with an additional "stale-while-revalidate" directive.
281
+ * Add a "stale-while-revalidate" directive.
305
282
* <p>This directive indicates that caches MAY serve the response in which it
306
283
* appears after it becomes stale, up to the indicated number of seconds.
307
284
* If a cached response is served stale due to the presence of this extension,
308
285
* the cache SHOULD attempt to revalidate it while still serving stale responses
309
286
* (i.e. without blocking).
310
287
* @param staleWhileRevalidate the maximum time the response should be used while being revalidated
311
- * @return a new CacheControl instance with an additional "stale-while-revalidate" directive
288
+ * @return {@code this}, to facilitate method chaining
312
289
* @since 5.2
313
290
* @see <a href="https://tools.ietf.org/html/rfc5861#section-3">rfc5861 section 3</a>
314
291
*/
315
292
public CacheControl staleWhileRevalidate (Duration staleWhileRevalidate ) {
316
- return new CacheControl (this .maxAge , this .noCache , this .noStore , this .mustRevalidate , this .noTransform ,
317
- this .cachePublic , this .cachePrivate , this .proxyRevalidate , staleWhileRevalidate ,
318
- this .staleIfError , this .sMaxAge , this .immutable );
293
+ this .staleWhileRevalidate = staleWhileRevalidate ;
294
+ return this ;
319
295
}
320
296
321
297
/**
322
- * Return a new instance with an additional "stale-if-error" directive.
298
+ * Add a "stale-if-error" directive.
323
299
* <p>This directive indicates that when an error is encountered, a cached stale response
324
300
* MAY be used to satisfy the request, regardless of other freshness information.
325
301
* @param staleIfError the maximum time the response should be used when errors are encountered
326
302
* @param unit the time unit of the {@code staleIfError} argument
327
- * @return a new CacheControl instance with an additional "stale-if-error" directive
303
+ * @return {@code this}, to facilitate method chaining
328
304
* @see #staleIfError(Duration)
329
305
* @see <a href="https://tools.ietf.org/html/rfc5861#section-4">rfc5861 section 4</a>
330
306
*/
@@ -333,34 +309,32 @@ public CacheControl staleIfError(long staleIfError, TimeUnit unit) {
333
309
}
334
310
335
311
/**
336
- * Return a new instance with an additional "stale-if-error" directive.
312
+ * Add a "stale-if-error" directive.
337
313
* <p>This directive indicates that when an error is encountered, a cached stale response
338
314
* MAY be used to satisfy the request, regardless of other freshness information.
339
315
* @param staleIfError the maximum time the response should be used when errors are encountered
340
- * @return a new CacheControl instance with an additional "stale-if-error" directive
316
+ * @return {@code this}, to facilitate method chaining
341
317
* @since 5.2
342
318
* @see <a href="https://tools.ietf.org/html/rfc5861#section-4">rfc5861 section 4</a>
343
319
*/
344
320
public CacheControl staleIfError (Duration staleIfError ) {
345
- return new CacheControl (this .maxAge , this .noCache , this .noStore , this .mustRevalidate , this .noTransform ,
346
- this .cachePublic , this .cachePrivate , this .proxyRevalidate , this .staleWhileRevalidate ,
347
- staleIfError , this .sMaxAge , this .immutable );
321
+ this .staleIfError = staleIfError ;
322
+ return this ;
348
323
}
349
324
350
325
/**
351
- * Return a new instance with an additional "immutable" directive.
326
+ * Add an "immutable" directive.
352
327
* <p>This directive indicates that the origin server will not update the
353
328
* representation of that resource during the freshness lifetime of the response.
354
329
* Adding a {@link #maxAge(Duration) max-age} directive is strongly advised
355
330
* to enforce the actual freshness lifetime.
356
- * @return a new CacheControl instance with an additional "immutable" directive
331
+ * @return {@code this}, to facilitate method chaining
357
332
* @since 6.0.5
358
333
* @see <a href="https://tools.ietf.org/html/rfc8246">rfc8246</a>
359
334
*/
360
335
public CacheControl immutable () {
361
- return new CacheControl (this .maxAge , this .noCache , this .noStore , this .mustRevalidate , this .noTransform ,
362
- this .cachePublic , this .cachePrivate , this .proxyRevalidate , this .staleWhileRevalidate ,
363
- this .staleIfError , this .sMaxAge , true );
336
+ this .immutable = true ;
337
+ return this ;
364
338
}
365
339
366
340
/**
0 commit comments