Version 1.0.2: Header in 304-Antworten korrekt gesetzt 1.0.2
authorKai Moritz <kai@coolibri.de>
Fri, 20 Apr 2012 08:49:18 +0000 (10:49 +0200)
committerKai Moritz <kai@coolibri.de>
Sat, 21 Apr 2012 10:20:08 +0000 (12:20 +0200)
cachecontrol/pom.xml
cachecontrol/src/main/java/de/halbekunst/juplo/cachecontrol/CacheControlInterceptor.java
pom.xml

index 0db7fde..85d4217 100644 (file)
@@ -7,7 +7,7 @@
   <parent>
     <groupId>de.halbekunst</groupId>
     <artifactId>juplo</artifactId>
-    <version>1.0.1</version>
+    <version>1.0.2</version>
   </parent>
 
   <artifactId>${pom.parent.artifactId}-cachecontrol</artifactId>
index a830e3c..3d0c52d 100644 (file)
@@ -99,52 +99,36 @@ public class CacheControlInterceptor implements HandlerInterceptor {
      */
     lastModified = lastModified - (lastModified % 1000);
 
-    String ifNoneMatch = request.getHeader(HEADER_IF_NONE_MATCH);
-    String eTag = cacheable.getETag(request);
-
     /**
-     * 304-Antworten sollen nach dem {@plainlink
-     * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 RFC
-     * 2616, Abschnitt 10.3.5} einen ETag-Header enthalten, wenn auch die
-     * 200-Antwort einen enthalten hätte.
+     * 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!)}
+     * <strong>müssen</strong> die folgenden Felder in einer 304-Antwort
+     * enthalten sein, wenn sie auch in der ursprünglichen Antwort enthalten
+     * waren:
+     * <ul>
+     * <li>Cache-Control</li>
+     * <li>ETag</li>
+     * <li>Expires</li>
+     * <li>Last-Modified</li>
+     * <li>Vary</li>
+     * </ul>
      */
-    if (eTag != null)
-      response.setHeader(HEADER_ETAG, eTag);
-
-
-    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;
-    }
-
-
-    log.debug("{}: first up!", url);
-
-    /** HTTP/1.1-Caching-Header richtig setzen!! */
+    /**
+     * Der Last-Modified-Header sollte (darf?) eventuell eigntlich nur für
+     * 200-Antworten gesetzt werden
+     * (s. http://webmasters.stackexchange.com/questions/25520/should-30)
+     *
+     * Da Squid sonst scheinbar nicht korrekt cached (und per if-not-modified
+     * aktualisiert) wird der Header aber trotzdem erst mal weiter erzeugt!
+     * (Ggf. noch mal prüfen, ob es eine Sinnestäuschung war, dass Squid
+     * Resourcen öfter als nötig komplett neu holt, wenn dieser Header fehlt!)
+     */
     response.setDateHeader(HEADER_LAST_MODIFIED, lastModified);
 
-    /** Cache-Control für HTTP/1.1-Clients generieren */
     Map<String, String> cacheControl = new HashMap<String, String>(cacheable.getCacheControl(request));
 
     /**
@@ -164,7 +148,7 @@ public class CacheControlInterceptor implements HandlerInterceptor {
        * Abschnitt 14.32})
        */
       response.setDateHeader(HEADER_EXPIRES, 0l);
-      response.addHeader(HEADER_PRAGMA, "no-cache");
+      /** response.addHeader(HEADER_PRAGMA, "no-cache"); */
     } else {
       /**
        * Hier muss nicht geprüft werden, ob cacheSeconds > 0 gilt, da in diesem
@@ -190,6 +174,49 @@ public class CacheControlInterceptor implements HandlerInterceptor {
       response.addHeader(HEADER_CACHE_CONTROL, builder.toString());
     }
 
+
+    String ifNoneMatch = request.getHeader(HEADER_IF_NONE_MATCH);
+    String eTag = cacheable.getETag(request);
+
+    /**
+     * 304-Antworten sollen nach dem {@plainlink
+     * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 RFC
+     * 2616, Abschnitt 10.3.5} einen ETag-Header enthalten, wenn auch die
+     * 200-Antwort einen enthalten hätte.
+     */
+    if (eTag != null)
+      response.setHeader(HEADER_ETAG, eTag);
+
+
+    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;
+    }
+
+
+    log.debug("{}: first up!", url);
+
     return true;
   }
 
diff --git a/pom.xml b/pom.xml
index abd2bf7..7357a3c 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
 
   <groupId>de.halbekunst</groupId>
   <artifactId>juplo</artifactId>
-  <version>1.0.1</version>
+  <version>1.0.2</version>
   <name>Juplo</name>
   <packaging>pom</packaging>
   <url>http://www.halbekunst.de</url>
@@ -24,9 +24,7 @@
   </developers>
 
   <modules>
-    <module>test</module>
     <module>cachecontrol</module>
-    <module>utils</module>
   </modules>
 
   <properties>