Skip to content

Commit

Permalink
Feature/httpcache responseheader exclusion (#1905)
Browse files Browse the repository at this point in the history
* Add excluded response headers to http cache config
  • Loading branch information
niekraaijmakers authored and davidjgonzalez committed May 28, 2019
1 parent 2fdafca commit 9a84c94
Show file tree
Hide file tree
Showing 10 changed files with 620 additions and 310 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.adobe.acs.commons.httpcache.keys.CacheKey;
import org.apache.sling.api.SlingHttpServletRequest;

import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

Expand All @@ -37,7 +38,7 @@
@ProviderType
public interface HttpCacheConfig {

public enum FilterScope {
enum FilterScope {
REQUEST,
INCLUDE
}
Expand Down Expand Up @@ -77,6 +78,15 @@ public enum FilterScope {
*/
List<Pattern> getJCRInvalidationPathPatterns();

/**
* Get a list of headers (as regex pattern) that should NOT be put in the cached response, to be served to the output.
* This is useful for example with systems that put a login cookie in each response.
* @return
*/
default List<Pattern> getExcludedResponseHeaderPatterns() {
return Collections.emptyList();
}

/**
* Determine if this cache config is applicable for the given request. Calls <code>HttpCacheConfigExtension
* .accept()</code> for providing share of control to the custom code.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.adobe.acs.commons.httpcache.keys.CacheKeyFactory;
import com.adobe.acs.commons.httpcache.store.HttpCacheStore;
import com.adobe.acs.commons.httpcache.util.UserUtils;
import com.adobe.acs.commons.util.ParameterUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Activate;
Expand Down Expand Up @@ -216,6 +217,15 @@ public class HttpCacheConfigImpl implements HttpCacheConfig {
static final String PROP_CACHE_HANDLING_RULES_PID = "httpcache.config.cache-handling-rules.pid";
private List<String> cacheHandlingRulesPid;



@Property(label = "Config-specific Excluded Response headers",
description = "List of header keys (as regex) that should NOT be put in the cached response, to be served to the output.",
unbounded = PropertyUnbounded.ARRAY
)
static final String PROP_RESPONSE_HEADER_EXCLUSIONS = "httpcache.config.excluded.response.headers";
private List<Pattern> responseHeaderExclusions;

@Property(label = "Expiry on create",
description = "Specifies a custom expiry on create. Overrules the global expiry, unless the value is 0.")
static final String PROP_EXPIRY_ON_CREATE = "httpcache.config.expiry.on.create";
Expand Down Expand Up @@ -249,6 +259,9 @@ protected void activate(Map<String, Object> configs) {
String[]{}));
requestUriPatternsAsRegEx = compileToPatterns(requestUriPatterns);

responseHeaderExclusions = ParameterUtil.toPatterns(PropertiesUtil.toStringArray(configs.get(PROP_RESPONSE_HEADER_EXCLUSIONS), new String[]{}));


// Request URIs - Blacklisted.
blacklistedRequestUriPatterns = Arrays.asList(PropertiesUtil.toStringArray(configs
.get(PROP_BLACKLISTED_REQUEST_URI_PATTERNS), new String[]{}));
Expand Down Expand Up @@ -452,4 +465,9 @@ public boolean acceptsRule(String servicePid) {
public FilterScope getFilterScope() {
return this.filterScope;
}

@Override
public List<Pattern> getExcludedResponseHeaderPatterns() {
return responseHeaderExclusions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
* #L%
*/

@org.osgi.annotation.versioning.Version("2.2.0")
@org.osgi.annotation.versioning.Version("2.3.0")
package com.adobe.acs.commons.httpcache.config;

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* Represents response content to be cached.
Expand All @@ -41,7 +42,7 @@ public class CacheContent {
/** Response content type */
private String contentType;
/** Response headers */
private Map<String, List<String>> headers = new HashMap<String, List<String>>();
private Map<String, List<String>> headers = new HashMap<>();
/** Response content as input stream */
private InputStream dataInputStream;
/** Temp sink attached to this cache content */
Expand Down Expand Up @@ -132,24 +133,37 @@ public CacheContent() {
* Construct from the custom servlet response wrapper..
*
* @param responseWrapper
* @deprecated Use build(HttpCacheServletResponseWrapper responseWrapper,int status, String charEncoding, String contentType, Map<String, List<String>> headers) throws HttpCacheDataStreamException
* @return
*/
@Deprecated
public CacheContent build(HttpCacheServletResponseWrapper responseWrapper) throws HttpCacheDataStreamException {
this.status = responseWrapper.getStatus();
// Extracting HTTP Response Header Names and Values
Map<String, List<String>> extractedHeaders = responseWrapper.getHeaderNames().stream().collect(
Collectors.toMap(headerName -> headerName, headerName ->
new ArrayList<>(responseWrapper.getHeaders(headerName)
)
));

return build(responseWrapper, responseWrapper.getStatus(), responseWrapper.getCharacterEncoding(), responseWrapper. getContentType(), extractedHeaders);
}

/**
* Construct from the custom servlet response wrapper..
*
* @param responseWrapper
* @param headers
* @return
*/
public CacheContent build(HttpCacheServletResponseWrapper responseWrapper,int status, String charEncoding, String contentType, Map<String, List<String>> headers) throws HttpCacheDataStreamException {
this.status = status;

// Extract information from response and populate state of the instance.
this.charEncoding = responseWrapper.getCharacterEncoding();
this.contentType = responseWrapper.getContentType();
this.charEncoding = charEncoding;
this.contentType = contentType;

// Extracting header K,V.
List<String> headerNames = new ArrayList<String>();

headerNames.addAll(responseWrapper.getHeaderNames());
for (String headerName: headerNames) {
List<String> values = new ArrayList<String>();
values.addAll(responseWrapper.getHeaders(headerName));
headers.put(headerName, values);
}
this.headers.putAll(headers);

// Get hold of the temp sink.
this.tempSink = responseWrapper.getTempSink();
Expand Down
Loading

0 comments on commit 9a84c94

Please sign in to comment.