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
28
29
30
31
32
33
34 package info.magnolia.module.cache.executor;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.context.MgnlContext;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.module.cache.Cache;
40 import info.magnolia.module.cache.CacheModule;
41 import info.magnolia.module.cache.CachePolicy;
42 import info.magnolia.module.cache.CachePolicyResult;
43 import info.magnolia.module.cache.filter.CacheResponseWrapper;
44 import info.magnolia.module.cache.filter.CachedEntry;
45 import info.magnolia.module.cache.filter.CachedError;
46 import info.magnolia.module.cache.filter.CachedRedirect;
47 import info.magnolia.module.cache.filter.ContentCachedEntry;
48 import info.magnolia.module.cache.filter.DelegatingBlobCachedEntry;
49 import info.magnolia.module.cache.filter.InMemoryCachedEntry;
50
51 import java.io.IOException;
52
53 import javax.jcr.Node;
54 import javax.jcr.RepositoryException;
55 import javax.servlet.FilterChain;
56 import javax.servlet.ServletException;
57 import javax.servlet.http.HttpServletRequest;
58 import javax.servlet.http.HttpServletResponse;
59
60
61
62
63
64
65
66 public class Store extends AbstractExecutor {
67
68 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Store.class);
69
70 @Override
71 public void processCacheRequest(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Cache cache, CachePolicyResult cachePolicyResult) throws IOException, ServletException {
72 CachedEntry cachedEntry = null;
73 final Object key = cachePolicyResult.getCacheKey();
74
75 final CacheResponseWrapper responseWrapper = new CacheResponseWrapper(response, CacheResponseWrapper.DEFAULT_THRESHOLD, false);
76 responseWrapper.setResponseExpirationDetectionEnabled();
77
78
79 final long cacheStorageDate = System.currentTimeMillis();
80 responseWrapper.setDateHeader("Last-Modified", cacheStorageDate);
81
82 try {
83 chain.doFilter(request, responseWrapper);
84 if (responseWrapper.getStatus() == HttpServletResponse.SC_NOT_MODIFIED) {
85 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
86 }
87 else {
88 responseWrapper.flushBuffer();
89 cachedEntry = makeCachedEntry(request, responseWrapper);
90 }
91
92 } catch (IOException e) {
93 responseWrapper.cleanUp();
94 throw e;
95 } catch (ServletException e) {
96 responseWrapper.cleanUp();
97 throw e;
98 } catch (Throwable e) {
99 responseWrapper.cleanUp();
100 throw new RuntimeException("Failed to process request with: " + e.getMessage(), e);
101 }
102
103 if (cachedEntry == null) {
104
105 cache.put(key, null);
106 return;
107 }
108
109 int timeToLiveInSeconds = cachedEntry.getTimeToLiveInSeconds();
110 if (timeToLiveInSeconds == 0) {
111
112 cache.put(key, null);
113
114
115 cachedEntry.replay(request, response, chain);
116 response.flushBuffer();
117
118 return;
119 }
120
121
122 cachePolicyResult.setCachedEntry(cachedEntry);
123
124 if (timeToLiveInSeconds == -1) {
125 cache.put(key, cachedEntry);
126 } else {
127 cache.put(key, cachedEntry, timeToLiveInSeconds);
128 }
129
130
131 final Content currentContent = MgnlContext.getAggregationState().getCurrentContent();
132 final Node content = currentContent != null ? currentContent.getJCRNode() : null;
133 try {
134 if (content != null && NodeUtil.isNodeType(content, "mix:referenceable")) {
135 final String uuid = content.getIdentifier();
136 String repo = content.getSession().getWorkspace().getName();
137 getCachePolicy(cache).persistCacheKey(repo, uuid, key);
138 }
139 } catch (RepositoryException e) {
140
141 throw new RuntimeException(e);
142 }
143 }
144
145 protected CachedEntry makeCachedEntry(HttpServletRequest request, CacheResponseWrapper cachedResponse) throws IOException {
146
147 final String originalUrl = request.getRequestURL().toString();
148 int status = cachedResponse.getStatus();
149 int timeToLiveInSeconds = cachedResponse.getTimeToLiveInSeconds();
150
151
152 if (cachedResponse.getRedirectionLocation() != null) {
153 return new CachedRedirect(cachedResponse.getStatus(), cachedResponse.getRedirectionLocation(), originalUrl, timeToLiveInSeconds);
154 }
155
156 if (cachedResponse.isError()) {
157 return new CachedError(cachedResponse.getStatus(), originalUrl, timeToLiveInSeconds);
158 }
159
160 final long modificationDate = cachedResponse.getLastModified();
161 final String contentType = cachedResponse.getContentType();
162
163 ContentCachedEntry cacheEntry;
164 if(!cachedResponse.isThresholdExceeded()){
165 cacheEntry = new InMemoryCachedEntry(cachedResponse.getBufferedContent(),
166 contentType,
167 cachedResponse.getCharacterEncoding(),
168 status,
169 cachedResponse.getHeaders(),
170 modificationDate,
171 originalUrl,
172 timeToLiveInSeconds);
173 }
174 else{
175 cacheEntry = new DelegatingBlobCachedEntry(cachedResponse.getContentLength(),
176 contentType,
177 cachedResponse.getCharacterEncoding(),
178 status,
179 cachedResponse.getHeaders(),
180 modificationDate,
181 originalUrl,
182 timeToLiveInSeconds);
183
184
185
186 ((DelegatingBlobCachedEntry)cacheEntry).bindContentFileToCurrentRequest(request, cachedResponse.getContentFile());
187 cachedResponse.getThresholdingOutputStream().close();
188 }
189
190 return cacheEntry;
191 }
192
193 protected CachePolicy getCachePolicy(Cache cache) {
194 return getModule().getConfiguration(cache.getName()).getCachePolicy();
195 }
196
197
198
199
200 @Deprecated
201 protected CacheModule getModule() {
202 return CacheModule.getInstance();
203 }
204 }