Author: etnu
Date: Tue Jun 17 12:13:27 2008
New Revision: 668800

URL: http://svn.apache.org/viewvc?rev=668800&view=rev
Log:
Adding support for HttpUtil for client side caching only. This is important for 
iframes that have per-user data (the security token) that needs to be kept 
private as well as ensuring that you don't trash intermediate caches.


Modified:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTask.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HttpUtil.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTaskTest.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpUtilTest.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/MakeRequestHandlerTest.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyServletTest.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ServletTestFixture.java

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTask.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTask.java?rev=668800&r1=668799&r2=668800&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTask.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTask.java
 Tue Jun 17 12:13:27 2008
@@ -69,11 +69,12 @@
  * Represents a single rendering task
  */
 public class GadgetRenderingTask {
-  private static final String CAJA_PARAM = "caja";
-  private static final String LIBS_PARAM_NAME = "libs";
-  private static final Logger logger
+  protected static final int DEFAULT_CACHE_TTL = 60 * 5;
+  protected static final String CAJA_PARAM = "caja";
+  protected static final String LIBS_PARAM_NAME = "libs";
+  protected static final Logger logger
       = Logger.getLogger("org.apache.shindig.gadgets");
-  public static final String STRICT_MODE_DOCTYPE = "<!DOCTYPE HTML PUBLIC 
\"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\";>";
+  protected static final String STRICT_MODE_DOCTYPE = "<!DOCTYPE HTML PUBLIC 
\"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\";>";
 
   private HttpServletRequest request;
   private HttpServletResponse response;
@@ -311,11 +312,11 @@
       HttpUtil.setCachingHeaders(response, 0);
     } else if (request.getParameter("v") != null) {
       // Versioned files get cached indefinitely
-      HttpUtil.setCachingHeaders(response);
+      HttpUtil.setCachingHeaders(response, true);
     } else {
       // Unversioned files get cached for 5 minutes.
       // TODO: This should be configurable
-      HttpUtil.setCachingHeaders(response, 60 * 5);
+      HttpUtil.setCachingHeaders(response, DEFAULT_CACHE_TTL, true);
     }
     response.getWriter().print(markup.toString());
   }

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HttpUtil.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HttpUtil.java?rev=668800&r1=668799&r2=668800&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HttpUtil.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HttpUtil.java
 Tue Jun 17 12:13:27 2008
@@ -24,7 +24,7 @@
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import java.util.Set;
+import java.util.Collection;
 
 import javax.servlet.http.HttpServletResponse;
 
