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 static org.junit.jupiter.api.Assertions.assertAll;
30 import static org.junit.jupiter.api.Assertions.assertEquals;
31 import static org.junit.jupiter.api.Assertions.assertThrows;
32 import static org.junit.jupiter.api.Assertions.assertTrue;
33
34 import java.util.Arrays;
35 import java.util.Collections;
36
37 import org.apache.hc.client5.http.cache.RequestCacheControl;
38 import org.apache.hc.client5.http.cache.ResponseCacheControl;
39 import org.apache.hc.core5.http.Header;
40 import org.apache.hc.core5.http.message.BasicHeader;
41 import org.junit.jupiter.api.Test;
42
43 class CacheControlParserTest {
44
45 private final CacheControlHeaderParser parser = CacheControlHeaderParser.INSTANCE;
46
47 @Test
48 void testParseMaxAgeZero() {
49 final Header header = new BasicHeader("Cache-Control", "max-age=0 , this = stuff;");
50 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
51 assertEquals(0L, cacheControl.getMaxAge());
52 }
53
54 @Test
55 void testParseSMaxAge() {
56 final Header header = new BasicHeader("Cache-Control", "s-maxage=3600");
57 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
58 assertEquals(3600L, cacheControl.getSharedMaxAge());
59 }
60
61 @Test
62 void testParseInvalidCacheValue() {
63 final Header header = new BasicHeader("Cache-Control", "max-age=invalid");
64 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
65 assertEquals(0L, cacheControl.getMaxAge());
66 }
67
68 @Test
69 void testParseInvalidHeader() {
70 final Header header = new BasicHeader("Cache-Control", "max-age");
71 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
72 assertEquals(-1L, cacheControl.getMaxAge());
73 }
74
75 @Test
76 void testParseNullHeader() {
77 final Header header = null;
78 assertThrows(NullPointerException.class, () -> parser.parseResponse(Collections.singletonList(header).iterator()));
79 }
80
81 @Test
82 void testParseEmptyHeader() {
83 final Header header = new BasicHeader("Cache-Control", "");
84 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
85 assertEquals(-1L, cacheControl.getMaxAge());
86 }
87
88 @Test
89 void testParseCookieEmptyValue() {
90 final Header header = new BasicHeader("Cache-Control", "max-age=,");
91 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
92 assertEquals(-1L, cacheControl.getMaxAge());
93 }
94
95 @Test
96 void testParseNoCache() {
97 final Header header = new BasicHeader(" Cache-Control", "no-cache");
98 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
99 assertEquals(-1L, cacheControl.getMaxAge());
100 }
101
102 @Test
103 void testParseNoDirective() {
104 final Header header = new BasicHeader(" Cache-Control", "");
105 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
106 assertEquals(-1L, cacheControl.getMaxAge());
107 }
108
109 @Test
110 void testGarbage() {
111 final Header header = new BasicHeader("Cache-Control", ",,= blah,");
112 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
113 assertEquals(-1L, cacheControl.getMaxAge());
114 }
115
116
117 @Test
118 void testParseMultipleDirectives() {
119 final Header header = new BasicHeader("Cache-Control", "max-age=604800, stale-while-revalidate=86400, s-maxage=3600, must-revalidate, private");
120 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
121
122 assertAll("Must all pass",
123 () -> assertEquals(604800L, cacheControl.getMaxAge()),
124 () -> assertEquals(3600L, cacheControl.getSharedMaxAge()),
125 () -> assertTrue(cacheControl.isMustRevalidate()),
126 () -> assertTrue(cacheControl.isCachePrivate())
127 );
128 }
129
130 @Test
131 void testParseMultipleDirectives2() {
132 final Header header = new BasicHeader("Cache-Control", "max-age=604800, stale-while-revalidate=86400, must-revalidate, private, s-maxage=3600");
133 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
134
135 assertAll("Must all pass",
136 () -> assertEquals(604800L, cacheControl.getMaxAge()),
137 () -> assertEquals(3600L, cacheControl.getSharedMaxAge()),
138 () -> assertTrue(cacheControl.isMustRevalidate()),
139 () -> assertTrue(cacheControl.isCachePrivate())
140 );
141 }
142
143 @Test
144 void testParsePublic() {
145 final Header header = new BasicHeader("Cache-Control", "public");
146 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
147
148 assertTrue(cacheControl.isPublic());
149 }
150
151 @Test
152 void testParsePrivate() {
153 final Header header = new BasicHeader("Cache-Control", "private");
154 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
155
156 assertTrue(cacheControl.isCachePrivate());
157 }
158
159 @Test
160 void testParseNoStore() {
161 final Header header = new BasicHeader("Cache-Control", "no-store");
162 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
163
164 assertTrue(cacheControl.isNoStore());
165 }
166
167 @Test
168 void testParseStaleWhileRevalidate() {
169 final Header header = new BasicHeader("Cache-Control", "max-age=3600, stale-while-revalidate=120");
170 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
171
172 assertEquals(120, cacheControl.getStaleWhileRevalidate());
173 }
174
175 @Test
176 void testParseNoCacheFields() {
177 final Header header = new BasicHeader("Cache-Control", "no-cache=\"Set-Cookie, Content-Language\", stale-while-revalidate=120");
178 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
179
180 assertTrue(cacheControl.isNoCache());
181 assertEquals(2, cacheControl.getNoCacheFields().size());
182 assertTrue(cacheControl.getNoCacheFields().contains("Set-Cookie"));
183 assertTrue(cacheControl.getNoCacheFields().contains("Content-Language"));
184 assertEquals(120, cacheControl.getStaleWhileRevalidate());
185 }
186
187 @Test
188 void testParseNoCacheFieldsNoQuote() {
189 final Header header = new BasicHeader("Cache-Control", "no-cache=Set-Cookie, Content-Language, stale-while-revalidate=120");
190 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
191
192 assertTrue(cacheControl.isNoCache());
193 assertEquals(1, cacheControl.getNoCacheFields().size());
194 assertTrue(cacheControl.getNoCacheFields().contains("Set-Cookie"));
195 assertEquals(120, cacheControl.getStaleWhileRevalidate());
196 }
197
198 @Test
199 void testParseNoCacheFieldsMessy() {
200 final Header header = new BasicHeader("Cache-Control", "no-cache=\" , , ,,, Set-Cookie , , Content-Language , \", stale-while-revalidate=120");
201 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
202
203 assertTrue(cacheControl.isNoCache());
204 assertEquals(2, cacheControl.getNoCacheFields().size());
205 assertTrue(cacheControl.getNoCacheFields().contains("Set-Cookie"));
206 assertTrue(cacheControl.getNoCacheFields().contains("Content-Language"));
207 assertEquals(120, cacheControl.getStaleWhileRevalidate());
208 }
209
210
211 @Test
212 void testParseMultipleHeaders() {
213
214 final Header header1 = new BasicHeader("Cache-Control", "max-age=3600, no-store");
215 final Header header2 = new BasicHeader("Cache-Control", "private, must-revalidate");
216 final Header header3 = new BasicHeader("Cache-Control", "max-age=3600");
217 final Header header4 = new BasicHeader("Cache-Control", "no-store");
218 final Header header5 = new BasicHeader("Cache-Control", "private");
219 final Header header6 = new BasicHeader("Cache-Control", "must-revalidate");
220
221
222 final ResponseCacheControl cacheControl1 = parser.parseResponse(Arrays.asList(header1, header2).iterator());
223 final ResponseCacheControl cacheControl2 = parser.parseResponse(Arrays.asList(header3, header4, header5, header6).iterator());
224
225
226 assertEquals(cacheControl1.getMaxAge(), cacheControl2.getMaxAge());
227 assertEquals(cacheControl1.isNoStore(), cacheControl2.isNoStore());
228 assertEquals(cacheControl1.isCachePrivate(), cacheControl2.isCachePrivate());
229 assertEquals(cacheControl1.isMustRevalidate(), cacheControl2.isMustRevalidate());
230 }
231
232 @Test
233 void testParseRequestMultipleDirectives() {
234 final Header header = new BasicHeader("Cache-Control", "blah, max-age=1111, max-stale=2222, " +
235 "min-fresh=3333, no-cache, no-store, no-cache, no-stuff, only-if-cached, only-if-cached-or-maybe-not");
236 final RequestCacheControl cacheControl = parser.parseRequest(Collections.singletonList(header).iterator());
237
238 assertAll("Must all pass",
239 () -> assertEquals(1111L, cacheControl.getMaxAge()),
240 () -> assertEquals(2222L, cacheControl.getMaxStale()),
241 () -> assertEquals(3333L, cacheControl.getMinFresh()),
242 () -> assertTrue(cacheControl.isNoCache()),
243 () -> assertTrue(cacheControl.isNoCache()),
244 () -> assertTrue(cacheControl.isOnlyIfCached())
245 );
246 }
247
248 @Test
249 void testParseIsImmutable() {
250 final Header header = new BasicHeader("Cache-Control", "max-age=0 , immutable");
251 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
252 assertTrue(cacheControl.isImmutable());
253 }
254
255 @Test
256 void testParseMultipleIsImmutable() {
257 final Header header = new BasicHeader("Cache-Control", "immutable, nmax-age=0 , immutable");
258 final ResponseCacheControl cacheControl = parser.parseResponse(Collections.singletonList(header).iterator());
259 assertTrue(cacheControl.isImmutable());
260 }
261
262 }