/*
* #%L
* ACS AEM Commons Bundle
* %%
* Copyright (C) 2016 Adobe
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package com.adobe.acs.commons.httpcache.filter.impl;
import com.adobe.acs.commons.httpcache.config.HttpCacheConfig;
import com.adobe.acs.commons.httpcache.engine.HttpCacheEngine;
import com.adobe.acs.commons.httpcache.exception.HttpCacheException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public abstract class AbstractHttpCacheFilter implements Filter {
private static final Logger log = LoggerFactory.getLogger(AbstractHttpCacheFilter.class);
@Override
public abstract void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException;
protected void doFilter(ServletRequest request, ServletResponse response, FilterChain chain,
HttpCacheEngine cacheEngine, HttpCacheConfig.FilterScope filterScope) throws IOException, ServletException {
log.trace("In HttpCache filter.");
final long start = System.currentTimeMillis();
final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
SlingHttpServletResponse slingResponse = (SlingHttpServletResponse) response;
HttpCacheConfig cacheConfig = null;
boolean isResponseCacheable = false;
try {
// Get the first accepting cache config, or null if no accepting cacheConfigs can be found.
cacheConfig = cacheEngine.getCacheConfig(slingRequest, filterScope);
// Check if the url is cache-able as per configs and rules.
// An accepting cacheConfig must exist and all cache rules must be met.
if (cacheConfig != null && cacheEngine.isRequestCacheable(slingRequest, cacheConfig)) {
// Check if cached response available for this request.
if (cacheEngine.isCacheHit(slingRequest, cacheConfig)) {
// Deliver the response from cache.
if (cacheEngine.deliverCacheContent(slingRequest, slingResponse, cacheConfig)) {
if (log.isDebugEnabled()) {
log.debug("Delivered cached request [ {} ] in {} ms", slingRequest.getResource().getPath(),
System.currentTimeMillis() - start);
}
return;
}
} else {
// Mark the request as cacheable once processed.
isResponseCacheable = true;
// Wrap the response
slingResponse = cacheEngine.wrapResponse(slingRequest, slingResponse, cacheConfig);
}
}
} catch (HttpCacheException e) {
log.error("HttpCache exception while dealing with request. Passed on the control to filter chain.", e);
}
// Pass on the request to filter chain.
chain.doFilter(request, slingResponse);
try {
// If the request has the attribute marked, cache the response.
if (isResponseCacheable) {
cacheEngine.cacheResponse(slingRequest, slingResponse, cacheConfig);
}
if (log.isTraceEnabled()) {
log.trace("Delivered un-cached request [ {} ] in {} ms", slingRequest.getResource().getPath(),
System.currentTimeMillis() - start);
}
} catch (HttpCacheException e) {
log.error("HttpCache exception while dealing with response. Returned the filter chain response", e);
}
}
//---------------<Do nothing methods. Just to satisfy interface contract>
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}