You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by th...@apache.org on 2008/09/06 23:08:35 UTC

svn commit: r692738 - in /wicket/trunk/wicket/src: main/java/org/apache/wicket/protocol/http/WicketFilter.java test/java/org/apache/wicket/protocol/http/WicketFilterTest.java

Author: thrantal
Date: Sat Sep  6 14:08:35 2008
New Revision: 692738

URL: http://svn.apache.org/viewvc?rev=692738&view=rev
Log:
WICKET-1748: Adding Expires header to 304 responses, which should help with Apache mod_cache interoperability and Internet Explorer (6) caching

Modified:
    wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
    wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java?rev=692738&r1=692737&r2=692738&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java Sat Sep  6 14:08:35 2008
@@ -51,6 +51,7 @@
 import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
 import org.apache.wicket.util.string.Strings;
+import org.apache.wicket.util.time.Duration;
 import org.apache.wicket.util.time.Time;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -257,6 +258,7 @@
 					else
 					{
 						httpServletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+						httpServletResponse.setDateHeader("Expires", System.currentTimeMillis() + Duration.hours(1).getMilliseconds());
 					}
 				}
 			}

Modified: wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java?rev=692738&r1=692737&r2=692738&view=diff
==============================================================================
--- wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java (original)
+++ wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java Sat Sep  6 14:08:35 2008
@@ -16,14 +16,45 @@
  */
 package org.apache.wicket.protocol.http;
 
+import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
 
 import junit.framework.TestCase;
+import org.apache.wicket.Application;
+import org.apache.wicket.markup.html.image.resource.DynamicImageResource;
+import org.apache.wicket.util.tester.WicketTester.DummyWebApplication;
 
 public class WicketFilterTest extends TestCase
 {
+	private static WebApplication application;
+	private DateFormat fullDateFormat = DateFormat.getDateInstance(DateFormat.FULL);
+	private DateFormat headerDateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.UK);
+
+	@Override
+    protected void tearDown() throws Exception
+	{
+		application = null;
+	}
+
 	public void testFilterPath1()
 	{
 		InputStream in = WicketFilterTest.class.getResourceAsStream("web1.xml");
@@ -38,14 +69,56 @@
 		assertEquals("filtertest/", filterPath);
 	}
 
+	public void testNotModifiedResponseIncludesExpiresHeader() throws IOException, ServletException, ParseException
+	{
+		application = new DummyWebApplication();
+		WicketFilter filter = new WicketFilter();
+		filter.init(new FilterTestingConfig());
+		Application.set(application);
+		DynamicImageResource resource = new DynamicImageResource()
+		{
+			@Override
+            protected byte[] getImageData()
+			{
+				throw new UnsupportedOperationException("Not implemented");
+			}
+		};
+		resource.setCacheable(true);
+		application.getSharedResources().add("foo.gif", resource);
+		MockHttpServletRequest request = new MockHttpServletRequest(application, null, null);
+		request.setURL(request.getContextPath() +  "/app/" + "resources/" + Application.class.getName() + "/foo.gif");
+		setIfModifiedSinceToNextWeek(request);
+		MockHttpServletResponse response = new MockHttpServletResponse(request);
+		filter.doFilter(request, response, new FilterChain()
+		{
+			public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException
+			{
+			}
+		});
+		assertEquals(HttpServletResponse.SC_NOT_MODIFIED, response.getStatus());
+		String responseExpiresHeader = response.getHeader("Expires");
+		assertNotNull("Expires header must be set on not modified response", responseExpiresHeader);
+
+		Date responseExpires = headerDateFormat.parse(responseExpiresHeader);
+		assertTrue("Expected later than current date but was " + responseExpires, responseExpires.after(new Date()));
+	}
+
+	private void setIfModifiedSinceToNextWeek(MockHttpServletRequest request)
+	{
+		Calendar nextWeek = Calendar.getInstance();
+		nextWeek.add(Calendar.DATE, 7);
+		nextWeek.setTimeZone(TimeZone.getTimeZone("GMT"));
+		String ifModifiedSince = fullDateFormat.format(nextWeek.getTime());
+		request.addHeader("If-Modified-Since", ifModifiedSince);
+	}
+
 	private String getFilterPath(String string, InputStream in)
 	{
 		try
 		{
-			Method method = WicketFilter.class.getDeclaredMethod("getFilterPath", new Class[] {
-					String.class, InputStream.class });
+			Method method = WicketFilter.class.getDeclaredMethod("getFilterPath", String.class, InputStream.class);
 			method.setAccessible(true);
-			return method.invoke(new WicketFilter(), new Object[] { string, in }).toString();
+			return method.invoke(new WicketFilter(), string, in).toString();
 		}
 		catch (SecurityException e)
 		{
@@ -68,4 +141,43 @@
 			throw new RuntimeException(e);
 		}
 	}
+
+	private static class FilterTestingConfig implements FilterConfig
+	{
+		private Map<String,String> initParameters = new HashMap<String,String>();
+
+		public FilterTestingConfig() {
+			initParameters.put(WicketFilter.APP_FACT_PARAM, FilterTestingApplicationFactory.class.getName());
+			initParameters.put(WicketFilter.FILTER_MAPPING_PARAM, "/app/*");
+			initParameters.put(ContextParamWebApplicationFactory.APP_CLASS_PARAM, DummyWebApplication.class.getName());
+		}
+
+		public String getFilterName()
+		{
+			return getClass().getName();
+		}
+
+		public ServletContext getServletContext()
+		{
+			return new MockServletContext(null, null);
+		}
+
+		public String getInitParameter(String s)
+		{
+			return initParameters.get(s);
+		}
+
+		public Enumeration<String> getInitParameterNames()
+		{
+			throw new UnsupportedOperationException("Not implemented");
+		}
+	}
+
+	public static class FilterTestingApplicationFactory implements IWebApplicationFactory
+	{
+		public WebApplication createApplication(WicketFilter filter)
+		{
+			return application;
+		}
+	}
 }