@@ -34,58 +34,85 @@
 public class HttpUtil {
   public static final long START_TIME = System.currentTimeMillis();
   // 1 year.
-  private static final int DEFAULT_TTL = 60 * 60 * 24 * 365;
+  public static final int DEFAULT_TTL = 60 * 60 * 24 * 365;
 
   /**
-   * Sets default caching Headers (Expires, Cache-Control, Last-Modified)
+   * Sets HTTP headers that instruct the browser to cache content. 
Implementations should take care
+   * to use cache-busting techniques on the url if caching for a long period 
of time.
    *
    * @param response The HTTP response
    */
   public static void setCachingHeaders(HttpServletResponse response) {
-    setCachingHeaders(response, DEFAULT_TTL);
+    setCachingHeaders(response, DEFAULT_TTL, false);
   }
 
   /**
-   * Sets HTTP headers that instruct the browser to cache content.
-   * Implementations should take care to use cache-busting techniques on the
-   * url.
+   * Sets HTTP headers that instruct the browser to cache content. 
Implementations should take care
+   * to use cache-busting techniques on the url if caching for a long period 
of time.
+   *
+   * @param response The HTTP response
+   * @param noProxy True if you don't want the response to be cacheable by 
proxies.
+   */
+  public static void setCachingHeaders(HttpServletResponse response, boolean 
noProxy) {
+    setCachingHeaders(response, DEFAULT_TTL, noProxy);
+  }
+
+  /**
+   * Sets HTTP headers that instruct the browser to cache content. 
Implementations should take care
+   * to use cache-busting techniques on the url if caching for a long period 
of time.
    *
    * @param response The HTTP response
    * @param ttl The time to cache for, in seconds. If 0, then insure that
-   * this object is not cached.
+   *            this object is not cached.
    */
   public static void setCachingHeaders(HttpServletResponse response, int ttl) {
-    response.setDateHeader("Expires",
-        System.currentTimeMillis() + (1000L * ttl));
+    setCachingHeaders(response, ttl, false);
+  }
+
+  /**
+   * Sets HTTP headers that instruct the browser to cache content. 
Implementations should take care
+   * to use cache-busting techniques on the url if caching for a long period 
of time.
+   *
+   * @param response The HTTP response
+   * @param ttl The time to cache for, in seconds. If 0, then insure that
+   *            this object is not cached.
+   * @param noProxy True if you don't want the response to be cacheable by 
proxies.
+   */
+  public static void setCachingHeaders(HttpServletResponse response, int ttl, 
boolean noProxy) {
+    response.setDateHeader("Expires", System.currentTimeMillis() + (1000L * 
ttl));
 
     if (ttl == 0) {
       response.setHeader("Pragma", "no-cache");
       response.setHeader("Cache-Control", "no-cache");
     } else {
-      // IE seems to need this (10 years should be enough).
-      response.setHeader("Cache-Control", "public,max-age=" +
-          Integer.toString(ttl));
+      if (noProxy) {
+        response.setHeader("Cache-Control", "private,max-age=" + 
Integer.toString(ttl));
+      } else {
+        response.setHeader("Cache-Control", "public,max-age=" + 
Integer.toString(ttl));
+      }
+      // Firefox requires this for certain cases.
+      response.setDateHeader("Last-Modified", START_TIME);
     }
-    // Firefox requires this for certain cases.
-    response.setDateHeader("Last-Modified", START_TIME);
   }
 
   /**
-   * Fetches js configuration for the given feature set & container
-   * @param config
-   * @param context
-   * @param features
+   * Fetches js configuration for the given feature set & container.
+   *
+   * @param config The configuration to extract js config from.
+   * @param context The request context.
+   * @param features A set of all features needed.
    */
-  public static JSONObject getJsConfig(ContainerConfig config,
-      GadgetContext context, Set<String> features) {
+  public static JSONObject getJsConfig(ContainerConfig config, GadgetContext 
context,
+      Collection<String> features) {
     JSONObject containerFeatures = config.getJsonObject(context.getContainer(),
-                                                   "gadgets.features");
+                                                        "gadgets.features");
     if (containerFeatures != null) {
       String[] featArray = features.toArray(new String[features.size()]);
       try {
         return new JSONObject(containerFeatures, featArray);
       } catch (JSONException e) {
-        return null;
+        // Can't happen.
+        throw new RuntimeException(e);
       }
     }
     return new JSONObject();

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTaskTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTaskTest.java?rev=668800&r1=668799&r2=668800&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTaskTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTaskTest.java
 Tue Jun 17 12:13:27 2008
@@ -21,8 +21,8 @@
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.isA;
 
-import org.apache.shindig.gadgets.ContainerConfig;
 import org.apache.shindig.common.testing.FakeGadgetToken;
+import org.apache.shindig.gadgets.ContainerConfig;
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.GadgetContext;
 import org.apache.shindig.gadgets.http.HttpRequest;
@@ -33,14 +33,13 @@
 import org.json.JSONArray;
 import org.json.JSONObject;
 
-import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
 import java.net.URI;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.List;
 
+// TODO: Migrate this to new Servlet testing setup.
 public class GadgetRenderingTaskTest extends HttpTestFixture {
 
   final static Enumeration<String> EMPTY_PARAMS = new Enumeration<String>() {
@@ -52,12 +51,10 @@
     }
   };
 
-  final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-  final PrintWriter writer = new PrintWriter(baos);
+  final ServletTestFixture fixture = new ServletTestFixture();
 
   final static URI SPEC_URL = URI.create("http://example.org/gadget.xml";);
-  final static HttpRequest SPEC_REQUEST
-      = new HttpRequest(SPEC_URL);
+  final static HttpRequest SPEC_REQUEST = new HttpRequest(SPEC_URL);
   final static String CONTENT = "Hello, world!";
   final static String ALT_CONTENT = "Goodbye, city.";
   final static String SPEC_XML
@@ -80,24 +77,25 @@
     expectLockedDomainCheck();
     expectWriteResponse();
     replay();
-    gadgetRenderer.process(request, response);
+    fixture.replay();
+    gadgetRenderer.process(fixture.request, fixture.recorder);
     verify();
-    writer.close();
-    return new String(baos.toByteArray(), "UTF-8");
+    fixture.verify();
+    return fixture.recorder.getResponseAsString();
   }
 
   private void expectParseRequestParams(String view) throws Exception {
-    expect(request.getParameter("url")).andReturn(SPEC_URL.toString());
-    expect(request.getParameter("view")).andReturn(view);
-    expect(request.getParameterNames()).andReturn(EMPTY_PARAMS);
-    expect(request.getParameter("container")).andReturn(null);
-    expect(request.getHeader("Host")).andReturn("www.example.com");
+    expect(fixture.request.getParameter("url")).andReturn(SPEC_URL.toString());
+    expect(fixture.request.getParameter("view")).andReturn(view);
+    expect(fixture.request.getParameterNames()).andReturn(EMPTY_PARAMS);
+    expect(fixture.request.getParameter("container")).andReturn(null);
+    expect(fixture.request.getHeader("Host")).andReturn("www.example.com");
   }
 
   private void expectLockedDomainCheck() throws Exception {
     expect(lockedDomainService.gadgetCanRender(
         EasyMock.eq("www.example.com"),
-        (Gadget)EasyMock.anyObject(),
+        isA(Gadget.class),
         EasyMock.eq("default"))).andReturn(true);
   }
 
@@ -106,8 +104,7 @@
   }
 
   private void expectWriteResponse() throws Exception {
-    expect(request.getParameter("libs")).andReturn(LIBS);
-    expect(response.getWriter()).andReturn(writer);
+    expect(fixture.request.getParameter("libs")).andReturn(LIBS);
   }
 
   public void testStandardsMode() throws Exception {
@@ -152,26 +149,26 @@
     expectLockedDomainFailure();
     expectSendRedirect();
     replay();
-    gadgetRenderer.process(request, response);
+    fixture.replay();
+    gadgetRenderer.process(fixture.request, response);
     verify();
-    writer.close();
+    fixture.verify();
   }
 
   private void expectLockedDomainFailure() {
     expect(lockedDomainService.gadgetCanRender(
         EasyMock.eq("www.example.com"),
-        (Gadget)EasyMock.anyObject(),
+        isA(Gadget.class),
         EasyMock.eq("default"))).andReturn(false);
-    expect(request.getScheme()).andReturn("http");
-    expect(request.getServletPath()).andReturn("/gadgets/ifr");
-    expect(request.getQueryString()).andReturn("stuff=foo%20bar");
+    expect(fixture.request.getScheme()).andReturn("http");
+    expect(fixture.request.getServletPath()).andReturn("/gadgets/ifr");
+    expect(fixture.request.getQueryString()).andReturn("stuff=foo%20bar");
     expect(lockedDomainService.getLockedDomainForGadget(
         SPEC_URL.toString(), "default")).andReturn("locked.example.com");
   }
 
   private void expectSendRedirect() throws Exception {
-    response.sendRedirect(
-        "http://locked.example.com/gadgets/ifr?stuff=foo%20bar";);
+    
response.sendRedirect("http://locked.example.com/gadgets/ifr?stuff=foo%20bar";);
     EasyMock.expectLastCall().once();
   }
 
