You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by et...@apache.org on 2008/07/10 02:30:28 UTC

svn commit: r675389 - in /incubator/shindig/trunk/java/gadgets/src: main/java/org/apache/shindig/gadgets/http/HttpResponse.java test/java/org/apache/shindig/gadgets/http/HttpResponseTest.java

Author: etnu
Date: Wed Jul  9 17:30:28 2008
New Revision: 675389

URL: http://svn.apache.org/viewvc?rev=675389&view=rev
Log:
Added logic to deal with invalid HTTP date headers in responses better. Previously an invalid header would result in an NPE here.


Modified:
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java
    incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/HttpResponseTest.java

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java?rev=675389&r1=675388&r2=675389&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java Wed Jul  9 17:30:28 2008
@@ -73,6 +73,7 @@
   private final byte[] responseBytes;
   private final Map<String, List<String>> headers;
   private final Map<String, String> metadata;
+  private final long date;
 
   private HttpResponse rewritten;
 
@@ -119,10 +120,9 @@
         }
       }
     }
-    // Force Last-Modified header -- caches should be sure to store this value.
-    if (tmpHeaders.get("Date") == null) {
-      tmpHeaders.put("Date", Arrays.asList(DateUtil.formatDate(System.currentTimeMillis())));
-    }
+
+    date = getValidDate(tmpHeaders);
+
     this.headers = tmpHeaders;
 
     this.metadata = new HashMap<String, String>();
@@ -152,6 +152,31 @@
   }
 
   /**
+   * Tries to find a valid date from the input headers. If one can't be found, the current time is
+   * used.
+   *
+   * @param headers Input headers. If the Date header is missing or invalid, it will be set with the
+   *                current time.
+   * @return The value of the date header, in milliseconds.
+   */
+  private long getValidDate(Map<String, List<String>> headers) {
+    // Validate the Date header. Must conform to the HTTP date format.
+    long timestamp = -1;
+    String dateStr = headers.get("Date") == null ? null : headers.get("Date").get(0);
+    if (dateStr != null) {
+      Date d = DateUtil.parseDate(dateStr);
+      if (d != null) {
+        timestamp = d.getTime();
+      }
+    }
+    if (timestamp == -1) {
+      timestamp = System.currentTimeMillis();
+      headers.put("Date", Arrays.asList(DateUtil.formatDate(timestamp)));
+    }
+    return timestamp;
+  }
+
+  /**
    * Attempts to determine the encoding of the body. If it can't be determined,
    * we use DEFAULT_ENCODING instead.
    * @return The detected encoding or DEFAULT_ENCODING.
@@ -355,8 +380,7 @@
    * @return The value of the HTTP Date header.
    */
   protected long getDate() {
-    String date = getHeader("Date");
-    return DateUtil.parseDate(date).getTime();
+    return date;
   }
 
   /**

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/HttpResponseTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/HttpResponseTest.java?rev=675389&r1=675388&r2=675389&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/HttpResponseTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/HttpResponseTest.java Wed Jul  9 17:30:28 2008
@@ -175,14 +175,22 @@
     assertTrue(response.getCacheTtl() <= HttpResponse.DEFAULT_TTL && response.getCacheTtl() > 0);
   }
 
+  /**
+   * Verifies that the cache TTL is within acceptable ranges.
+   * This always rounds down due to timing, so actual verification will be against maxAge - 1.
+   */
+  private void assertTtlOk(int maxAge, HttpResponse response) {
+    assertEquals(maxAge - 1, roundToSeconds(response.getCacheTtl() - 1));
+  }
+
   public void testExpires() throws Exception {
-    int ttl = 10;
-    int time = roundToSeconds(System.currentTimeMillis()) + ttl;
+    int maxAge = 10;
+    int time = roundToSeconds(System.currentTimeMillis()) + maxAge;
     addHeader("Expires", DateUtil.formatDate(1000L * time));
     HttpResponse response = new HttpResponse(200, null, headers);
     assertEquals(time, roundToSeconds(response.getCacheExpiration()));
-    // 9 because of rounding.
-    assertEquals(9, roundToSeconds(response.getCacheTtl()));
+    // Second rounding makes this n-1.
+    assertTtlOk(maxAge, response);
   }
 
   public void testMaxAgeNoDate() throws Exception {
@@ -194,8 +202,20 @@
     int expiration = roundToSeconds(response.getCacheExpiration());
 
     assertEquals(expected, expiration);
-    // Second rounding makes this n-1.
-    assertEquals(maxAge - 1 , roundToSeconds(response.getCacheTtl()));
+    assertTtlOk(maxAge, response);
+  }
+
+  public void testMaxAgeInvalidDate() throws Exception {
+    int maxAge = 10;
+    // Guess time.
+    int expected = roundToSeconds(System.currentTimeMillis()) + maxAge;
+    addHeader("Date", "Wed, 09 Jul 2008 19:18:33 EDT");
+    addHeader("Cache-Control", "public, max-age=" + maxAge);
+    HttpResponse response = new HttpResponse(200, null, headers);
+    int expiration = roundToSeconds(response.getCacheExpiration());
+
+    assertEquals(expected, expiration);
+    assertTtlOk(maxAge, response);
   }
 
   public void testMaxAgeWithDate() throws Exception {
@@ -206,7 +226,7 @@
     HttpResponse response = new HttpResponse(200, null, headers);
 
     assertEquals(now + maxAge, roundToSeconds(response.getCacheExpiration()));
-    assertEquals(maxAge - 1, roundToSeconds(response.getCacheTtl()));
+    assertTtlOk(maxAge, response);
   }
 
   public void testFixedDate() throws Exception {
@@ -216,6 +236,7 @@
     assertEquals(time, roundToSeconds(response.getDate()));
     assertEquals(time + roundToSeconds(HttpResponse.DEFAULT_TTL),
         roundToSeconds(response.getCacheExpiration()));
+    assertTtlOk(roundToSeconds(HttpResponse.DEFAULT_TTL), response);
   }
 
   public void testNegativeCaching() {