Es werden nun vorerst doch auch 30x-Antworten werden dekoriert
[percentcodec] / cachecontrol / src / main / java / de / halbekunst / juplo / cachecontrol / CacheControl.java
index b248227..458979d 100644 (file)
@@ -1,5 +1,6 @@
 package de.halbekunst.juplo.cachecontrol;
 
+import de.halbekunst.juplo.cachecontrol.AcceleratorFilter.AccelerationWrapper;
 import de.halbekunst.juplo.cachecontrol.annotations.CacheSeconds;
 import de.halbekunst.juplo.cachecontrol.annotations.Accepts;
 import de.halbekunst.juplo.cachecontrol.annotations.AdditionalHeaders;
@@ -38,21 +39,20 @@ public class CacheControl {
     CacheControl.tl.set(handle);
   }
 
-  public void init(Object handler) throws NoSuchMethodException {
-    CacheControl.tl.set(new ReflectionCacheMethodHandle(handler));
+  void init(Object handler, AccelerationWrapper wrapper) throws NoSuchMethodException {
+    CacheControl.tl.set(new ReflectionCacheMethodHandle(handler, wrapper == null ? false : wrapper.zipped));
   }
 
   public boolean decorate(
       HttpServletRequest request,
-      HttpServletResponse response,
-      Object handler
+      HttpServletResponse response
       )
   {
     try {
-    CacheMethodHandle controller = CacheControl.tl.get();
+    CacheMethodHandle handle = CacheControl.tl.get();
 
     /** Doppelte Ausführung verhindern... */
-    if (controller == null) {
+    if (handle == null) {
       /** Dekoration wurde bereits durchgeführt! */
       return true;
     }
@@ -62,16 +62,25 @@ public class CacheControl {
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.18 RFC 2616,
      * Abschnitt 14.18} einen Date-Header enthalten
      */
-    response.setDateHeader(Headers.HEADER_DATE, controller.getTimestamp());
+    response.setDateHeader(Headers.HEADER_DATE, handle.getTimestamp());
 
     /** Besondere Maßnahmen für besondere HTTP-Status-Codes ?!? */
-    int status = controller.accepts(request);
+    int status = handle.accepts(request);
     switch (status) {
       case HttpServletResponse.SC_OK: // 200
       case HttpServletResponse.SC_NO_CONTENT: // 204
       case HttpServletResponse.SC_PARTIAL_CONTENT: // 206
         /** Normale Antwort! Antwort dekorieren... */
         break;
+      case HttpServletResponse.SC_MOVED_PERMANENTLY: // 301
+      case HttpServletResponse.SC_MOVED_TEMPORARILY: // 302
+      case HttpServletResponse.SC_SEE_OTHER: // 303
+      case HttpServletResponse.SC_NOT_MODIFIED: // 304
+      case HttpServletResponse.SC_USE_PROXY: // 305
+      case HttpServletResponse.SC_TEMPORARY_REDIRECT: // 307
+        /** Redirect-Antwort! Antwort dekodieren... */
+        // TODO: Kann das wirklich nicht zu Protokoll-Verletzungen führen?
+        break;
       case HttpServletResponse.SC_BAD_REQUEST: // 400
       case HttpServletResponse.SC_UNAUTHORIZED: // 401
       case HttpServletResponse.SC_PAYMENT_REQUIRED: // 402
@@ -93,16 +102,15 @@ public class CacheControl {
       case HttpServletResponse.SC_NOT_IMPLEMENTED: // 501
       case HttpServletResponse.SC_SERVICE_UNAVAILABLE: // 503
       case HttpServletResponse.SC_HTTP_VERSION_NOT_SUPPORTED: // 505
-        return true;
       default:
         /**
          * Es ist nicht klar, was der Handler noch machen wird/muss:
          * Antwort nicht dekorieren und Kontroller an den Handler übergeben...
          */
-        return false;
+        return true;
     }
 
-    Map<String,String> headers = controller.getAdditionalHeaders(request);
+    Map<String,String> headers = handle.getAdditionalHeaders(request);
     for (String name : headers.keySet())
       response.addHeader(name, headers.get(name));
 
@@ -120,10 +128,10 @@ public class CacheControl {
       }
     }
 
-    int cacheSeconds = controller.getCacheSeconds(request);
-    if (cacheSeconds < 1) {
+    int cacheSeconds = handle.getCacheSeconds(request);
+    if (cacheSeconds < 0) {
       log.debug("{}: caching disabled!", url);
-      response.setDateHeader(Headers.HEADER_DATE, controller.getTimestamp());
+      response.setDateHeader(Headers.HEADER_DATE, handle.getTimestamp());
       response.setDateHeader(Headers.HEADER_EXPIRES, 0);
       response.addHeader(Headers.HEADER_PRAGMA, "no-cache");
       response.addHeader(Headers.HEADER_CACHE_CONTROL, "private");
@@ -131,6 +139,8 @@ public class CacheControl {
       response.addHeader(Headers.HEADER_CACHE_CONTROL, "no-store");
       response.addHeader(Headers.HEADER_CACHE_CONTROL, "max-age=0");
       response.addHeader(Headers.HEADER_CACHE_CONTROL, "s-max-age=0");
+      if (handle.isZipped())
+        response.addHeader(Headers.HEADER_CONTENT_ENCODING, "gzip");
       return true;
     }
 
@@ -142,7 +152,7 @@ public class CacheControl {
       log.error("Exception while fetching If-Modified-Since: {}", e);
     }
 
-    long lastModified = controller.getLastModified(request);
+    long lastModified = handle.getLastModified(request);
 
     /**
      * Sicherstellen, dass der Wert keine Millisekunden enthält, da die
@@ -152,7 +162,7 @@ public class CacheControl {
     lastModified = lastModified - (lastModified % 1000);
 
     String ifNoneMatch = request.getHeader(Headers.HEADER_IF_NONE_MATCH);
-    String eTag = controller.getETag(request);
+    String eTag = handle.getETag(request);
 
     /**
      * 304-Antworten sollen nach dem {@plainlink
@@ -162,7 +172,7 @@ public class CacheControl {
      */
     if (eTag != null) {
       StringBuilder builder = new StringBuilder();
-      if (controller.isETagWeak())
+      if (handle.isETagWeak())
         builder.append("W/");
       builder.append('"');
       builder.append(eTag);
@@ -207,7 +217,7 @@ public class CacheControl {
          * Antwort stark sind (starke Gleichheit!), oder wenn die Antwort nur
          * schwache Gleichheit fordert...
          */
-        if (ifNoneMatch.equals(eTag) && (controller.isETagWeak() || !weak)) {
+        if (ifNoneMatch.equals(eTag) && (handle.isETagWeak() || !weak)) {
           log.debug("{}: ETag {} not changed -> 304 ", url, ifNoneMatch);
           response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
           return false;
@@ -221,6 +231,9 @@ public class CacheControl {
 
     log.debug("{}: first up!", url);
 
+    if (handle.isZipped())
+      response.addHeader(Headers.HEADER_CONTENT_ENCODING, "gzip");
+
     /** HTTP/1.1-Caching-Header richtig setzen!! */
     response.setDateHeader(Headers.HEADER_LAST_MODIFIED, lastModified);
 
@@ -245,11 +258,11 @@ public class CacheControl {
        * <code>Expires</code>-Header für HTTP/1.0-Clients setzen.
        */
       cacheControl.put("max-age", Integer.toString(cacheSeconds));
-      response.setDateHeader(Headers.HEADER_EXPIRES, (controller.getTimestamp() + (long) cacheSeconds * 1000));
+      response.setDateHeader(Headers.HEADER_EXPIRES, (handle.getTimestamp() + (long) cacheSeconds * 1000));
     }
 
     /** Dem Handler die Gelegenheit geben, den Cache-Controll-Header anzupassen */
-    controller.cacheControl(request, cacheControl);
+    handle.cacheControl(request, cacheControl);
 
 
     if (cacheControl.containsKey("private")) {
@@ -293,18 +306,6 @@ public class CacheControl {
   }
 
 
-  public interface CacheMethodHandle {
-    long getTimestamp();
-    int accepts(HttpServletRequest request);
-    int getCacheSeconds(HttpServletRequest request);
-    long getLastModified(HttpServletRequest request);
-    String getETag(HttpServletRequest request);
-    boolean isETagWeak();
-    void cacheControl(HttpServletRequest request, Map<String, String> cacheControlMap);
-    Map<String,String> getAdditionalHeaders(HttpServletRequest request);
-  }
-
-
   class ReflectionCacheMethodHandle implements CacheMethodHandle {
 
     private Object handler;
@@ -326,15 +327,16 @@ public class CacheControl {
     private boolean isCacheControlMethodDefined;
     private boolean isAdditionalHeadersMethodDefined;
     private boolean weak;
+    private boolean zipped;
 
 
-    ReflectionCacheMethodHandle(Object handler) throws NoSuchMethodException {
+    ReflectionCacheMethodHandle(Object handler, boolean zipped) throws NoSuchMethodException {
 
       this.handler = handler;
+      this.zipped = zipped;
 
       cacheSeconds = CacheControl.this.defaultCacheSeconds;
       lastModified = CacheControl.this.defaultLastModified;
-      eTag = "";
 
       /** Class-Level-Annotations auslesen */
       for (Annotation annotation : handler.getClass().getAnnotations()) {
@@ -436,6 +438,11 @@ public class CacheControl {
     }
 
 
+    @Override
+    public boolean isZipped() {
+      return zipped;
+    }
+
     @Override
     public long getTimestamp() {
       return now;