Refactor CacheControl parser to handle multiple headers.
This commit refactors the CacheControl parsing logic to handle multiple "Cache-Control" headers. The previous implementation treated each header independently, returning an array of CacheControl objects. This caused issues when headers had directives that should be combined into a single CacheControl object. The updated implementation combines all directives from all headers into a single CacheControl object, ensuring accurate representation of the caching directives.
This commit is contained in:
parent
cf7b582d6e
commit
46fe5a6a81
|
@ -28,6 +28,7 @@ package org.apache.hc.client5.http.impl.cache;
|
||||||
|
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.cache.HeaderConstants;
|
import org.apache.hc.client5.http.cache.HeaderConstants;
|
||||||
|
@ -50,7 +51,7 @@ import org.slf4j.LoggerFactory;
|
||||||
* This class is thread-safe and has a singleton instance ({@link #INSTANCE}).
|
* This class is thread-safe and has a singleton instance ({@link #INSTANCE}).
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* The {@link #parse(Header)} method takes an HTTP header and returns a {@link CacheControl} object containing
|
* The {@link #parse(Iterator)} method takes an HTTP header and returns a {@link CacheControl} object containing
|
||||||
* the relevant caching directives. The header can be either a {@link FormattedHeader} object, which contains a
|
* the relevant caching directives. The header can be either a {@link FormattedHeader} object, which contains a
|
||||||
* pre-parsed {@link CharArrayBuffer}, or a plain {@link Header} object, in which case the value will be parsed and
|
* pre-parsed {@link CharArrayBuffer}, or a plain {@link Header} object, in which case the value will be parsed and
|
||||||
* stored in a new {@link CharArrayBuffer}.
|
* stored in a new {@link CharArrayBuffer}.
|
||||||
|
@ -113,28 +114,14 @@ class CacheControlHeaderParser {
|
||||||
* <p>
|
* <p>
|
||||||
* "s-maxage" (-1).</p>
|
* "s-maxage" (-1).</p>
|
||||||
*
|
*
|
||||||
* @param header the header to parse, cannot be {@code null}
|
* @param headerIterator the header to parse, cannot be {@code null}
|
||||||
* @return a new {@link CacheControl} instance containing the relevant caching directives parsed from the header
|
* @return a new {@link CacheControl} instance containing the relevant caching directives parsed from the header
|
||||||
* @throws IllegalArgumentException if the input header is {@code null}
|
* @throws IllegalArgumentException if the input header is {@code null}
|
||||||
*/
|
*/
|
||||||
public final CacheControl parse(final Header header) {
|
public final CacheControl parse(final Iterator<Header> headerIterator) {
|
||||||
Args.notNull(header, "Header");
|
Args.notNull(headerIterator, "headerIterator");
|
||||||
|
|
||||||
final CharArrayBuffer buffer;
|
|
||||||
final Tokenizer.Cursor cursor;
|
|
||||||
if (header instanceof FormattedHeader) {
|
|
||||||
buffer = ((FormattedHeader) header).getBuffer();
|
|
||||||
cursor = new Tokenizer.Cursor(((FormattedHeader) header).getValuePos(), buffer.length());
|
|
||||||
} else {
|
|
||||||
final String s = header.getValue();
|
|
||||||
if (s == null) {
|
|
||||||
return new CacheControl();
|
|
||||||
}
|
|
||||||
buffer = new CharArrayBuffer(s.length());
|
|
||||||
buffer.append(s);
|
|
||||||
cursor = new Tokenizer.Cursor(0, buffer.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Initialize variables to hold the Cache-Control directives
|
||||||
long maxAge = -1;
|
long maxAge = -1;
|
||||||
long sharedMaxAge = -1;
|
long sharedMaxAge = -1;
|
||||||
boolean noCache = false;
|
boolean noCache = false;
|
||||||
|
@ -144,55 +131,76 @@ class CacheControlHeaderParser {
|
||||||
boolean proxyRevalidate = false;
|
boolean proxyRevalidate = false;
|
||||||
boolean cachePublic = false;
|
boolean cachePublic = false;
|
||||||
long staleWhileRevalidate = -1;
|
long staleWhileRevalidate = -1;
|
||||||
|
|
||||||
// Declare a new Set variable at the beginning of the method to store the field-names
|
// Declare a new Set variable at the beginning of the method to store the field-names
|
||||||
final Set<String> noCacheFields = new HashSet<>();
|
final Set<String> noCacheFields = new HashSet<>();
|
||||||
|
|
||||||
while (!cursor.atEnd()) {
|
// Iterate over each header
|
||||||
final String name = tokenParser.parseToken(buffer, cursor, TOKEN_DELIMS);
|
while (headerIterator.hasNext()) {
|
||||||
String value = null;
|
final Header header = headerIterator.next();
|
||||||
if (!cursor.atEnd()) {
|
final CharArrayBuffer buffer;
|
||||||
final int valueDelim = buffer.charAt(cursor.getPos());
|
final Tokenizer.Cursor cursor;
|
||||||
cursor.updatePos(cursor.getPos() + 1);
|
if (header instanceof FormattedHeader) {
|
||||||
if (valueDelim == EQUAL_CHAR) {
|
buffer = ((FormattedHeader) header).getBuffer();
|
||||||
value = tokenParser.parseValue(buffer, cursor, VALUE_DELIMS);
|
cursor = new Tokenizer.Cursor(((FormattedHeader) header).getValuePos(), buffer.length());
|
||||||
if (!cursor.atEnd()) {
|
} else {
|
||||||
cursor.updatePos(cursor.getPos() + 1);
|
final String s = header.getValue();
|
||||||
}
|
if (s == null) {
|
||||||
|
return new CacheControl();
|
||||||
}
|
}
|
||||||
|
buffer = new CharArrayBuffer(s.length());
|
||||||
|
buffer.append(s);
|
||||||
|
cursor = new Tokenizer.Cursor(0, buffer.length());
|
||||||
}
|
}
|
||||||
if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_S_MAX_AGE)) {
|
|
||||||
sharedMaxAge = parseSeconds(name, value);
|
// Parse the header
|
||||||
} else if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_MAX_AGE)) {
|
while (!cursor.atEnd()) {
|
||||||
maxAge = parseSeconds(name, value);
|
final String name = tokenParser.parseToken(buffer, cursor, TOKEN_DELIMS);
|
||||||
} else if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_MUST_REVALIDATE)) {
|
String value = null;
|
||||||
mustRevalidate = true;
|
if (!cursor.atEnd()) {
|
||||||
} else if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_NO_CACHE)) {
|
final int valueDelim = buffer.charAt(cursor.getPos());
|
||||||
noCache = true;
|
cursor.updatePos(cursor.getPos() + 1);
|
||||||
if (value != null) {
|
if (valueDelim == EQUAL_CHAR) {
|
||||||
final Tokenizer.Cursor valCursor = new ParserCursor(0, value.length());
|
value = tokenParser.parseValue(buffer, cursor, VALUE_DELIMS);
|
||||||
while (!valCursor.atEnd()) {
|
if (!cursor.atEnd()) {
|
||||||
final String token = tokenParser.parseToken(value, valCursor, VALUE_DELIMS);
|
cursor.updatePos(cursor.getPos() + 1);
|
||||||
if (!TextUtils.isBlank(token)) {
|
|
||||||
noCacheFields.add(token);
|
|
||||||
}
|
|
||||||
if (!valCursor.atEnd()) {
|
|
||||||
valCursor.updatePos(valCursor.getPos() + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_NO_STORE)) {
|
// Update the Cache-Control directives based on the current header
|
||||||
noStore = true;
|
if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_S_MAX_AGE)) {
|
||||||
} else if (name.equalsIgnoreCase(HeaderConstants.PRIVATE)) {
|
sharedMaxAge = parseSeconds(name, value);
|
||||||
cachePrivate = true;
|
} else if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_MAX_AGE)) {
|
||||||
} else if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_PROXY_REVALIDATE)) {
|
maxAge = parseSeconds(name, value);
|
||||||
proxyRevalidate = true;
|
} else if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_MUST_REVALIDATE)) {
|
||||||
} else if (name.equalsIgnoreCase(HeaderConstants.PUBLIC)) {
|
mustRevalidate = true;
|
||||||
cachePublic = true;
|
} else if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_NO_CACHE)) {
|
||||||
} else if (name.equalsIgnoreCase(HeaderConstants.STALE_WHILE_REVALIDATE)) {
|
noCache = true;
|
||||||
staleWhileRevalidate = parseSeconds(name, value);
|
if (value != null) {
|
||||||
|
final Tokenizer.Cursor valCursor = new ParserCursor(0, value.length());
|
||||||
|
while (!valCursor.atEnd()) {
|
||||||
|
final String token = tokenParser.parseToken(value, valCursor, VALUE_DELIMS);
|
||||||
|
if (!TextUtils.isBlank(token)) {
|
||||||
|
noCacheFields.add(token);
|
||||||
|
}
|
||||||
|
if (!valCursor.atEnd()) {
|
||||||
|
valCursor.updatePos(valCursor.getPos() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_NO_STORE)) {
|
||||||
|
noStore = true;
|
||||||
|
} else if (name.equalsIgnoreCase(HeaderConstants.PRIVATE)) {
|
||||||
|
cachePrivate = true;
|
||||||
|
} else if (name.equalsIgnoreCase(HeaderConstants.CACHE_CONTROL_PROXY_REVALIDATE)) {
|
||||||
|
proxyRevalidate = true;
|
||||||
|
} else if (name.equalsIgnoreCase(HeaderConstants.PUBLIC)) {
|
||||||
|
cachePublic = true;
|
||||||
|
} else if (name.equalsIgnoreCase(HeaderConstants.STALE_WHILE_REVALIDATE)) {
|
||||||
|
staleWhileRevalidate = parseSeconds(name, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Return a single CacheControl object with the combined directives
|
||||||
return new CacheControl(maxAge, sharedMaxAge, mustRevalidate, noCache, noStore, cachePrivate, proxyRevalidate, cachePublic, staleWhileRevalidate, noCacheFields);
|
return new CacheControl(maxAge, sharedMaxAge, mustRevalidate, noCache, noStore, cachePrivate, proxyRevalidate, cachePublic, staleWhileRevalidate, noCacheFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,11 +383,11 @@ public class CachingExecBase {
|
||||||
* false otherwise
|
* false otherwise
|
||||||
*/
|
*/
|
||||||
boolean requestContainsNoCacheDirective(final HttpRequest request) {
|
boolean requestContainsNoCacheDirective(final HttpRequest request) {
|
||||||
final Header cacheControlHeader = request.getFirstHeader(HttpHeaders.CACHE_CONTROL);
|
final Iterator<Header> it = request.headerIterator(HttpHeaders.CACHE_CONTROL);
|
||||||
if (cacheControlHeader == null) {
|
if (it == null || !it.hasNext()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
final CacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(cacheControlHeader);
|
final CacheControl cacheControl = CacheControlHeaderParser.INSTANCE.parse(it);
|
||||||
return cacheControl.isNoCache();
|
return cacheControl.isNoCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,11 +535,11 @@ class ResponseCachingPolicy {
|
||||||
* @return a CacheControl instance with the parsed directives or default values if the header is not present
|
* @return a CacheControl instance with the parsed directives or default values if the header is not present
|
||||||
*/
|
*/
|
||||||
private CacheControl parseCacheControlHeader(final MessageHeaders messageHeaders) {
|
private CacheControl parseCacheControlHeader(final MessageHeaders messageHeaders) {
|
||||||
final Header cacheControlHeader = messageHeaders.getFirstHeader(HttpHeaders.CACHE_CONTROL);
|
final Iterator<Header> it = messageHeaders.headerIterator(HttpHeaders.CACHE_CONTROL);
|
||||||
if (cacheControlHeader == null) {
|
if (it == null || !it.hasNext()) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return CacheControlHeaderParser.INSTANCE.parse(cacheControlHeader);
|
return CacheControlHeaderParser.INSTANCE.parse(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,9 @@ import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.message.BasicHeader;
|
import org.apache.hc.core5.http.message.BasicHeader;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public class CacheControlParserTest {
|
public class CacheControlParserTest {
|
||||||
|
|
||||||
private final CacheControlHeaderParser parser = CacheControlHeaderParser.INSTANCE;
|
private final CacheControlHeaderParser parser = CacheControlHeaderParser.INSTANCE;
|
||||||
|
@ -42,69 +45,69 @@ public class CacheControlParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void testParseMaxAgeZero() {
|
public void testParseMaxAgeZero() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "max-age=0 , this = stuff;");
|
final Header header = new BasicHeader("Cache-Control", "max-age=0 , this = stuff;");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
assertEquals(0L, cacheControl.getMaxAge());
|
assertEquals(0L, cacheControl.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseSMaxAge() {
|
public void testParseSMaxAge() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "s-maxage=3600");
|
final Header header = new BasicHeader("Cache-Control", "s-maxage=3600");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
assertEquals(3600L, cacheControl.getSharedMaxAge());
|
assertEquals(3600L, cacheControl.getSharedMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseInvalidCacheValue() {
|
public void testParseInvalidCacheValue() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "max-age=invalid");
|
final Header header = new BasicHeader("Cache-Control", "max-age=invalid");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
assertEquals(-1L, cacheControl.getMaxAge());
|
assertEquals(-1L, cacheControl.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseInvalidHeader() {
|
public void testParseInvalidHeader() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "max-age");
|
final Header header = new BasicHeader("Cache-Control", "max-age");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
assertEquals(-1L, cacheControl.getMaxAge());
|
assertEquals(-1L, cacheControl.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseNullHeader() {
|
public void testParseNullHeader() {
|
||||||
final Header header = null;
|
final Header header = null;
|
||||||
assertThrows(NullPointerException.class, () -> parser.parse(header));
|
assertThrows(NullPointerException.class, () -> parser.parse(Collections.singletonList(header).iterator()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseEmptyHeader() {
|
public void testParseEmptyHeader() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "");
|
final Header header = new BasicHeader("Cache-Control", "");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
assertEquals(-1L, cacheControl.getMaxAge());
|
assertEquals(-1L, cacheControl.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseCookieEmptyValue() {
|
public void testParseCookieEmptyValue() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "max-age=;");
|
final Header header = new BasicHeader("Cache-Control", "max-age=;");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
assertEquals(-1L, cacheControl.getMaxAge());
|
assertEquals(-1L, cacheControl.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseNoCache() {
|
public void testParseNoCache() {
|
||||||
final Header header = new BasicHeader(" Cache-Control", "no-cache");
|
final Header header = new BasicHeader(" Cache-Control", "no-cache");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
assertEquals(-1L, cacheControl.getMaxAge());
|
assertEquals(-1L, cacheControl.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseNoDirective() {
|
public void testParseNoDirective() {
|
||||||
final Header header = new BasicHeader(" Cache-Control", "");
|
final Header header = new BasicHeader(" Cache-Control", "");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
assertEquals(-1L, cacheControl.getMaxAge());
|
assertEquals(-1L, cacheControl.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGarbage() {
|
public void testGarbage() {
|
||||||
final Header header = new BasicHeader("Cache-Control", ",,= blah,");
|
final Header header = new BasicHeader("Cache-Control", ",,= blah,");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
assertEquals(-1L, cacheControl.getMaxAge());
|
assertEquals(-1L, cacheControl.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +115,7 @@ public class CacheControlParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void testParseMultipleDirectives() {
|
public void testParseMultipleDirectives() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "max-age=604800, stale-while-revalidate=86400, s-maxage=3600, must-revalidate, private");
|
final Header header = new BasicHeader("Cache-Control", "max-age=604800, stale-while-revalidate=86400, s-maxage=3600, must-revalidate, private");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
|
|
||||||
assertAll("Must all pass",
|
assertAll("Must all pass",
|
||||||
() -> assertEquals(604800L, cacheControl.getMaxAge()),
|
() -> assertEquals(604800L, cacheControl.getMaxAge()),
|
||||||
|
@ -125,7 +128,7 @@ public class CacheControlParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void testParseMultipleDirectives2() {
|
public void testParseMultipleDirectives2() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "max-age=604800, stale-while-revalidate=86400, must-revalidate, private, s-maxage=3600");
|
final Header header = new BasicHeader("Cache-Control", "max-age=604800, stale-while-revalidate=86400, must-revalidate, private, s-maxage=3600");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
|
|
||||||
assertAll("Must all pass",
|
assertAll("Must all pass",
|
||||||
() -> assertEquals(604800L, cacheControl.getMaxAge()),
|
() -> assertEquals(604800L, cacheControl.getMaxAge()),
|
||||||
|
@ -138,7 +141,7 @@ public class CacheControlParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void testParsePublic() {
|
public void testParsePublic() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "public");
|
final Header header = new BasicHeader("Cache-Control", "public");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
|
|
||||||
assertTrue(cacheControl.isPublic());
|
assertTrue(cacheControl.isPublic());
|
||||||
}
|
}
|
||||||
|
@ -146,7 +149,7 @@ public class CacheControlParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void testParsePrivate() {
|
public void testParsePrivate() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "private");
|
final Header header = new BasicHeader("Cache-Control", "private");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
|
|
||||||
assertTrue(cacheControl.isCachePrivate());
|
assertTrue(cacheControl.isCachePrivate());
|
||||||
}
|
}
|
||||||
|
@ -154,7 +157,7 @@ public class CacheControlParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void testParseNoStore() {
|
public void testParseNoStore() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "no-store");
|
final Header header = new BasicHeader("Cache-Control", "no-store");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
|
|
||||||
assertTrue(cacheControl.isNoStore());
|
assertTrue(cacheControl.isNoStore());
|
||||||
}
|
}
|
||||||
|
@ -162,7 +165,7 @@ public class CacheControlParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void testParseStaleWhileRevalidate() {
|
public void testParseStaleWhileRevalidate() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "max-age=3600, stale-while-revalidate=120");
|
final Header header = new BasicHeader("Cache-Control", "max-age=3600, stale-while-revalidate=120");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
|
|
||||||
assertEquals(120, cacheControl.getStaleWhileRevalidate());
|
assertEquals(120, cacheControl.getStaleWhileRevalidate());
|
||||||
}
|
}
|
||||||
|
@ -170,7 +173,7 @@ public class CacheControlParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void testParseNoCacheFields() {
|
public void testParseNoCacheFields() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "no-cache=\"Set-Cookie, Content-Language\", stale-while-revalidate=120");
|
final Header header = new BasicHeader("Cache-Control", "no-cache=\"Set-Cookie, Content-Language\", stale-while-revalidate=120");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
|
|
||||||
assertTrue(cacheControl.isNoCache());
|
assertTrue(cacheControl.isNoCache());
|
||||||
assertEquals(2, cacheControl.getNoCacheFields().size());
|
assertEquals(2, cacheControl.getNoCacheFields().size());
|
||||||
|
@ -182,7 +185,7 @@ public class CacheControlParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void testParseNoCacheFieldsNoQuote() {
|
public void testParseNoCacheFieldsNoQuote() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "no-cache=Set-Cookie, Content-Language, stale-while-revalidate=120");
|
final Header header = new BasicHeader("Cache-Control", "no-cache=Set-Cookie, Content-Language, stale-while-revalidate=120");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
|
|
||||||
assertTrue(cacheControl.isNoCache());
|
assertTrue(cacheControl.isNoCache());
|
||||||
assertEquals(1, cacheControl.getNoCacheFields().size());
|
assertEquals(1, cacheControl.getNoCacheFields().size());
|
||||||
|
@ -193,7 +196,7 @@ public class CacheControlParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void testParseNoCacheFieldsMessy() {
|
public void testParseNoCacheFieldsMessy() {
|
||||||
final Header header = new BasicHeader("Cache-Control", "no-cache=\" , , ,,, Set-Cookie , , Content-Language , \", stale-while-revalidate=120");
|
final Header header = new BasicHeader("Cache-Control", "no-cache=\" , , ,,, Set-Cookie , , Content-Language , \", stale-while-revalidate=120");
|
||||||
final CacheControl cacheControl = parser.parse(header);
|
final CacheControl cacheControl = parser.parse(Collections.singletonList(header).iterator());
|
||||||
|
|
||||||
assertTrue(cacheControl.isNoCache());
|
assertTrue(cacheControl.isNoCache());
|
||||||
assertEquals(2, cacheControl.getNoCacheFields().size());
|
assertEquals(2, cacheControl.getNoCacheFields().size());
|
||||||
|
@ -202,4 +205,25 @@ public class CacheControlParserTest {
|
||||||
assertEquals(120, cacheControl.getStaleWhileRevalidate());
|
assertEquals(120, cacheControl.getStaleWhileRevalidate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseMultipleHeaders() {
|
||||||
|
// Create headers
|
||||||
|
final Header header1 = new BasicHeader("Cache-Control", "max-age=3600, no-store");
|
||||||
|
final Header header2 = new BasicHeader("Cache-Control", "private, must-revalidate");
|
||||||
|
final Header header3 = new BasicHeader("Cache-Control", "max-age=3600");
|
||||||
|
final Header header4 = new BasicHeader("Cache-Control", "no-store");
|
||||||
|
final Header header5 = new BasicHeader("Cache-Control", "private");
|
||||||
|
final Header header6 = new BasicHeader("Cache-Control", "must-revalidate");
|
||||||
|
|
||||||
|
// Parse headers
|
||||||
|
final CacheControl cacheControl1 = parser.parse(Arrays.asList(header1, header2).iterator());
|
||||||
|
final CacheControl cacheControl2 = parser.parse(Arrays.asList(header3, header4, header5, header6).iterator());
|
||||||
|
|
||||||
|
// Validate Cache-Control directives
|
||||||
|
assertEquals(cacheControl1.getMaxAge(), cacheControl2.getMaxAge());
|
||||||
|
assertEquals(cacheControl1.isNoStore(), cacheControl2.isNoStore());
|
||||||
|
assertEquals(cacheControl1.isCachePrivate(), cacheControl2.isCachePrivate());
|
||||||
|
assertEquals(cacheControl1.isMustRevalidate(), cacheControl2.isMustRevalidate());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -381,7 +381,7 @@ public class TestResponseCachingPolicy {
|
||||||
response.addHeader("Cache-Control", "max-age=20");
|
response.addHeader("Cache-Control", "max-age=20");
|
||||||
response.addHeader("Cache-Control", "public, no-store");
|
response.addHeader("Cache-Control", "public, no-store");
|
||||||
|
|
||||||
Assertions.assertTrue(policy.isResponseCacheable("GET", response));
|
Assertions.assertFalse(policy.isResponseCacheable("GET", response));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -389,7 +389,7 @@ public class TestResponseCachingPolicy {
|
||||||
response.addHeader("Cache-Control", "max-age=20");
|
response.addHeader("Cache-Control", "max-age=20");
|
||||||
response.addHeader("Cache-Control", "public, no-store");
|
response.addHeader("Cache-Control", "public, no-store");
|
||||||
|
|
||||||
Assertions.assertTrue(policy.isResponseCacheable("HEAD", response));
|
Assertions.assertFalse(policy.isResponseCacheable("HEAD", response));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue