1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.client5.http.impl.cache;
28
29 import java.time.Instant;
30 import java.util.Random;
31
32 import org.apache.hc.client5.http.auth.StandardAuthScheme;
33 import org.apache.hc.client5.http.classic.methods.HttpOptions;
34 import org.apache.hc.client5.http.utils.DateUtils;
35 import org.apache.hc.core5.http.HttpRequest;
36 import org.apache.hc.core5.http.HttpResponse;
37 import org.apache.hc.core5.http.HttpStatus;
38 import org.apache.hc.core5.http.HttpVersion;
39 import org.apache.hc.core5.http.ProtocolVersion;
40 import org.apache.hc.core5.http.message.BasicHttpRequest;
41 import org.apache.hc.core5.http.message.BasicHttpResponse;
42 import org.junit.jupiter.api.Assertions;
43 import org.junit.jupiter.api.BeforeEach;
44 import org.junit.jupiter.api.Test;
45
46 public class TestResponseCachingPolicy {
47
48 private static final ProtocolVersion HTTP_1_1 = new ProtocolVersion("HTTP", 1, 1);
49 private ResponseCachingPolicy policy;
50 private HttpResponse response;
51 private HttpRequest request;
52 private final int[] acceptableCodes = new int[] { HttpStatus.SC_OK,
53 HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION, HttpStatus.SC_MULTIPLE_CHOICES,
54 HttpStatus.SC_MOVED_PERMANENTLY, HttpStatus.SC_GONE };
55 private Instant now;
56 private Instant tenSecondsFromNow;
57 private Instant sixSecondsAgo;
58
59 @BeforeEach
60 public void setUp() throws Exception {
61 now = Instant.now();
62 sixSecondsAgo = now.minusSeconds(6);
63 tenSecondsFromNow = now.plusSeconds(10);
64
65 policy = new ResponseCachingPolicy(0, true, false, false);
66 request = new BasicHttpRequest("GET","/");
67 response = new BasicHttpResponse(HttpStatus.SC_OK, "");
68 response.setHeader("Date", DateUtils.formatStandardDate(Instant.now()));
69 response.setHeader("Content-Length", "0");
70 }
71
72 @Test
73 public void testIsGetCacheable() {
74 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
75 }
76
77 @Test
78 public void testIsHeadCacheable() {
79 policy = new ResponseCachingPolicy(0, true, false, false);
80 Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
81 }
82
83 @Test
84 public void testResponsesToRequestsWithAuthorizationHeadersAreNotCacheableBySharedCache() {
85 request = new BasicHttpRequest("GET","/");
86 request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
87 Assertions.assertFalse(policy.isResponseCacheable(request,response));
88 }
89
90 @Test
91 public void testResponsesToRequestsWithAuthorizationHeadersAreCacheableByNonSharedCache() {
92 policy = new ResponseCachingPolicy(0, false, false, false);
93 request = new BasicHttpRequest("GET","/");
94 request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
95 Assertions.assertTrue(policy.isResponseCacheable(request,response));
96 }
97
98 @Test
99 public void testAuthorizedResponsesWithSMaxAgeAreCacheable() {
100 request = new BasicHttpRequest("GET","/");
101 request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
102 response.setHeader("Cache-Control","s-maxage=3600");
103 Assertions.assertTrue(policy.isResponseCacheable(request,response));
104 }
105
106 @Test
107 public void testAuthorizedResponsesWithMustRevalidateAreCacheable() {
108 request = new BasicHttpRequest("GET","/");
109 request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
110 response.setHeader("Cache-Control","must-revalidate");
111 Assertions.assertTrue(policy.isResponseCacheable(request,response));
112 }
113
114 @Test
115 public void testAuthorizedResponsesWithCacheControlPublicAreCacheable() {
116 request = new BasicHttpRequest("GET","/");
117 request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
118 response.setHeader("Cache-Control","public");
119 Assertions.assertTrue(policy.isResponseCacheable(request,response));
120 }
121
122 @Test
123 public void testAuthorizedResponsesWithCacheControlMaxAgeAreNotCacheable() {
124 request = new BasicHttpRequest("GET","/");
125 request.setHeader("Authorization", StandardAuthScheme.BASIC + " dXNlcjpwYXNzd2Q=");
126 response.setHeader("Cache-Control","max-age=3600");
127 Assertions.assertFalse(policy.isResponseCacheable(request,response));
128 }
129
130 @Test
131 public void test203ResponseCodeIsCacheable() {
132 response.setCode(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION);
133 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
134 }
135
136 @Test
137 public void test206ResponseCodeIsNotCacheable() {
138 response.setCode(HttpStatus.SC_PARTIAL_CONTENT);
139 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
140 }
141
142 @Test
143 public void test206ResponseCodeIsNotCacheableUsingSharedPublicCache() {
144 policy = new ResponseCachingPolicy(0, true, false, false);
145
146 request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
147 response.setCode(HttpStatus.SC_PARTIAL_CONTENT);
148 response.setHeader("Cache-Control", "public");
149 Assertions.assertFalse(policy.isResponseCacheable(request, response));
150 }
151
152 @Test
153 public void test300ResponseCodeIsCacheable() {
154 response.setCode(HttpStatus.SC_MULTIPLE_CHOICES);
155 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
156 }
157
158 @Test
159 public void test301ResponseCodeIsCacheable() {
160 response.setCode(HttpStatus.SC_MOVED_PERMANENTLY);
161 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
162 }
163
164 @Test
165 public void test410ResponseCodeIsCacheable() {
166 response.setCode(HttpStatus.SC_GONE);
167 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
168 }
169
170 @Test
171 public void testPlain302ResponseCodeIsNotCacheable() {
172 response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
173 response.removeHeaders("Expires");
174 response.removeHeaders("Cache-Control");
175 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
176 }
177
178 @Test
179 public void testPlain303ResponseCodeIsNotCacheableUnderDefaultBehavior() {
180 response.setCode(HttpStatus.SC_SEE_OTHER);
181 response.removeHeaders("Expires");
182 response.removeHeaders("Cache-Control");
183 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
184 }
185
186 @Test
187 public void testPlain303ResponseCodeIsNotCacheableEvenIf303CachingEnabled() {
188 policy = new ResponseCachingPolicy(0, true, false, true);
189 response.setCode(HttpStatus.SC_SEE_OTHER);
190 response.removeHeaders("Expires");
191 response.removeHeaders("Cache-Control");
192 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
193 }
194
195
196 @Test
197 public void testPlain307ResponseCodeIsNotCacheable() {
198 response.setCode(HttpStatus.SC_TEMPORARY_REDIRECT);
199 response.removeHeaders("Expires");
200 response.removeHeaders("Cache-Control");
201 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
202 }
203
204 @Test
205 public void testNon206WithExplicitExpiresIsCacheable() {
206 final int status = getRandomStatus();
207 response.setCode(status);
208 response.setHeader("Expires", DateUtils.formatStandardDate(Instant.now()));
209 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
210 }
211
212 @Test
213 public void testNon206WithMaxAgeIsCacheable() {
214 final int status = getRandomStatus();
215 response.setCode(status);
216 response.setHeader("Cache-Control", "max-age=0");
217 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
218 }
219
220 @Test
221 public void testNon206WithSMaxAgeIsCacheable() {
222 final int status = getRandomStatus();
223 response.setCode(status);
224 response.setHeader("Cache-Control", "s-maxage=0");
225 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
226 }
227
228 @Test
229 public void testNon206WithMustRevalidateIsCacheable() {
230 final int status = getRandomStatus();
231 response.setCode(status);
232 response.setHeader("Cache-Control", "must-revalidate");
233 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
234 }
235
236 @Test
237 public void testNon206WithProxyRevalidateIsCacheable() {
238 final int status = getRandomStatus();
239 response.setCode(status);
240 response.setHeader("Cache-Control", "proxy-revalidate");
241 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
242 }
243
244 @Test
245 public void testNon206WithPublicCacheControlIsCacheable() {
246 final int status = getRandomStatus();
247 response.setCode(status);
248 response.setHeader("Cache-Control", "public");
249 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
250 }
251
252 @Test
253 public void testNon206WithPrivateCacheControlIsNotCacheableBySharedCache() {
254 final int status = getRandomStatus();
255 response.setCode(status);
256 response.setHeader("Cache-Control", "private");
257 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
258 }
259
260 @Test
261 public void test200ResponseWithPrivateCacheControlIsCacheableByNonSharedCache() {
262 policy = new ResponseCachingPolicy(0, false, false, false);
263 response.setCode(HttpStatus.SC_OK);
264 response.setHeader("Cache-Control", "private");
265 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
266 }
267
268 @Test
269 public void testIsGetWithNoCacheCacheable() {
270 response.addHeader("Cache-Control", "no-cache");
271
272 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
273 }
274
275 @Test
276 public void testIsHeadWithNoCacheCacheable() {
277 response.addHeader("Cache-Control", "no-cache");
278
279 Assertions.assertFalse(policy.isResponseCacheable("HEAD", response));
280 }
281
282 @Test
283 public void testIsGetWithNoStoreCacheable() {
284 response.addHeader("Cache-Control", "no-store");
285
286 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
287 }
288
289 @Test
290 public void testIsHeadWithNoStoreCacheable() {
291 response.addHeader("Cache-Control", "no-store");
292
293 Assertions.assertFalse(policy.isResponseCacheable("HEAD", response));
294 }
295
296 @Test
297 public void testIsGetWithNoStoreEmbeddedInListCacheable() {
298 response.addHeader("Cache-Control", "public, no-store");
299
300 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
301 }
302
303 @Test
304 public void testIsHeadWithNoStoreEmbeddedInListCacheable() {
305 response.addHeader("Cache-Control", "public, no-store");
306
307 Assertions.assertFalse(policy.isResponseCacheable("HEAD", response));
308 }
309
310 @Test
311 public void testIsGetWithNoCacheEmbeddedInListCacheable() {
312 response.addHeader("Cache-Control", "public, no-cache");
313
314 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
315 }
316
317 @Test
318 public void testIsHeadWithNoCacheEmbeddedInListCacheable() {
319 response.addHeader("Cache-Control", "public, no-cache");
320
321 Assertions.assertFalse(policy.isResponseCacheable("HEAD", response));
322 }
323
324 @Test
325 public void testIsGetWithNoCacheEmbeddedInListAfterFirstHeaderCacheable() {
326 response.addHeader("Cache-Control", "max-age=20");
327 response.addHeader("Cache-Control", "public, no-cache");
328
329 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
330 }
331
332 @Test
333 public void testIsHeadWithNoCacheEmbeddedInListAfterFirstHeaderCacheable() {
334 response.addHeader("Cache-Control", "max-age=20");
335 response.addHeader("Cache-Control", "public, no-cache");
336
337 Assertions.assertFalse(policy.isResponseCacheable("HEAD", response));
338 }
339
340 @Test
341 public void testIsGetWithNoStoreEmbeddedInListAfterFirstHeaderCacheable() {
342 response.addHeader("Cache-Control", "max-age=20");
343 response.addHeader("Cache-Control", "public, no-store");
344
345 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
346 }
347
348 @Test
349 public void testIsHeadWithNoStoreEmbeddedInListAfterFirstHeaderCacheable() {
350 response.addHeader("Cache-Control", "max-age=20");
351 response.addHeader("Cache-Control", "public, no-store");
352
353 Assertions.assertFalse(policy.isResponseCacheable("HEAD", response));
354 }
355
356 @Test
357 public void testIsGetWithAnyCacheControlCacheable() {
358 response.addHeader("Cache-Control", "max=10");
359
360 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
361
362 response = new BasicHttpResponse(HttpStatus.SC_OK, "");
363 response.setHeader("Date", DateUtils.formatStandardDate(Instant.now()));
364 response.addHeader("Cache-Control", "no-transform");
365 response.setHeader("Content-Length", "0");
366
367 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
368 }
369
370 @Test
371 public void testIsHeadWithAnyCacheControlCacheable() {
372 policy = new ResponseCachingPolicy(0, true, false, false);
373 response.addHeader("Cache-Control", "max=10");
374
375 Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
376
377 response = new BasicHttpResponse(HttpStatus.SC_OK, "");
378 response.setHeader("Date", DateUtils.formatStandardDate(Instant.now()));
379 response.addHeader("Cache-Control", "no-transform");
380 response.setHeader("Content-Length", "0");
381
382 Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
383 }
384
385 @Test
386 public void testIsGetWithout200Cacheable() {
387 HttpResponse response404 = new BasicHttpResponse(HttpStatus.SC_NOT_FOUND, "");
388
389 Assertions.assertFalse(policy.isResponseCacheable("GET", response404));
390
391 response404 = new BasicHttpResponse(HttpStatus.SC_GATEWAY_TIMEOUT, "");
392
393 Assertions.assertFalse(policy.isResponseCacheable("GET", response404));
394 }
395
396 @Test
397 public void testIsHeadWithout200Cacheable() {
398 HttpResponse response404 = new BasicHttpResponse(HttpStatus.SC_NOT_FOUND, "");
399
400 Assertions.assertFalse(policy.isResponseCacheable("HEAD", response404));
401
402 response404 = new BasicHttpResponse(HttpStatus.SC_GATEWAY_TIMEOUT, "");
403
404 Assertions.assertFalse(policy.isResponseCacheable("HEAD", response404));
405 }
406
407 @Test
408 public void testVaryStarIsNotCacheable() {
409 response.setHeader("Vary", "*");
410 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
411 }
412
413 @Test
414 public void testVaryStarIsNotCacheableUsingSharedPublicCache() {
415 policy = new ResponseCachingPolicy(0, true, false, false);
416
417 request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
418 response.setHeader("Cache-Control", "public");
419 response.setHeader("Vary", "*");
420 Assertions.assertFalse(policy.isResponseCacheable(request, response));
421 }
422
423 @Test
424 public void testIsGetWithVaryHeaderCacheable() {
425 response.addHeader("Vary", "Accept-Encoding");
426 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
427 }
428
429 @Test
430 public void testIsHeadWithVaryHeaderCacheable() {
431 policy = new ResponseCachingPolicy(0, true, false, false);
432 response.addHeader("Vary", "Accept-Encoding");
433 Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
434 }
435
436 @Test
437 public void testIsArbitraryMethodCacheable() {
438
439 Assertions.assertFalse(policy.isResponseCacheable("PUT", response));
440
441 Assertions.assertFalse(policy.isResponseCacheable("get", response));
442 }
443
444 @Test
445 public void testIsArbitraryMethodCacheableUsingSharedPublicCache() {
446 policy = new ResponseCachingPolicy(0, true, false, false);
447
448 request = new HttpOptions("http://foo.example.com/");
449 request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
450 response.setCode(HttpStatus.SC_NO_CONTENT);
451 response.setHeader("Cache-Control", "public");
452
453 Assertions.assertFalse(policy.isResponseCacheable(request, response));
454 }
455
456 @Test
457 public void testResponsesToRequestsWithNoStoreAreNotCacheable() {
458 request.setHeader("Cache-Control","no-store");
459 response.setHeader("Cache-Control","public");
460 Assertions.assertFalse(policy.isResponseCacheable(request,response));
461 }
462
463 @Test
464 public void testResponsesWithMultipleAgeHeadersAreNotCacheable() {
465 response.addHeader("Age", "3");
466 response.addHeader("Age", "5");
467 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
468 }
469
470 @Test
471 public void testResponsesWithMultipleAgeHeadersAreNotCacheableUsingSharedPublicCache() {
472 policy = new ResponseCachingPolicy(0, true, false, false);
473
474 request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
475 response.setHeader("Cache-Control", "public");
476 response.addHeader("Age", "3");
477 response.addHeader("Age", "5");
478 Assertions.assertFalse(policy.isResponseCacheable(request, response));
479 }
480
481 @Test
482 public void testResponsesWithMultipleDateHeadersAreNotCacheable() {
483 response.addHeader("Date", DateUtils.formatStandardDate(now));
484 response.addHeader("Date", DateUtils.formatStandardDate(sixSecondsAgo));
485 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
486 }
487
488 @Test
489 public void testResponsesWithMultipleDateHeadersAreNotCacheableUsingSharedPublicCache() {
490 policy = new ResponseCachingPolicy(0, true, false, false);
491
492 request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
493 response.setHeader("Cache-Control", "public");
494 response.addHeader("Date", DateUtils.formatStandardDate(now));
495 response.addHeader("Date", DateUtils.formatStandardDate(sixSecondsAgo));
496 Assertions.assertFalse(policy.isResponseCacheable(request, response));
497 }
498
499 @Test
500 public void testResponsesWithMalformedDateHeadersAreNotCacheable() {
501 response.addHeader("Date", "garbage");
502 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
503 }
504
505 @Test
506 public void testResponsesWithMalformedDateHeadersAreNotCacheableUsingSharedPublicCache() {
507 policy = new ResponseCachingPolicy(0, true, false, false);
508
509 request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
510 response.setHeader("Cache-Control", "public");
511 response.addHeader("Date", "garbage");
512 Assertions.assertFalse(policy.isResponseCacheable(request, response));
513 }
514
515 @Test
516 public void testResponsesWithMultipleExpiresHeadersAreNotCacheable() {
517 response.addHeader("Expires", DateUtils.formatStandardDate(now));
518 response.addHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo));
519 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
520 }
521
522 @Test
523 public void testResponsesWithMultipleExpiresHeadersAreNotCacheableUsingSharedPublicCache() {
524 policy = new ResponseCachingPolicy(0, true, false, false);
525
526 request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
527 response.setHeader("Cache-Control", "public");
528 response.addHeader("Expires", DateUtils.formatStandardDate(now));
529 response.addHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo));
530 Assertions.assertFalse(policy.isResponseCacheable(request, response));
531 }
532
533 @Test
534 public void testResponsesWithoutDateHeadersAreNotCacheable() {
535 response.removeHeaders("Date");
536 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
537 }
538
539 @Test
540 public void testResponseThatHasTooMuchContentIsNotCacheable() {
541 response.setHeader("Content-Length", "9000");
542 Assertions.assertFalse(policy.isResponseCacheable("GET", response));
543 }
544
545 @Test
546 public void testResponseThatHasTooMuchContentIsNotCacheableUsingSharedPublicCache() {
547 policy = new ResponseCachingPolicy(0, true, false, false);
548
549 request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
550 response.setHeader("Cache-Control", "public");
551 response.setHeader("Content-Length", "9000");
552 Assertions.assertFalse(policy.isResponseCacheable(request, response));
553 }
554
555 @Test
556 public void testResponsesThatAreSmallEnoughAreCacheable() {
557 response.setHeader("Content-Length", "0");
558 Assertions.assertTrue(policy.isResponseCacheable("GET", response));
559 }
560
561 @Test
562 public void testResponsesToGETWithQueryParamsButNoExplicitCachingAreNotCacheable() {
563 request = new BasicHttpRequest("GET", "/foo?s=bar");
564 Assertions.assertFalse(policy.isResponseCacheable(request, response));
565 }
566
567 @Test
568 public void testResponsesToHEADWithQueryParamsButNoExplicitCachingAreNotCacheable() {
569 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
570 Assertions.assertFalse(policy.isResponseCacheable(request, response));
571 }
572
573 @Test
574 public void testResponsesToGETWithQueryParamsButNoExplicitCachingAreNotCacheableEvenWhen1_0QueryCachingDisabled() {
575 policy = new ResponseCachingPolicy(0, true, true, false);
576 request = new BasicHttpRequest("GET", "/foo?s=bar");
577 Assertions.assertFalse(policy.isResponseCacheable(request, response));
578 }
579
580 @Test
581 public void testResponsesToHEADWithQueryParamsButNoExplicitCachingAreNotCacheableEvenWhen1_0QueryCachingDisabled() {
582 policy = new ResponseCachingPolicy(0, true, true, false);
583 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
584 Assertions.assertFalse(policy.isResponseCacheable(request, response));
585 }
586
587 @Test
588 public void testResponsesToGETWithQueryParamsAndExplicitCachingAreCacheable() {
589 request = new BasicHttpRequest("GET", "/foo?s=bar");
590 response.setHeader("Date", DateUtils.formatStandardDate(now));
591 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
592 Assertions.assertTrue(policy.isResponseCacheable(request, response));
593 }
594
595 @Test
596 public void testResponsesToHEADWithQueryParamsAndExplicitCachingAreCacheable() {
597 policy = new ResponseCachingPolicy(0, true, false, false);
598 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
599 response.setHeader("Date", DateUtils.formatStandardDate(now));
600 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
601 Assertions.assertTrue(policy.isResponseCacheable(request, response));
602 }
603
604 @Test
605 public void testResponsesToGETWithQueryParamsAndExplicitCachingAreCacheableEvenWhen1_0QueryCachingDisabled() {
606 policy = new ResponseCachingPolicy(0, true, true, false);
607 request = new BasicHttpRequest("GET", "/foo?s=bar");
608 response.setHeader("Date", DateUtils.formatStandardDate(now));
609 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
610 Assertions.assertTrue(policy.isResponseCacheable(request, response));
611 }
612
613 @Test
614 public void testResponsesToHEADWithQueryParamsAndExplicitCachingAreCacheableEvenWhen1_0QueryCachingDisabled() {
615 policy = new ResponseCachingPolicy(0, true, true, false);
616 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
617 response.setHeader("Date", DateUtils.formatStandardDate(now));
618 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
619 Assertions.assertTrue(policy.isResponseCacheable(request, response));
620 }
621
622 @Test
623 public void getsWithQueryParametersDirectlyFrom1_0OriginsAreNotCacheable() {
624 request = new BasicHttpRequest("GET", "/foo?s=bar");
625 response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
626 response.setVersion(HttpVersion.HTTP_1_0);
627 Assertions.assertFalse(policy.isResponseCacheable(request, response));
628 }
629
630 @Test
631 public void headsWithQueryParametersDirectlyFrom1_0OriginsAreNotCacheable() {
632 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
633 response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
634 response.setVersion(HttpVersion.HTTP_1_0);
635 Assertions.assertFalse(policy.isResponseCacheable(request, response));
636 }
637
638 @Test
639 public void getsWithQueryParametersDirectlyFrom1_0OriginsAreNotCacheableEvenWithSetting() {
640 policy = new ResponseCachingPolicy(0, true, true, false);
641 request = new BasicHttpRequest("GET", "/foo?s=bar");
642 response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
643 response.setVersion(HttpVersion.HTTP_1_0);
644 Assertions.assertFalse(policy.isResponseCacheable(request, response));
645 }
646
647 @Test
648 public void headsWithQueryParametersDirectlyFrom1_0OriginsAreNotCacheableEvenWithSetting() {
649 policy = new ResponseCachingPolicy(0, true, true, false);
650 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
651 response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
652 response.setVersion(HttpVersion.HTTP_1_0);
653 Assertions.assertFalse(policy.isResponseCacheable(request, response));
654 }
655
656 @Test
657 public void getsWithQueryParametersDirectlyFrom1_0OriginsAreCacheableWithExpires() {
658 request = new BasicHttpRequest("GET", "/foo?s=bar");
659 response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
660 response.setVersion(HttpVersion.HTTP_1_0);
661 response.setHeader("Date", DateUtils.formatStandardDate(now));
662 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
663 Assertions.assertTrue(policy.isResponseCacheable(request, response));
664 }
665
666 @Test
667 public void headsWithQueryParametersDirectlyFrom1_0OriginsAreCacheableWithExpires() {
668 policy = new ResponseCachingPolicy(0, true, false, false);
669 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
670 response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
671 response.setVersion(HttpVersion.HTTP_1_0);
672 response.setHeader("Date", DateUtils.formatStandardDate(now));
673 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
674 Assertions.assertTrue(policy.isResponseCacheable(request, response));
675 }
676
677 @Test
678 public void getsWithQueryParametersDirectlyFrom1_0OriginsCanBeNotCacheableEvenWithExpires() {
679 policy = new ResponseCachingPolicy(0, true, true, false);
680 request = new BasicHttpRequest("GET", "/foo?s=bar");
681 response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
682 response.setVersion(HttpVersion.HTTP_1_0);
683 response.setHeader("Date", DateUtils.formatStandardDate(now));
684 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
685 Assertions.assertFalse(policy.isResponseCacheable(request, response));
686 }
687
688 @Test
689 public void headsWithQueryParametersDirectlyFrom1_0OriginsCanBeNotCacheableEvenWithExpires() {
690 policy = new ResponseCachingPolicy(0, true, true, false);
691 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
692 response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
693 response.setVersion(HttpVersion.HTTP_1_0);
694 response.setHeader("Date", DateUtils.formatStandardDate(now));
695 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
696 Assertions.assertFalse(policy.isResponseCacheable(request, response));
697 }
698
699 @Test
700 public void getsWithQueryParametersFrom1_0OriginsViaProxiesAreNotCacheable() {
701 request = new BasicHttpRequest("GET", "/foo?s=bar");
702 response.setHeader("Via", "1.0 someproxy");
703 Assertions.assertFalse(policy.isResponseCacheable(request, response));
704 }
705
706 @Test
707 public void headsWithQueryParametersFrom1_0OriginsViaProxiesAreNotCacheable() {
708 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
709 response.setHeader("Via", "1.0 someproxy");
710 Assertions.assertFalse(policy.isResponseCacheable(request, response));
711 }
712
713 @Test
714 public void getsWithQueryParametersFrom1_0OriginsViaProxiesAreCacheableWithExpires() {
715 request = new BasicHttpRequest("GET", "/foo?s=bar");
716 response.setHeader("Date", DateUtils.formatStandardDate(now));
717 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
718 response.setHeader("Via", "1.0 someproxy");
719 Assertions.assertTrue(policy.isResponseCacheable(request, response));
720 }
721
722 @Test
723 public void headsWithQueryParametersFrom1_0OriginsViaProxiesAreCacheableWithExpires() {
724 policy = new ResponseCachingPolicy(0, true, false, false);
725 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
726 response.setHeader("Date", DateUtils.formatStandardDate(now));
727 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
728 response.setHeader("Via", "1.0 someproxy");
729 Assertions.assertTrue(policy.isResponseCacheable(request, response));
730 }
731
732 @Test
733 public void getsWithQueryParametersFrom1_0OriginsViaProxiesCanNotBeCacheableEvenWithExpires() {
734 policy = new ResponseCachingPolicy(0, true, true, true);
735 request = new BasicHttpRequest("GET", "/foo?s=bar");
736 response.setHeader("Date", DateUtils.formatStandardDate(now));
737 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
738 response.setHeader("Via", "1.0 someproxy");
739 Assertions.assertFalse(policy.isResponseCacheable(request, response));
740 }
741
742 @Test
743 public void headsWithQueryParametersFrom1_0OriginsViaProxiesCanNotBeCacheableEvenWithExpires() {
744 policy = new ResponseCachingPolicy(0, true, true, true);
745 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
746 response.setHeader("Date", DateUtils.formatStandardDate(now));
747 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
748 response.setHeader("Via", "1.0 someproxy");
749 Assertions.assertFalse(policy.isResponseCacheable(request, response));
750 }
751
752 @Test
753 public void getsWithQueryParametersFrom1_0OriginsViaExplicitProxiesAreCacheableWithExpires() {
754 request = new BasicHttpRequest("GET", "/foo?s=bar");
755 response.setHeader("Date", DateUtils.formatStandardDate(now));
756 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
757 response.setHeader("Via", "HTTP/1.0 someproxy");
758 Assertions.assertTrue(policy.isResponseCacheable(request, response));
759 }
760
761 @Test
762 public void headsWithQueryParametersFrom1_0OriginsViaExplicitProxiesAreCacheableWithExpires() {
763 policy = new ResponseCachingPolicy(0, true, false, false);
764 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
765 response.setHeader("Date", DateUtils.formatStandardDate(now));
766 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
767 response.setHeader("Via", "HTTP/1.0 someproxy");
768 Assertions.assertTrue(policy.isResponseCacheable(request, response));
769 }
770
771 @Test
772 public void getsWithQueryParametersFrom1_0OriginsViaExplicitProxiesCanNotBeCacheableEvenWithExpires() {
773 policy = new ResponseCachingPolicy(0, true, true, true);
774 request = new BasicHttpRequest("GET", "/foo?s=bar");
775 response.setHeader("Date", DateUtils.formatStandardDate(now));
776 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
777 response.setHeader("Via", "HTTP/1.0 someproxy");
778 Assertions.assertFalse(policy.isResponseCacheable(request, response));
779 }
780
781 @Test
782 public void headsWithQueryParametersFrom1_0OriginsViaExplicitProxiesCanNotBeCacheableEvenWithExpires() {
783 policy = new ResponseCachingPolicy(0, true, true, true);
784 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
785 response.setHeader("Date", DateUtils.formatStandardDate(now));
786 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
787 response.setHeader("Via", "HTTP/1.0 someproxy");
788 Assertions.assertFalse(policy.isResponseCacheable(request, response));
789 }
790
791 @Test
792 public void getsWithQueryParametersFrom1_1OriginsVia1_0ProxiesAreCacheableWithExpires() {
793 request = new BasicHttpRequest("GET", "/foo?s=bar");
794 response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
795 response.setVersion(HttpVersion.HTTP_1_0);
796 response.setHeader("Date", DateUtils.formatStandardDate(now));
797 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
798 response.setHeader("Via", "1.1 someproxy");
799 Assertions.assertTrue(policy.isResponseCacheable(request, response));
800 }
801
802 @Test
803 public void headsWithQueryParametersFrom1_1OriginsVia1_0ProxiesAreCacheableWithExpires() {
804 policy = new ResponseCachingPolicy(0, true, false, false);
805 request = new BasicHttpRequest("HEAD", "/foo?s=bar");
806 response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
807 response.setVersion(HttpVersion.HTTP_1_0);
808 response.setHeader("Date", DateUtils.formatStandardDate(now));
809 response.setHeader("Expires", DateUtils.formatStandardDate(tenSecondsFromNow));
810 response.setHeader("Via", "1.1 someproxy");
811 Assertions.assertTrue(policy.isResponseCacheable(request, response));
812 }
813
814 @Test
815 public void notCacheableIfExpiresEqualsDateAndNoCacheControl() {
816 response.setHeader("Date", DateUtils.formatStandardDate(now));
817 response.setHeader("Expires", DateUtils.formatStandardDate(now));
818 response.removeHeaders("Cache-Control");
819 Assertions.assertFalse(policy.isResponseCacheable(request, response));
820 }
821
822 @Test
823 public void notCacheableIfExpiresPrecedesDateAndNoCacheControl() {
824 response.setHeader("Date", DateUtils.formatStandardDate(now));
825 response.setHeader("Expires", DateUtils.formatStandardDate(sixSecondsAgo));
826 response.removeHeaders("Cache-Control");
827 Assertions.assertFalse(policy.isResponseCacheable(request, response));
828 }
829
830 @Test
831 public void test302WithExplicitCachingHeaders() {
832 response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
833 response.setHeader("Date", DateUtils.formatStandardDate(now));
834 response.setHeader("Cache-Control","max-age=300");
835 Assertions.assertTrue(policy.isResponseCacheable(request, response));
836 }
837
838 @Test
839 public void test303WithExplicitCachingHeadersUnderDefaultBehavior() {
840
841 response.setCode(HttpStatus.SC_SEE_OTHER);
842 response.setHeader("Date", DateUtils.formatStandardDate(now));
843 response.setHeader("Cache-Control","max-age=300");
844 Assertions.assertFalse(policy.isResponseCacheable(request, response));
845 }
846
847 @Test
848 public void test303WithExplicitCachingHeadersWhenPermittedByConfig() {
849
850
851 policy = new ResponseCachingPolicy(0, true, false, true);
852 response.setCode(HttpStatus.SC_SEE_OTHER);
853 response.setHeader("Date", DateUtils.formatStandardDate(now));
854 response.setHeader("Cache-Control","max-age=300");
855 Assertions.assertTrue(policy.isResponseCacheable(request, response));
856 }
857
858 @Test
859 public void test307WithExplicitCachingHeaders() {
860 response.setCode(HttpStatus.SC_TEMPORARY_REDIRECT);
861 response.setHeader("Date", DateUtils.formatStandardDate(now));
862 response.setHeader("Cache-Control","max-age=300");
863 Assertions.assertTrue(policy.isResponseCacheable(request, response));
864 }
865
866 @Test
867 public void otherStatusCodesAreCacheableWithExplicitCachingHeaders() {
868 response.setCode(HttpStatus.SC_NOT_FOUND);
869 response.setHeader("Date", DateUtils.formatStandardDate(now));
870 response.setHeader("Cache-Control","max-age=300");
871 Assertions.assertTrue(policy.isResponseCacheable(request, response));
872 }
873
874 private int getRandomStatus() {
875 final int rnd = new Random().nextInt(acceptableCodes.length);
876
877 return acceptableCodes[rnd];
878 }
879 }