abdera-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmsn...@apache.org
Subject svn commit: r431393 - in /incubator/abdera/java/trunk/client/src: main/java/org/apache/abdera/protocol/client/CommonsClient.java main/java/org/apache/abdera/protocol/client/RequestOptions.java test/java/org/apache/abdera/test/client/cache/CacheTest.java
Date Mon, 14 Aug 2006 18:15:30 GMT
Author: jmsnell
Date: Mon Aug 14 11:15:30 2006
New Revision: 431393

URL: http://svn.apache.org/viewvc?rev=431393&view=rev
Log:
If authentication is used, add a requestoptions to force the cache to revalidate
Add test checking to make sure the requestoption works
Add tests for checking response no-cache, no-store and maxage=0

Modified:
    incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/CommonsClient.java
    incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/RequestOptions.java
    incubator/abdera/java/trunk/client/src/test/java/org/apache/abdera/test/client/cache/CacheTest.java

Modified: incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/CommonsClient.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/CommonsClient.java?rev=431393&r1=431392&r2=431393&view=diff
==============================================================================
--- incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/CommonsClient.java
(original)
+++ incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/CommonsClient.java
Mon Aug 14 11:15:30 2006
@@ -70,6 +70,18 @@
         options.getUseLocalCache();
   }
   
+  private boolean mustRevalidate(RequestOptions options, CachedResponse response) {
+    if (options.getRevalidateWithAuth()) {
+      if (options.getAuthorization() != null) return true;
+      if (client.getParams().getBooleanParameter(
+        HttpClientParams.PREEMPTIVE_AUTHENTICATION, false)) return true;
+      if (response != null) {
+        if (response.isPublic()) return false;
+      }
+    }
+    return false;
+  }
+  
   @Override
   public Response execute(
     String method, 
@@ -84,14 +96,22 @@
             cache.getDisposition(uri, options) : 
             CacheDisposition.TRANSPARENT;
         CachedResponse cached_response = cache.get(uri, options);
+        disp = (!disp.equals(CacheDisposition.TRANSPARENT) && 
+                mustRevalidate(options, cached_response)) ? 
+                  CacheDisposition.STALE : 
+                  disp;
         switch(disp) {
           case FRESH:                                                            // CACHE
HIT: FRESH
             if (cached_response != null)
               return cached_response;
           case STALE:                                                            // CACHE
HIT: STALE
             // revalidate the cached entry
-            options.setIfModifiedSince(cached_response.getLastModified());
-            options.setIfNoneMatch(cached_response.getEntityTag());
+            if (cached_response != null) {
+              options.setIfModifiedSince(cached_response.getLastModified());
+              options.setIfNoneMatch(cached_response.getEntityTag());
+            } else {
+              disp = CacheDisposition.TRANSPARENT;
+            }
           default:                                                               // CACHE
MISS
             HttpMethod httpMethod = 
               MethodHelper.createMethod(
@@ -103,6 +123,7 @@
               response;
         }
       } catch (Throwable t) {
+        t.printStackTrace();
         throw new ClientException(t);
       }
   }
@@ -111,7 +132,7 @@
   public RequestOptions getDefaultRequestOptions() {
     return MethodHelper.createDefaultRequestOptions();
   }
-
+  
   @Override
   public void addCredentials(
     String target,

Modified: incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/RequestOptions.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/RequestOptions.java?rev=431393&r1=431392&r2=431393&view=diff
==============================================================================
--- incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/RequestOptions.java
(original)
+++ incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/RequestOptions.java
Mon Aug 14 11:15:30 2006
@@ -41,6 +41,7 @@
   private long max_stale = -1;
   private long min_fresh = -1;
   private boolean noLocalCache = false;
+  private boolean revalidateAuth = false;
   
   private Map<String,List<String>> headers = null;  
   
@@ -363,4 +364,11 @@
     buf.append(value);
   }
   
+  public boolean getRevalidateWithAuth() {
+    return revalidateAuth;
+  }
+  
+  public void setRevalidateWithAuth(boolean revalidateAuth) {
+    this.revalidateAuth= revalidateAuth;
+  }
 }

