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;
+ }
+ }
}