@@ -202,7 +199,7 @@
   }
 
   public void testAuthTokenInjection_allparams() throws Exception {
-    expect(request.getParameter("st")).andReturn("fake-token");
+    expect(fixture.request.getParameter("st")).andReturn("fake-token");
     expect(securityTokenDecoder.createToken("fake-token")).andReturn(
         new FakeGadgetToken("updated-token", "{ 'foo' : 'bar' }"));
     String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
@@ -212,7 +209,7 @@
   }
 
   public void testAuthTokenInjection_none() throws Exception {
-    expect(request.getParameter("st")).andReturn("fake-token");
+    expect(fixture.request.getParameter("st")).andReturn("fake-token");
     expect(securityTokenDecoder.createToken("fake-token")).andReturn(
         new FakeGadgetToken());
     String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
@@ -221,7 +218,7 @@
   }
 
   public void testAuthTokenInjection_trustedJson() throws Exception {
-    expect(request.getParameter("st")).andReturn("fake-token");
+    expect(fixture.request.getParameter("st")).andReturn("fake-token");
     expect(securityTokenDecoder.createToken("fake-token")).andReturn(
         new FakeGadgetToken(null, "trusted"));
     String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
@@ -231,7 +228,7 @@
   }
 
   public void testAuthTokenInjection_updatedToken() throws Exception {
-    expect(request.getParameter("st")).andReturn("fake-token");
+    expect(fixture.request.getParameter("st")).andReturn("fake-token");
     expect(securityTokenDecoder.createToken("fake-token")).andReturn(
         new FakeGadgetToken("updated-token", null));
     String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
@@ -240,5 +237,22 @@
     assertEquals("updated-token", auth.getString("authToken"));
   }
 