Modified: incubator/abdera/java/trunk/client/src/test/java/org/apache/abdera/test/client/cache/CacheTest.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/client/src/test/java/org/apache/abdera/test/client/cache/CacheTest.java?rev=431393&r1=431392&r2=431393&view=diff
==============================================================================
--- incubator/abdera/java/trunk/client/src/test/java/org/apache/abdera/test/client/cache/CacheTest.java
(original)
+++ incubator/abdera/java/trunk/client/src/test/java/org/apache/abdera/test/client/cache/CacheTest.java
Mon Aug 14 11:15:30 2006
@@ -17,6 +17,7 @@
 */
 package org.apache.abdera.test.client.cache;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -30,6 +31,7 @@
 import org.apache.abdera.protocol.client.CommonsClient;
 import org.apache.abdera.protocol.client.RequestOptions;
 import org.apache.abdera.protocol.client.Response;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
 
 import junit.framework.TestCase;
 
@@ -53,11 +55,12 @@
 
   private static final String PORT_PROP = "abdera.test.client.cache.port";
   private static String CHECK_CACHE_INVALIDATE;
+  private static String CHECK_NO_CACHE;
+  private static String CHECK_AUTH;
   private static int PORT;
-  
-  private static Server server;
 
-  private static int NUM_TESTS = 3;
+  private static Server server;
+  private static int NUM_TESTS = 10;
   private static int testsRun  = 0;
 
   static {
@@ -67,7 +70,9 @@
       PORT = 8080;
     }
     
-    CHECK_CACHE_INVALIDATE = "http://localhost:" + PORT + "/";
+    CHECK_CACHE_INVALIDATE = "http://localhost:" + PORT + "/check_cache_invalidate";
+    CHECK_NO_CACHE = "http://localhost:" + PORT + "/no_cache";
+    CHECK_AUTH = "http://localhost:" + PORT + "/auth";
 
     server = new Server();
 
@@ -82,10 +87,17 @@
     server.setHandler(handler);
 
     handler.addServletWithMapping(
-      "org.apache.abdera.test.client.cache.CacheTest$Servlet",
-      "/"
+      "org.apache.abdera.test.client.cache.CacheTest$CheckCacheInvalidateServlet",
+      "/check_cache_invalidate"
+    );
+    handler.addServletWithMapping(
+      "org.apache.abdera.test.client.cache.CacheTest$NoCacheServlet",
+      "/no_cache"
+    );
+    handler.addServletWithMapping(
+      "org.apache.abdera.test.client.cache.CacheTest$AuthServlet",
+      "/auth"
     );
-
     try {
       server.start();
     } catch (Exception e) {
@@ -97,8 +109,9 @@
     if (++testsRun == NUM_TESTS)
       server.stop();
   }
-
-  public static class Servlet extends HttpServlet {
+  
+  @SuppressWarnings("serial")
+  public static class CheckCacheInvalidateServlet extends HttpServlet {
     protected void doGet(HttpServletRequest request,
                          HttpServletResponse response)
       throws ServletException, IOException
@@ -114,34 +127,191 @@
     }
   }
 
