Author: thrantal Date: Sat Sep 6 14:03:25 2008 New Revision: 692736 URL: http://svn.apache.org/viewvc?rev=692736&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/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java Modified: wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java URL: http://svn.apache.org/viewvc/wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java?rev=692736&r1=692735&r2=692736&view=diff ============================================================================== --- wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java (original) +++ wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java Sat Sep 6 14:03:25 2008 @@ -22,7 +22,6 @@ import java.text.ParseException; import java.util.ArrayList; import java.util.Properties; - import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -49,6 +48,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; @@ -224,6 +224,7 @@ else { httpServletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + httpServletResponse.setDateHeader("Expires", System.currentTimeMillis() + Duration.hours(1).getMilliseconds()); } } } Modified: wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java URL: http://svn.apache.org/viewvc/wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java?rev=692736&r1=692735&r2=692736&view=diff ============================================================================== --- wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java (original) +++ wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java Sat Sep 6 14:03:25 2008 @@ -16,14 +16,44 @@ */ 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); + + protected void tearDown() throws Exception + { + application = null; + } + public void testFilterPath1() { InputStream in = WicketFilterTest.class.getResourceAsStream("web1.xml"); @@ -38,6 +68,48 @@ 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() + { + 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 @@ -68,4 +140,43 @@ throw new RuntimeException(e); } } + + private static class FilterTestingConfig implements FilterConfig + { + private Map initParameters = new HashMap(); + + 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 (String) initParameters.get(s); + } + + public Enumeration getInitParameterNames() + { + throw new UnsupportedOperationException("Not implemented"); + } + } + + public static class FilterTestingApplicationFactory implements IWebApplicationFactory + { + public WebApplication createApplication(WicketFilter filter) + { + return application; + } + } }