+  public void testRenderSetsProperCacheControlHeaders() throws Exception {
+    String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
+    fixture.checkCacheControlHeaders(GadgetRenderingTask.DEFAULT_CACHE_TTL, 
true);
+  }
+
+  public void testRenderSetsLongLivedCacheControlHeadersWhenVParamIsSet() 
throws Exception {
+    expect(fixture.request.getParameter("v")).andReturn("some value");
+    String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
+    fixture.checkCacheControlHeaders(HttpUtil.DEFAULT_TTL, true);
+  }
+
+  public void testRenderSetsNoCacheHeadersWhenNoCacheParamIsSet() throws 
Exception {
+    expect(fixture.request.getParameter("nocache")).andReturn("1");
+    String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
+    fixture.checkCacheControlHeaders(0, true);
+  }
+
   // TODO: Lots of ugly tests on html content.
 }

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpUtilTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpUtilTest.java?rev=668800&r1=668799&r2=668800&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpUtilTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpUtilTest.java
 Tue Jun 17 12:13:27 2008
@@ -18,12 +18,9 @@
  */
 package org.apache.shindig.gadgets.servlet;
 
-import static org.easymock.EasyMock.anyLong;
-import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.classextension.EasyMock.createNiceMock;
 import static org.easymock.classextension.EasyMock.replay;
-import static org.easymock.classextension.EasyMock.verify;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
@@ -34,23 +31,68 @@
 import org.json.JSONObject;
 import org.junit.Test;
 
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
-import javax.servlet.http.HttpServletResponse;
-
 public class HttpUtilTest {
+  private final static String CONTAINER = "container";
+  private final static String FEATURE_0 = "featureZero";
+  private final static String FEATURE_1 = "feature-One";
+
+  private final ContainerConfig config = createNiceMock(ContainerConfig.class);
+  private final GadgetContext context = createNiceMock(GadgetContext.class);
+
+  private final ServletTestFixture fixture = new ServletTestFixture();
 
   @Test
   public void setCachingHeaders() {
-    HttpServletResponse response = createNiceMock(HttpServletResponse.class);
+    HttpUtil.setCachingHeaders(fixture.recorder);
+    fixture.replay();
+
+    fixture.checkCacheControlHeaders(HttpUtil.DEFAULT_TTL, false);
+  }
+
+  @Test
+  public void setCachingHeadersNoProxy() {
+    HttpUtil.setCachingHeaders(fixture.recorder, true);
+    fixture.replay();
+
+    fixture.checkCacheControlHeaders(HttpUtil.DEFAULT_TTL, true);
+  }
+
+  @Test
+  public void setCachingHeadersAllowProxy() {
+    HttpUtil.setCachingHeaders(fixture.recorder, false);
+    fixture.replay();
+
+    fixture.checkCacheControlHeaders(HttpUtil.DEFAULT_TTL, false);
+  }
+
+  @Test
+  public void setCachingHeadersFixedTtl() {
     int ttl = 10;
-    response.setDateHeader(eq("Expires"), anyLong());
-    response.setHeader("Cache-Control", "public,max-age=" + ttl);
-    response.setDateHeader(eq("Last-Modified"), anyLong());
-    replay(response);
-    HttpUtil.setCachingHeaders(response, ttl);
-    verify(response);
+    HttpUtil.setCachingHeaders(fixture.recorder, ttl);
+    fixture.replay();
+
+    fixture.checkCacheControlHeaders(ttl, false);
+  }
+
+  @Test
+  public void setCachingHeadersWithTtlAndNoProxy() {
+    int ttl = 20;
+    HttpUtil.setCachingHeaders(fixture.recorder, ttl, true);
+    fixture.replay();
+
+    fixture.checkCacheControlHeaders(ttl, true);
+  }
+
+  @Test
+  public void setCachingHeadersNoCache() {
+    HttpUtil.setCachingHeaders(fixture.recorder, 0);
+    fixture.replay();
+
+    fixture.checkCacheControlHeaders(0, true);
   }
 
   private void assertJsonEquals(JSONObject lhs, JSONObject rhs) throws 
JSONException {
@@ -68,23 +110,16 @@
 
   @Test
   public void getJsConfig() throws JSONException {
-    String feature0 = "featureZero";
-    String feature1 = "featureOne";
-
     JSONObject features = new JSONObject()
-        .put(feature0, "config")
-        .put(feature1, "other config");
-
-    String container = "container";
+        .put(FEATURE_0, "config")
+        .put(FEATURE_1, "other config");
 
-    ContainerConfig config = createNiceMock(ContainerConfig.class);
-    GadgetContext context = createNiceMock(GadgetContext.class);
     Set<String> needed = new HashSet<String>();
-    needed.add(feature0);
-    needed.add(feature1);
+    needed.add(FEATURE_0);
+    needed.add(FEATURE_1);
 
-    expect(context.getContainer()).andReturn(container);
-    expect(config.getJsonObject(container, "gadgets.features"))
+    expect(context.getContainer()).andReturn(CONTAINER);
+    expect(config.getJsonObject(CONTAINER, "gadgets.features"))
         .andReturn(features);
 
     replay(context);
@@ -92,4 +127,18 @@
 
     assertJsonEquals(features, HttpUtil.getJsConfig(config, context, needed));
   }
-}
+
+  @Test
+  public void getJsConfigNoFeatures() {
+    expect(context.getContainer()).andReturn(CONTAINER);
+    expect(config.getJsonObject(CONTAINER, "gadgets.features"))
+        .andReturn(null);
+
+    replay(context);
+    replay(config);
+
+    JSONObject results = HttpUtil.getJsConfig(config, context, 
Collections.<String>emptySet());
+
+    assertEquals("Results should be empty when there are no features", 0, 
results.length());
+  }
+}
\ No newline at end of file

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/MakeRequestHandlerTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/MakeRequestHandlerTest.java?rev=668800&r1=668799&r2=668800&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/MakeRequestHandlerTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/MakeRequestHandlerTest.java
 Tue Jun 17 12:13:27 2008
