X-Git-Url: https://juplo.de/gitweb/?p=percentcodec;a=blobdiff_plain;f=cachecontrol%2Fsrc%2Fmain%2Fjava%2Fde%2Fhalbekunst%2Fjuplo%2Fcachecontrol%2FCacheControlInterceptor.java;h=3d0c52d42a280ec20a8bf7f5889357b62886ca70;hp=49231f61d217609cf35446493a8f5c9850ae7448;hb=b959bda46cfb3501adb9431e5df94fe6885437d7;hpb=41728c62c300452447d569fcfce057f085d7fda9 diff --git a/cachecontrol/src/main/java/de/halbekunst/juplo/cachecontrol/CacheControlInterceptor.java b/cachecontrol/src/main/java/de/halbekunst/juplo/cachecontrol/CacheControlInterceptor.java index 49231f61..3d0c52d4 100644 --- a/cachecontrol/src/main/java/de/halbekunst/juplo/cachecontrol/CacheControlInterceptor.java +++ b/cachecontrol/src/main/java/de/halbekunst/juplo/cachecontrol/CacheControlInterceptor.java @@ -30,173 +30,194 @@ public class CacheControlInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - try { - Cacheable cacheable = (Cacheable)handler; + if (!(handler instanceof Cacheable)) + return true; - long now = System.currentTimeMillis(); + Cacheable cacheable = (Cacheable) handler; - /** - * Alle Antworten (insbesondere auch 304) sollen nach dem {@plainlink - * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.18 RFC 2616, - * Abschnitt 14.18} einen Date-Header enthalten - */ - response.setDateHeader(HEADER_DATE, now); + long now = System.currentTimeMillis(); - /** Prüfen, ob der Handler willig ist, den Request zu verarbeiten */ - if (!cacheable.accepts(request)) { - response.sendError(HttpServletResponse.SC_NOT_FOUND); - return false; - } + /** + * Alle Antworten (insbesondere auch 304) sollen nach dem {@plainlink + * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.18 RFC 2616, + * Abschnitt 14.18} einen Date-Header enthalten + */ + response.setDateHeader(HEADER_DATE, now); - /** Nichts weiter unternehmen, wenn der Handler dies nicht will */ - if (!cacheable.isGenerateCacheHeaders(request)) - return true; - - String url = null; - if (log.isDebugEnabled()) { - if (request.getQueryString() == null) { - url = request.getRequestURI(); - } - else { - StringBuilder builder = new StringBuilder(); - builder.append(request.getRequestURI()); - builder.append('?'); - builder.append(request.getQueryString()); - url = builder.toString(); - } - } + /** Prüfen, ob der Handler willig ist, den Request zu verarbeiten */ + if (!cacheable.accepts(request)) { + response.sendError(HttpServletResponse.SC_NOT_FOUND); + return false; + } - int cacheSeconds = cacheable.getCacheSeconds(request); - if (cacheSeconds < 0) { - log.debug("{}: caching disabled!", url); - response.setDateHeader(HEADER_DATE, now); - response.setDateHeader(HEADER_EXPIRES, 0); - response.addHeader(HEADER_PRAGMA, "no-cache"); - response.addHeader(HEADER_CACHE_CONTROL, "private"); - response.addHeader(HEADER_CACHE_CONTROL, "no-cache"); - response.addHeader(HEADER_CACHE_CONTROL, "no-store"); - response.addHeader(HEADER_CACHE_CONTROL, "max-age=0"); - response.addHeader(HEADER_CACHE_CONTROL, "s-max-age=0"); - return true; - } + /** Nichts weiter unternehmen, wenn der Handler dies nicht will */ + if (!cacheable.isGenerateCacheHeaders(request)) + return true; - long ifModifiedSince = -1; - try { - ifModifiedSince = request.getDateHeader(HEADER_IF_MODIFIED_SINCE); + String url = null; + if (log.isDebugEnabled()) { + if (request.getQueryString() == null) { + url = request.getRequestURI(); } - catch (Exception e) { - log.error("Exception while fetching If-Modified-Since: {}", e); + else { + StringBuilder builder = new StringBuilder(); + builder.append(request.getRequestURI()); + builder.append('?'); + builder.append(request.getQueryString()); + url = builder.toString(); } + } - long lastModified = cacheable.getLastModified(request); + int cacheSeconds = cacheable.getCacheSeconds(request); + if (cacheSeconds < 0) { + log.debug("{}: caching disabled!", url); + response.setDateHeader(HEADER_DATE, now); + response.setDateHeader(HEADER_EXPIRES, 0); + response.addHeader(HEADER_PRAGMA, "no-cache"); + response.addHeader(HEADER_CACHE_CONTROL, "private"); + response.addHeader(HEADER_CACHE_CONTROL, "no-cache"); + response.addHeader(HEADER_CACHE_CONTROL, "no-store"); + response.addHeader(HEADER_CACHE_CONTROL, "max-age=0"); + response.addHeader(HEADER_CACHE_CONTROL, "s-max-age=0"); + return true; + } + long ifModifiedSince = -1; + try { + ifModifiedSince = request.getDateHeader(HEADER_IF_MODIFIED_SINCE); + } + catch (Exception e) { + log.error("Exception while fetching If-Modified-Since: {}", e); + } + + long lastModified = cacheable.getLastModified(request); + + /** + * Sicherstellen, dass der Wert keine Millisekunden enthält, da die + * Zeitangabe aus dem Modified-Since-Header keine Millisekunden enthalten + * kann und der Test unten dann stets fehlschlagen würde! + */ + lastModified = lastModified - (lastModified % 1000); + + /** + * Cache-Control für HTTP/1.1-Clients generieren und setzen + * + * Nach {@plainlink http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-18#section-4.1 + * "HTTP/1.1, part 4: Conditional Requests", + * Abschnitt 4.1 "304 Not Modified" (Achtung: Entwurf -> work in progress!)} + * müssen die folgenden Felder in einer 304-Antwort + * enthalten sein, wenn sie auch in der ursprünglichen Antwort enthalten + * waren: + *
false
+ * zurückgeliefert werden!
+ *
+ * Den Wert als max-age
zu den Schlüssel-Wert-Paaren für den
+ * Cache-Control
-Header hinzufügen und einen entsprechenden
+ * Expires
-Header für HTTP/1.0-Clients setzen.
*/
- if (eTag != null) {
- response.setHeader(HEADER_ETAG, eTag);
- }
-
+ cacheControl.put("max-age", Integer.toString(cacheSeconds));
+ response.setDateHeader(HEADER_EXPIRES, (now + (long) cacheSeconds * 1000));
+ }
- if (ifModifiedSince >= lastModified && lastModified > 0) {
- /**
- * request.getDateHeader liefert die Zeit als long, oder -1, wenn der
- * Header nicht existiert. D.h., wenn "If-Modified-Since" nicht gesetzt
- * ist, wird die komplette Seite ausgeliefert.
- * Der zusätzliche Test, ob lastModified gröÃer 0 ist, ist nötig, um
- * Fehler auszuschlieÃen, wenn die Implementierung von Cachable
- * negative Werte für Last-Modified zurückliefert.
- */
- if (log.isDebugEnabled())
- log.debug("{}: Not modified since {}", url, new Date(ifModifiedSince));
-
- if (ifNoneMatch == null) {
- /** Neue Anfrage oder HTTP/1.0 Client! */
- log.debug("{}: ETag nicht gesetzt -> 304", url);
- response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
- return false;
- }
- }
-
- if (ifNoneMatch != null && ifNoneMatch.equals(eTag)) {
- log.debug("{}: ETag {} not changed -> 304 ", url, ifNoneMatch);
- response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
- return false;
+ StringBuilder builder = new StringBuilder();
+ for (Entryfalse
- * zurückgeliefert werden!
- *
- * Den Wert als max-age
zu den Schlüssel-Wert-Paaren für den
- * Cache-Control
-Header hinzufügen und einen entsprechenden
- * Expires
-Header für HTTP/1.0-Clients setzen.
- */
- cacheControl.put("max-age", Integer.toString(cacheSeconds));
- response.setDateHeader(HEADER_EXPIRES, (now + (long)cacheSeconds * 1000));
- }
+ if (log.isDebugEnabled())
+ log.debug("{}: Not modified since {}", url, new Date(ifModifiedSince));
- StringBuilder builder = new StringBuilder();
- for (Entry