+  @SuppressWarnings("serial")
+  public static class NoCacheServlet extends HttpServlet {
+    protected void doGet(HttpServletRequest request,
+                         HttpServletResponse response)
+      throws ServletException, IOException
+    {
+      String reqnum = request.getHeader("X-Reqnum");
+      int reqtest = Integer.parseInt(request.getHeader("X-Reqtest"));
+
+      response.setContentType("text/plain");
+      response.setStatus(HttpServletResponse.SC_OK);
+      switch(reqtest) {
+        case NOCACHE: response.setHeader("Cache-Control", "no-cache"); break;
+        case NOSTORE: response.setHeader("Cache-Control", "no-store"); break;
+        case MAXAGE0: response.setHeader("Cache-Control", "max-age=0"); break;
+      }
+      response.setDateHeader("Date", System.currentTimeMillis());
+
+      response.getWriter().println(reqnum);
+    }
+  }
+  
+  @SuppressWarnings("serial")
+  public static class AuthServlet extends HttpServlet {
+    protected void doGet(HttpServletRequest request,
+                         HttpServletResponse response)
+      throws ServletException, IOException
+    {
+      String reqnum = request.getHeader("X-Reqnum");
+      int num = Integer.parseInt(reqnum);
+      response.setContentType("text/plain");
+      switch (num) {
+        case 1: response.setStatus(HttpServletResponse.SC_OK); break;
+        case 2: response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); break;
+        default:
+          response.setStatus(HttpServletResponse.SC_OK); break;
+      }
+      response.setDateHeader("Date", System.currentTimeMillis());
+      response.getWriter().println(reqnum);
+    }
+  }
+  
+  private static final int NOCACHE = 0;
+  private static final int NOSTORE = 1;
+  private static final int MAXAGE0 = 2;
+  private static final int POST = 3;
+  private static final int DELETE = 4;
+  private static final int PUT = 5;
+  
   public static void testRequestNoStore() throws Exception {
-    
-      Client client = new CommonsClient();
-      RequestOptions options = client.getDefaultRequestOptions();
-      options.setHeader("x-reqnum", "1");
-      Response response = client.get(CHECK_CACHE_INVALIDATE, options);
-    
-      String resp1 = getResponse(response.getInputStream());
-      assertEquals(resp1, "1");
-      
-      // Should not use the cache
-      options.setHeader("x-reqnum", "2");
-      options.setNoStore(true);
-      response = client.get(CHECK_CACHE_INVALIDATE, options);
-    
-      String resp2 = getResponse(response.getInputStream());
-      assertEquals(resp2, "2");
-      
-      // Should use the cache
-      options.setHeader("x-reqnum", "3");
-      options.setNoStore(false);
-      response = client.get(CHECK_CACHE_INVALIDATE, options);
-    
-      String resp3 = getResponse(response.getInputStream());
-      assertEquals(resp3, "2");
+    _requestCacheInvalidation(NOSTORE);
   }
 
   public static void testRequestNoCache() throws Exception {
+    _requestCacheInvalidation(NOCACHE);    
+  }
+  
+  public static void testRequestMaxAge0() throws Exception {
+    _requestCacheInvalidation(MAXAGE0);
+  }
+
+  public static void testResponseNoStore() throws Exception {
+    _responseNoCache(NOSTORE);
+  }
+
+  public static void testResponseNoCache() throws Exception {
+    _responseNoCache(NOCACHE);
+  }
+  
+  public static void testResponseMaxAge0() throws Exception {
+    _responseNoCache(MAXAGE0);
+  }
+  
+  public static void testPostInvalidates() throws Exception {
+    _methodInvalidates(POST);
+  }
+
+  public static void testPutInvalidates() throws Exception {
+    _methodInvalidates(PUT);
+  }
+  
+  public static void testDeleteInvalidates() throws Exception {
+    _methodInvalidates(DELETE);
+  }
+  
+  public static void testAuthForcesRevalidation() throws Exception {
+    
+    // the revalidatewithauth mechanism allows us to revalidate the 
+    // cache when authentication is used, meaning that we'll only
+    // be served data from the cache if our authentication credentials
+    // are valid.
+    
+    // unfortunately, this only works for preemptive auth and auth using
+    // the RequestOptions.setAuthorization method.  I'm not quite sure
+    // yet how to plug into httpclient's built in auth mechanisms to 
+    // ensure we can invalidate the cache.    
+    
+    Client client = new CommonsClient();
+    client.usePreemptiveAuthentication(true);
+    client.addCredentials(CHECK_AUTH, null, null, new UsernamePasswordCredentials("james","snell"));
+    RequestOptions options = client.getDefaultRequestOptions();
+    options.setRevalidateWithAuth(true);
+    options.setHeader("x-reqnum", "1");
+    Response response = client.get(CHECK_AUTH, options);
+  
+    // first request works as expected. fills the cache
+    String resp1 = getResponse(response.getInputStream());
+    assertEquals(resp1, "1");
+
+    // second request uses authentication, should force revalidation of the cache
+    options.setHeader("x-reqnum", "2");
+    response = client.get(CHECK_AUTH, options);
+  
+    resp1 = getResponse(response.getInputStream());
+    assertEquals(response.getStatus(), HttpServletResponse.SC_UNAUTHORIZED);
+    assertEquals(resp1, "2");
+
+    // third request does not use authentication, but since the previous request
+    // resulted in an "unauthorized" response, the cache needs to be refilled
+    options.setHeader("x-reqnum", "3");
+    client.usePreemptiveAuthentication(false);
+    response = client.get(CHECK_AUTH, options);
+  
+    resp1 = getResponse(response.getInputStream());
+    assertEquals(response.getStatus(), HttpServletResponse.SC_OK);
+    assertEquals(resp1, "3");  
+
+    // fourth request does not use authentication, will pull from the cache
+    options.setHeader("x-reqnum", "4");
+    response = client.get(CHECK_AUTH, options);
+  
+    resp1 = getResponse(response.getInputStream());
+    assertEquals(response.getStatus(), HttpServletResponse.SC_OK);
+    assertEquals(resp1, "3");  
+    
+    // fifth request uses authentication, will force revalidation
+    options.setAuthorization("Basic amFtZXM6c25lbGw=");
+    options.setHeader("x-reqnum", "5");
+    response = client.get(CHECK_AUTH, options);
+    
+    resp1 = getResponse(response.getInputStream());
+    assertEquals(response.getStatus(), HttpServletResponse.SC_OK);
+    assertEquals(resp1, "5");
+  }
+  
+  private static void _methodInvalidates(int type) throws Exception {
+    
+    Client client = new CommonsClient();
+    RequestOptions options = client.getDefaultRequestOptions();
+    options.setHeader("x-reqnum", "1");
+    Response response = client.get(CHECK_CACHE_INVALIDATE, options);
+  
+    String resp1 = getResponse(response.getInputStream());
+    assertEquals(resp1, "1");
+    
+    // calling a method that could change state on the server should invalidate the cache
+    options.setHeader("x-reqnum", "2");
+    switch(type) {
+      case POST:  
+        client.post(
+          CHECK_CACHE_INVALIDATE, 
+          new ByteArrayInputStream("".getBytes()), 
+          options);
+        break;
+      case PUT:
+        client.put(
+          CHECK_CACHE_INVALIDATE, 
+          new ByteArrayInputStream("".getBytes()), 
+          options);
+        break;
+      case DELETE:
+        client.delete(
+          CHECK_CACHE_INVALIDATE, 
+          options);
+        break;
+    }
+    
+    options.setHeader("x-reqnum", "3");
+    response = client.get(CHECK_CACHE_INVALIDATE, options);
+  
+    resp1 = getResponse(response.getInputStream());
+    assertEquals(resp1, "3");
+  }
+  
+  private static void _requestCacheInvalidation(int type) throws Exception {
     
     Client client = new CommonsClient();
     RequestOptions options = client.getDefaultRequestOptions();
@@ -153,7 +323,11 @@
     
     // Should not use the cache
     options.setHeader("x-reqnum", "2");
-    options.setNoCache(true);
+    switch(type) {
+      case NOCACHE: options.setNoCache(true); break;
+      case NOSTORE: options.setNoStore(true); break;
+      case MAXAGE0: options.setMaxAge(0); break;
+    }
     response = client.get(CHECK_CACHE_INVALIDATE, options);
   
     String resp2 = getResponse(response.getInputStream());
@@ -161,40 +335,42 @@
     
     // Should use the cache
     options.setHeader("x-reqnum", "3");
-    options.setNoCache(false);
+    switch(type) {
+      case NOCACHE: options.setNoCache(false); break;
+      case NOSTORE: options.setNoStore(false); break;
+      case MAXAGE0: options.setMaxAge(60); break;
+    }
     response = client.get(CHECK_CACHE_INVALIDATE, options);
   
     String resp3 = getResponse(response.getInputStream());
     assertEquals(resp3, "2");
   }
   