@@ -61,8 +61,6 @@
   private final ServletTestFixture fixture = new ServletTestFixture();
   private final MakeRequestHandler handler = new 
MakeRequestHandler(fixture.contentFetcherFactory,
       fixture.securityTokenDecoder, fixture.rewriter);
-  private final HttpServletResponseRecorder recorder
-      = new HttpServletResponseRecorder(fixture.response);
 
   private void expectGetAndReturnBody(String response) throws Exception {
     expectGetAndReturnBody(fixture.httpFetcher, response);
@@ -87,7 +85,7 @@
   }
 
   private JSONObject extractJsonFromResponse() throws JSONException {
-    String body = recorder.getResponseAsString();
+    String body = fixture.recorder.getResponseAsString();
     assertStartsWith(MakeRequestHandler.UNPARSEABLE_CRUFT, body);
     body = body.substring(MakeRequestHandler.UNPARSEABLE_CRUFT.length());
     return new JSONObject(body).getJSONObject(REQUEST_URL);
@@ -105,7 +103,7 @@
     expectGetAndReturnBody(RESPONSE_BODY);
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
 
     JSONObject results = extractJsonFromResponse();
     assertEquals(HttpResponse.SC_OK, results.getInt("rc"));
@@ -130,7 +128,7 @@
     
expect(fixture.request.getParameter(MakeRequestHandler.HEADERS_PARAM)).andReturn(headerString);
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     fixture.verify();
 
     assertEquals("bar", requests.get(0).getHeader("X-Foo"));
@@ -147,7 +145,7 @@
     
expect(fixture.request.getParameter(MakeRequestHandler.METHOD_PARAM)).andReturn("POST");
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     assertEquals(HttpResponse.SC_OK, results.getInt("rc"));
@@ -174,7 +172,7 @@
     
expect(fixture.request.getParameter(MakeRequestHandler.CONTENT_TYPE_PARAM)).andReturn("FEED");
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     JSONObject feed = new JSONObject(results.getString("body"));
@@ -218,7 +216,7 @@
     
expect(fixture.request.getParameter(MakeRequestHandler.CONTENT_TYPE_PARAM)).andReturn("FEED");
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     JSONObject feed = new JSONObject(results.getString("body"));
@@ -238,7 +236,7 @@
     expectGetAndReturnBody("");
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     assertEquals(HttpResponse.SC_OK, results.getInt("rc"));
@@ -258,7 +256,7 @@
         .andReturn(new HttpResponse(RESPONSE_BODY));
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     assertEquals(RESPONSE_BODY, results.get("body"));
@@ -276,7 +274,7 @@
         .andReturn(Auth.SIGNED.toString()).atLeastOnce();
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     assertEquals(RESPONSE_BODY, results.get("body"));
@@ -297,7 +295,7 @@
         .andReturn(Auth.SIGNED.toString()).atLeastOnce();
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     assertEquals(RESPONSE_BODY, results.get("body"));
@@ -317,7 +315,7 @@
         .andReturn(Auth.AUTHENTICATED.toString()).atLeastOnce();
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     assertEquals(HttpResponse.SC_OK, results.getInt("rc"));
@@ -330,7 +328,7 @@
     
expect(fixture.request.getParameter(Preload.AUTHZ_ATTR)).andReturn("garbage");
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     assertEquals(HttpResponse.SC_OK, results.getInt("rc"));
@@ -343,7 +341,7 @@
     expect(fixture.httpFetcher.fetch(request)).andReturn(HttpResponse.error());
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     assertEquals(HttpResponse.SC_INTERNAL_SERVER_ERROR, results.getInt("rc"));
@@ -359,10 +357,10 @@
         .andThrow(new SecurityTokenException("No!"));
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
 
     assertTrue("Response for bad tokens should not be SC_OK",
-        HttpServletResponse.SC_OK != recorder.getHttpStatusCode());
+        HttpServletResponse.SC_OK != fixture.recorder.getHttpStatusCode());
   }
 
   @Test
