Improve support for caching encoded resources
The key in CachingResourceResolver now includes the "Accept-Encoding" request header cleaned to exclude "*", "identity", and parameters, and also sorted alphabetically. For encoded resources the response now includes a response header with "Vary: Accept-Encoding". Issue: SPR-16381
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,14 +16,18 @@
|
||||
|
||||
package org.springframework.web.servlet.resource;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A {@link org.springframework.web.servlet.resource.ResourceResolver} that
|
||||
@@ -95,14 +99,31 @@ public class CachingResourceResolver extends AbstractResourceResolver {
|
||||
StringBuilder key = new StringBuilder(RESOLVED_RESOURCE_CACHE_KEY_PREFIX);
|
||||
key.append(requestPath);
|
||||
if (request != null) {
|
||||
String encoding = request.getHeader("Accept-Encoding");
|
||||
if (encoding != null && encoding.contains("gzip")) {
|
||||
key.append("+encoding=gzip");
|
||||
String codingKey = getContentCodingKey(request);
|
||||
if (codingKey != null) {
|
||||
key.append("+encoding=").append(codingKey);
|
||||
}
|
||||
}
|
||||
return key.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getContentCodingKey(HttpServletRequest request) {
|
||||
String header = request.getHeader(HttpHeaders.ACCEPT_ENCODING);
|
||||
if (!StringUtils.hasText(header)) {
|
||||
return null;
|
||||
}
|
||||
return Arrays.stream(StringUtils.tokenizeToStringArray(header, ","))
|
||||
.map(token -> {
|
||||
int index = token.indexOf(';');
|
||||
return (index >= 0 ? token.substring(0, index) : token).trim().toLowerCase();
|
||||
})
|
||||
.filter(coding -> !coding.equals("*"))
|
||||
.filter(coding -> !coding.equals("identity"))
|
||||
.sorted()
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String resolveUrlPathInternal(String resourceUrlPath,
|
||||
List<? extends Resource> locations, ResourceResolverChain chain) {
|
||||
|
||||
@@ -263,6 +263,7 @@ public class EncodedResourceResolver extends AbstractResourceResolver {
|
||||
headers = new HttpHeaders();
|
||||
}
|
||||
headers.add(HttpHeaders.CONTENT_ENCODING, this.coding);
|
||||
headers.add(HttpHeaders.VARY, HttpHeaders.ACCEPT_ENCODING);
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +167,7 @@ public class GzipResourceResolver extends AbstractResourceResolver {
|
||||
headers = new HttpHeaders();
|
||||
}
|
||||
headers.add(HttpHeaders.CONTENT_ENCODING, "gzip");
|
||||
headers.add(HttpHeaders.VARY, HttpHeaders.ACCEPT_ENCODING);
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user