-  public static void testRequestMaxAge() throws Exception {
+  private static void _responseNoCache(int type) throws Exception {
     
     Client client = new CommonsClient();
     RequestOptions options = client.getDefaultRequestOptions();
     options.setHeader("x-reqnum", "1");
-    Response response = client.get(CHECK_CACHE_INVALIDATE, options);
+    options.setHeader("x-reqtest", String.valueOf(type));
+    Response response = client.get(CHECK_NO_CACHE, options);
   
     String resp1 = getResponse(response.getInputStream());
     assertEquals(resp1, "1");
     
     // Should not use the cache
     options.setHeader("x-reqnum", "2");
-    options.setMaxAge(0);
-    response = client.get(CHECK_CACHE_INVALIDATE, options);
+    response = client.get(CHECK_NO_CACHE, options);
   
     String resp2 = getResponse(response.getInputStream());
     assertEquals(resp2, "2");
     
     // Should use the cache
     options.setHeader("x-reqnum", "3");
-    options.setMaxAge(60);
-    response = client.get(CHECK_CACHE_INVALIDATE, options);
+    response = client.get(CHECK_NO_CACHE, options);
   
     String resp3 = getResponse(response.getInputStream());
-    assertEquals(resp3, "2");
+    assertEquals(resp3, "3");
   }
-
   
   private static String getResponse(InputStream in) throws IOException {
     ByteArrayOutputStream out = new ByteArrayOutputStream();



Mime
View raw message