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
77
78 final long cacheStorageDate = System.currentTimeMillis();
79 responseWrapper.setDateHeader("Last-Modified", cacheStorageDate);
80
81 try {
82 chain.doFilter(request, responseWrapper);
83 if (responseWrapper.getStatus() == HttpServletResponse.SC_NOT_MODIFIED) {
84 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
85 }
86 else {
87 responseWrapper.flushBuffer();
88 cachedEntry = makeCachedEntry(request, responseWrapper);
89 }
90
91 } catch (IOException e) {
92 responseWrapper.cleanUp();
93 throw e;
94 } catch (ServletException e) {
95 responseWrapper.cleanUp();
96 throw e;
97 } catch (Throwable e) {
98 responseWrapper.cleanUp();
99 throw new RuntimeException("Failed to process request with: " + e.getMessage(), e);
100 }
101
102 if (cachedEntry == null) {
103
104 cache.put(key, null);
105 return;
106 }
107
108 int timeToLiveInSeconds = cachedEntry.getTimeToLiveInSeconds();
109 if (timeToLiveInSeconds == 0) {
110
111 cache.put(key, null);
112
113
114 cachedEntry.replay(request, response, chain);
115 response.flushBuffer();
116
117 return;
118 }
119
120
121 cachePolicyResult.setCachedEntry(cachedEntry);
122
123 if (timeToLiveInSeconds == -1) {
124 cache.put(key, cachedEntry);
125 } else {
126 cache.put(key, cachedEntry, timeToLiveInSeconds);
127 }
128
129
130 final Content currentContent = MgnlContext.getAggregationState().getCurrentContent();
131 final Node content = currentContent != null ? currentContent.getJCRNode() : null;
132 try {
133 if (content != null && NodeUtil.isNodeType(content, "mix:referenceable")) {
134 final String uuid = content.getIdentifier();
135 String repo = content.getSession().getWorkspace().getName();
136 getCachePolicy(cache).persistCacheKey(repo, uuid, key);
137 }
138 } catch (RepositoryException e) {
139
140 throw new RuntimeException(e);
141 }
142 }
143
144 protected CachedEntry makeCachedEntry(HttpServletRequest request, CacheResponseWrapper cachedResponse) throws IOException {
145
146 final String originalUrl = request.getRequestURL().toString();
147 int status = cachedResponse.getStatus();
148 int timeToLiveInSeconds = cachedResponse.getTimeToLiveInSeconds();
149
150
151 if (cachedResponse.getRedirectionLocation() != null) {
152 return new CachedRedirect(cachedResponse.getStatus(), cachedResponse.getRedirectionLocation(), originalUrl, timeToLiveInSeconds);
153 }
154
155 if (cachedResponse.isError()) {
156 return new CachedError(cachedResponse.getStatus(), originalUrl, timeToLiveInSeconds);
157 }
158
159 final long modificationDate = cachedResponse.getLastModified();
160 final String contentType = cachedResponse.getContentType();
161
162 ContentCachedEntry cacheEntry;
163 if(!cachedResponse.isThresholdExceeded()){
164 cacheEntry = new InMemoryCachedEntry(cachedResponse.getBufferedContent(),
165 contentType,
166 cachedResponse.getCharacterEncoding(),
167 status,
168 cachedResponse.getHeaders(),
169 modificationDate,
170 originalUrl,
171 timeToLiveInSeconds);
172 }
173 else{
174 cacheEntry = new DelegatingBlobCachedEntry(cachedResponse.getContentLength(),
175 contentType,
176 cachedResponse.getCharacterEncoding(),
177 status,
178 cachedResponse.getHeaders(),
179 modificationDate,
180 originalUrl,
181 timeToLiveInSeconds);
182
183
184
185 ((DelegatingBlobCachedEntry)cacheEntry).bindContentFileToCurrentRequest(request, cachedResponse.getContentFile());
186 cachedResponse.getThresholdingOutputStream().close();
187 }
188
189 return cacheEntry;
190 }
191
192 protected CachePolicy getCachePolicy(Cache cache) {
193 return getModule().getConfiguration(cache.getName()).getCachePolicy();
194 }
195
196
197
198
199 @Deprecated
200 protected CacheModule getModule() {
201 return CacheModule.getInstance();
202 }
203 }