@@ -373,7 +371,7 @@
     expect(fixture.httpFetcher.fetch(request)).andReturn(response);
     fixture.replay();
 
-    handler.fetch(fixture.request, recorder);
+    handler.fetch(fixture.request, fixture.recorder);
     JSONObject results = extractJsonFromResponse();
 
     assertEquals(RESPONSE_BODY, results.getString("foo"));

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyServletTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyServletTest.java?rev=668800&r1=668799&r2=668800&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyServletTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyServletTest.java
 Tue Jun 17 12:13:27 2008
@@ -52,8 +52,6 @@
   private final ProxyHandler proxyHandler
       = new ProxyHandler(fixture.httpFetcher, fixture.lockedDomainService, 
fixture.rewriter);
   private final ProxyServlet servlet = new ProxyServlet();
-  private final HttpServletResponseRecorder recorder
-      = new HttpServletResponseRecorder(fixture.response);
   private final HttpRequest request = 
HttpRequest.getRequest(URI.create(REQUEST_URL), false);
   private final HttpResponse response = new HttpResponse(RESPONSE_BODY);
 
@@ -76,8 +74,8 @@
   }
 
   private void assertResponseOk(int expectedStatus, String expectedBody) {
-      assertEquals(expectedStatus, recorder.getHttpStatusCode());
-      assertEquals(expectedBody, recorder.getResponseAsString());
+      assertEquals(expectedStatus, fixture.recorder.getHttpStatusCode());
+      assertEquals(expectedBody, fixture.recorder.getResponseAsString());
   }
 
   @Test
@@ -86,7 +84,7 @@
     expect(fixture.httpFetcher.fetch(request)).andReturn(response);
     fixture.replay();
 
-    servlet.doGet(fixture.request, recorder);
+    servlet.doGet(fixture.request, fixture.recorder);
 
     assertResponseOk(HttpResponse.SC_OK, RESPONSE_BODY);
   }
@@ -97,7 +95,7 @@
     
expect(fixture.httpFetcher.fetch(request)).andReturn(HttpResponse.notFound());
     fixture.replay();
 
-    servlet.doGet(fixture.request, recorder);
+    servlet.doGet(fixture.request, fixture.recorder);
 
     assertResponseOk(HttpResponse.SC_NOT_FOUND, "");
   }
@@ -109,10 +107,10 @@
         new GadgetException(GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT, 
ERROR_MESSAGE));
     fixture.replay();
 
