Description:
This patch sets the cache-related headers properly, similarly to how the
embedded Tomcat did.
This is derived from code in my production Jetty server (the default
case is different of course) at home that has been running for a couple
of years.
Please review this at http://gwt-code-reviews.appspot.com/56807
Affected files:
dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java
Index: dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java
===================================================================
--- dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java
(revision 5915)
+++ dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java (working
copy)
@@ -19,6 +19,7 @@
import com.google.gwt.core.ext.ServletContainerLauncher;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.util.HttpHeaders;
import com.google.gwt.dev.util.InstalledHelpInfo;
import org.mortbay.component.AbstractLifeCycle;
@@ -40,6 +41,10 @@
import java.net.URL;
import java.util.Iterator;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
/**
* A {@link ServletContainerLauncher} for an embedded Jetty server.
*/
@@ -425,6 +430,53 @@
}
@Override
+ public void handle(String target, HttpServletRequest request,
+ HttpServletResponse response, int dispatch) throws IOException,
+ ServletException {
+ super.handle(target, request, response, dispatch);
+
+ // If the cache-control header has already been set, assume it
+ // has been set properly by the servlet/etc.
+ if (response.containsHeader(HttpHeaders.CACHE_CONTROL)) {
+ return;
+ }
+
+ // Set headers for caching -- unfortunately we can't get the status
+ // code from the response, but setting the extra headers on 304s/etc
+ // doesn't appear to cause any problems.
+ long now = System.currentTimeMillis();
+ response.setDateHeader(HttpHeaders.DATE, now);
+ if (!request.getMethod().equals("GET")) {
+ // to be safe, mark all non-GETs as non-cacheable
+ response.setHeader(HttpHeaders.CACHE_CONTROL,
+ HttpHeaders.CACHE_CONTROL_NO_CACHE);
+ // for older caches
+ response.setHeader("Pragma", "no-cache");
+ response.setDateHeader(HttpHeaders.EXPIRES, now);
+ } else if (target.contains(".nocache.")) {
+ // nocache is used for the selection script, and should be only
+ // privately cached, since it may vary on user-specific data, and
must be
+ // revalidated for each use
+ response.setHeader(HttpHeaders.CACHE_CONTROL,
+ HttpHeaders.CACHE_CONTROL_PRIVATE + ", "
+ + HttpHeaders.CACHE_CONTROL_MAXAGE + "0, "
+ + HttpHeaders.CACHE_CONTROL_MUST_REVALIDATE);
+ // Set expires to the same as Date to disable old proxy caches
+ response.setDateHeader(HttpHeaders.EXPIRES, now);
+ } else if (target.contains(".cache.")) {
+ // cache files should be cached for anyone forever (ie, 1 year)
+ response.setHeader("Cache-Control", "public, max-age=31536000");
+ response.setDateHeader(HttpHeaders.EXPIRES, now + 31536000000L);
+ } else {
+ // everything else gets public caching for 60 seconds
+ response.setHeader(HttpHeaders.CACHE_CONTROL,
+ HttpHeaders.CACHE_CONTROL_PUBLIC + ", "
+ + HttpHeaders.CACHE_CONTROL_MAXAGE + "60");
+ response.setDateHeader(HttpHeaders.EXPIRES, now + 6000);
+ }
+ }
+
+ @Override
protected void doStart() throws Exception {
setClassLoader(new WebAppClassLoaderExtension());
super.doStart();