-    servlet.doGet(fixture.request, recorder);
+    servlet.doGet(fixture.request, fixture.recorder);
 
-    assertEquals(HttpServletResponse.SC_BAD_REQUEST, 
recorder.getHttpStatusCode());
-    assertContains(ERROR_MESSAGE, recorder.getResponseAsString());
+    assertEquals(HttpServletResponse.SC_BAD_REQUEST, 
fixture.recorder.getHttpStatusCode());
+    assertContains(ERROR_MESSAGE, fixture.recorder.getResponseAsString());
   }
 
   @Test
@@ -122,7 +120,7 @@
     expect(fixture.httpFetcher.fetch(request)).andReturn(response);
     fixture.replay();
 
-    servlet.doGet(fixture.request, recorder);
+    servlet.doGet(fixture.request, fixture.recorder);
 
     assertResponseOk(HttpResponse.SC_OK, RESPONSE_BODY);
   }

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ServletTestFixture.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ServletTestFixture.java?rev=668800&r1=668799&r2=668800&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ServletTestFixture.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ServletTestFixture.java
 Tue Jun 17 12:13:27 2008
@@ -18,11 +18,16 @@
  */
 package org.apache.shindig.gadgets.servlet;
 
+import static junitx.framework.ComparableAssert.assertEquals;
+import static junitx.framework.ComparableAssert.assertGreater;
+import static junitx.framework.ComparableAssert.assertLesser;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.isA;
+import static org.junit.Assert.assertTrue;
 
 import org.apache.shindig.common.SecurityToken;
 import org.apache.shindig.common.SecurityTokenDecoder;
+import org.apache.shindig.common.util.DateUtil;
 import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.LockedDomainService;
 import org.apache.shindig.gadgets.SigningFetcher;
@@ -33,9 +38,11 @@
 import org.apache.shindig.gadgets.rewrite.ContentRewriter;
 import org.apache.shindig.gadgets.rewrite.NoOpContentRewriter;
 
+import org.apache.commons.lang.StringUtils;
 import org.easymock.classextension.EasyMock;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
@@ -49,6 +56,7 @@
 
   public final HttpServletRequest request = mock(HttpServletRequest.class);
   public final HttpServletResponse response = mock(HttpServletResponse.class);
+  public final HttpServletResponseRecorder recorder = new 
HttpServletResponseRecorder(response);
   public final SecurityTokenDecoder securityTokenDecoder = 
mock(SecurityTokenDecoder.class);
   public final HttpFetcher httpFetcher = mock(HttpFetcher.class);
   public final SigningFetcher signingFetcher = mock(SigningFetcher.class);
@@ -71,6 +79,42 @@
     }
   }
 
+  private final long testStartTime = System.currentTimeMillis();
+
+  public void checkCacheControlHeaders(int ttl, boolean noProxy) {
+
+    long expires = DateUtil.parseDate(recorder.getHeader("Expires")).getTime();
+
+    // TODO: A better solution here would be an injectable clock. For now a 1 
second fudge is used.
+    long lowerBound = testStartTime + (1000L * (ttl - 1));
+    long upperBound = lowerBound + 6000L;
+
+    assertGreater("Expires should be at least " + ttl + " seconds more than 
start time.",
+        lowerBound, expires);
+
+    assertLesser("Expires should be within 5 seconds of the requested value.",
+        upperBound, expires);
+
+    if (ttl == 0) {
+      assertEquals("no-cache", recorder.getHeader("Pragma"));
+      assertEquals("no-cache", recorder.getHeader("Cache-Control"));
+    } else {
+      List<String> directives
+          = 
Arrays.asList(StringUtils.split(recorder.getHeader("Cache-Control"), ','));
+
+      assertTrue("Incorrect max-age set.", directives.contains("max-age=" + 
ttl));
+      if (noProxy) {
+        assertTrue("No private Cache-Control directive was set.", 
directives.contains("private"));
+      } else {
+        assertTrue("No public Cache-Control directive was set.", 
directives.contains("public"));
+      }
+
+      long lastModified = 
DateUtil.parseDate(recorder.getHeader("Last-Modified")).getTime();
+
+      assertGreater("Invalid Last-Modified header set.", 0L, lastModified);
+    }
+  }
+
   /**
    * Creates a strict mock object for the given class, adds it to the internal
    * list of all mocks, and returns it.


Reply via email to