Fix caching rules by upgrading to gwtexpui 1.3

Use the new CacheHeaders class to define consistent caching rules
throughout the code. This removes a lot of copy-and-paste for the
setNotCacheable case, and ensures cacheable rules are consistent
with the way CacheControlFilter works on secure responses.

Change-Id: Ibdf1d76095e3623980b4ca8585cf654a5018b553
This commit is contained in:
Shawn Pearce 2013-01-11 12:39:45 -08:00
parent 89136bc832
commit 1756441516
19 changed files with 52 additions and 84 deletions

View File

@ -26,6 +26,7 @@ import com.google.gerrit.server.account.AccountException;
import com.google.gerrit.server.account.AccountManager;
import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.account.AuthResult;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.gwtorm.server.SchemaFactory;
@ -76,9 +77,7 @@ public class BecomeAnyAccountLoginServlet extends HttpServlet {
@Override
protected void doPost(final HttpServletRequest req,
final HttpServletResponse rsp) throws IOException, ServletException {
rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(rsp);
final AuthResult res;
if ("create_account".equals(req.getParameter("action"))) {

View File

@ -17,6 +17,7 @@ package com.google.gerrit.httpd.auth.container;
import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.httpd.raw.HostPageServlet;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtjsonrpc.server.RPCServletUtils;
import com.google.inject.Inject;
import com.google.inject.Provider;
@ -87,9 +88,7 @@ class HttpAuthFilter implements Filter {
tosend = signInRaw;
}
rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(rsp);
rsp.setContentType("text/html");
rsp.setCharacterEncoding(HtmlDomUtil.ENC);
rsp.setContentLength(tosend.length);

View File

@ -23,6 +23,7 @@ import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.account.AuthResult;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@ -85,10 +86,7 @@ class HttpLoginServlet extends HttpServlet {
return;
}
rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(rsp);
final String user = getRemoteUser(req);
if (user == null || "".equals(user)) {
log.error("Unable to authenticate user by " + loginHeader

View File

@ -16,6 +16,7 @@ package com.google.gerrit.httpd.auth.container;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@ -55,9 +56,7 @@ public class HttpsClientSslCertLoginServlet extends HttpServlet {
rdr.append('#');
rdr.append(getToken(req));
rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(rsp);
rsp.sendRedirect(rdr.toString());
}

View File

@ -18,6 +18,7 @@ import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.auth.SignInMode;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@ -67,9 +68,7 @@ class LoginRedirectServlet extends HttpServlet {
rdr.append('#');
rdr.append(token);
rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(rsp);
rsp.sendRedirect(rdr.toString());
}

View File

@ -15,6 +15,7 @@
package com.google.gerrit.httpd.gitweb;
import com.google.gerrit.httpd.GitWebConfig;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@ -33,11 +34,6 @@ import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
@Singleton
class GitLogoServlet extends HttpServlet {
private static final long MAX_AGE =
TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES);
private static final String CACHE_CTRL =
"public, max-age=" + (MAX_AGE / 1000L);
private final long modified;
private final byte[] raw;
@ -59,17 +55,19 @@ class GitLogoServlet extends HttpServlet {
raw = png;
}
@Override
protected long getLastModified(final HttpServletRequest req) {
return modified;
}
@Override
protected void doGet(final HttpServletRequest req,
final HttpServletResponse rsp) throws IOException {
if (raw != null) {
final long now = System.currentTimeMillis();
rsp.setContentType("image/png");
rsp.setContentLength(raw.length);
rsp.setHeader("Cache-Control", CACHE_CTRL);
rsp.setDateHeader("Date", now);
rsp.setDateHeader("Expires", now + MAX_AGE);
rsp.setDateHeader("Last-Modified", modified);
CacheHeaders.setCacheable(req, rsp, 5, TimeUnit.MINUTES);
final ServletOutputStream os = rsp.getOutputStream();
try {
@ -78,6 +76,7 @@ class GitLogoServlet extends HttpServlet {
os.close();
}
} else {
CacheHeaders.setNotCacheable(rsp);
rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}

View File

@ -17,6 +17,7 @@ package com.google.gerrit.httpd.gitweb;
import com.google.gerrit.httpd.GitWebConfig;
import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gerrit.server.config.SitePaths;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtjsonrpc.server.RPCServletUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@ -49,10 +50,6 @@ abstract class GitWebCssServlet extends HttpServlet {
}
private static final String ENC = "UTF-8";
private static final long MAX_AGE =
TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES);
private static final String CACHE_CTRL =
"public, max-age=" + (MAX_AGE / 1000L);
private final long modified;
private final byte[] raw_css;
@ -89,7 +86,6 @@ abstract class GitWebCssServlet extends HttpServlet {
protected void doGet(final HttpServletRequest req,
final HttpServletResponse rsp) throws IOException {
if (raw_css != null) {
final long now = System.currentTimeMillis();
rsp.setContentType("text/css");
rsp.setCharacterEncoding(ENC);
final byte[] toSend;
@ -100,10 +96,8 @@ abstract class GitWebCssServlet extends HttpServlet {
toSend = raw_css;
}
rsp.setContentLength(toSend.length);
rsp.setHeader("Cache-Control", CACHE_CTRL);
rsp.setDateHeader("Date", now);
rsp.setDateHeader("Expires", now + MAX_AGE);
rsp.setDateHeader("Last-Modified", modified);
CacheHeaders.setCacheable(req, rsp, 5, TimeUnit.MINUTES);
final ServletOutputStream os = rsp.getOutputStream();
try {
@ -112,6 +106,7 @@ abstract class GitWebCssServlet extends HttpServlet {
os.close();
}
} else {
CacheHeaders.setNotCacheable(rsp);
rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}

View File

@ -15,6 +15,7 @@
package com.google.gerrit.httpd.gitweb;
import com.google.gerrit.httpd.GitWebConfig;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@ -33,11 +34,6 @@ import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
@Singleton
class GitWebJavaScriptServlet extends HttpServlet {
private static final long MAX_AGE =
TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES);
private static final String CACHE_CTRL =
"public, max-age=" + (MAX_AGE / 1000L);
private final long modified;
private final byte[] raw;
@ -68,13 +64,10 @@ class GitWebJavaScriptServlet extends HttpServlet {
protected void doGet(final HttpServletRequest req,
final HttpServletResponse rsp) throws IOException {
if (raw != null) {
final long now = System.currentTimeMillis();
rsp.setContentType("text/javascript");
rsp.setContentLength(raw.length);
rsp.setHeader("Cache-Control", CACHE_CTRL);
rsp.setDateHeader("Date", now);
rsp.setDateHeader("Expires", now + MAX_AGE);
rsp.setDateHeader("Last-Modified", modified);
CacheHeaders.setCacheable(req, rsp, 5, TimeUnit.MINUTES);
final ServletOutputStream os = rsp.getOutputStream();
try {
@ -83,6 +76,7 @@ class GitWebJavaScriptServlet extends HttpServlet {
os.close();
}
} else {
CacheHeaders.setNotCacheable(rsp);
rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}

View File

@ -40,6 +40,7 @@ import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.util.Url;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@ -387,9 +388,7 @@ class GitWebServlet extends HttpServlet {
return;
}
try {
rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(rsp);
exec(req, rsp, project, repo);
} finally {
repo.close();

View File

@ -30,6 +30,7 @@ import com.google.gerrit.server.plugins.PluginsCollection;
import com.google.gerrit.server.plugins.ReloadPluginListener;
import com.google.gerrit.server.plugins.StartPluginListener;
import com.google.gerrit.server.ssh.SshInfo;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@ -203,7 +204,7 @@ class HttpPluginServlet extends HttpServlet
String name = parts.get(0);
final PluginHolder holder = plugins.get(name);
if (holder == null) {
noCache(res);
CacheHeaders.setNotCacheable(res);
res.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
@ -235,7 +236,7 @@ class HttpPluginServlet extends HttpServlet
HttpServletRequest req,
HttpServletResponse res) throws IOException {
if (!"GET".equals(req.getMethod()) && !"HEAD".equals(req.getMethod())) {
noCache(res);
CacheHeaders.setNotCacheable(res);
res.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
@ -570,13 +571,6 @@ class HttpPluginServlet extends HttpServlet
return data;
}
static void noCache(HttpServletResponse res) {
res.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
res.setHeader("Pragma", "no-cache");
res.setHeader("Cache-Control", "no-cache, must-revalidate");
res.setHeader("Content-Disposition", "attachment");
}
private static class PluginHolder {
final Plugin plugin;
final GuiceFilter filter;

View File

@ -14,6 +14,8 @@
package com.google.gerrit.httpd.plugins;
import com.google.gwtexpui.server.CacheHeaders;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
@ -29,7 +31,7 @@ abstract class Resource {
@Override
void send(HttpServletRequest req, HttpServletResponse res)
throws IOException {
HttpPluginServlet.noCache(res);
CacheHeaders.setNotCacheable(res);
res.sendError(HttpServletResponse.SC_NOT_FOUND);
}
};

View File

@ -24,6 +24,7 @@ import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.util.Url;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@ -226,9 +227,7 @@ public class CatServlet extends HttpServlet {
final long when = fromCommit.getCommitTime() * 1000L;
rsp.setDateHeader("Last-Modified", when);
rsp.setDateHeader("Expires", 0L);
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(rsp);
OutputStream out;
ZipOutputStream zo;

View File

@ -30,6 +30,7 @@ import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gwtexpui.linker.server.Permutation;
import com.google.gwtexpui.linker.server.PermutationSelector;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtjsonrpc.server.JsonServlet;
import com.google.gwtjsonrpc.server.RPCServletUtils;
import com.google.inject.Inject;
@ -206,9 +207,7 @@ public class HostPageServlet extends HttpServlet {
tosend = raw;
}
rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(rsp);
rsp.setContentType("text/html");
rsp.setCharacterEncoding(HtmlDomUtil.ENC);
rsp.setContentLength(tosend.length);

View File

@ -15,6 +15,7 @@
package com.google.gerrit.httpd.raw;
import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtjsonrpc.server.RPCServletUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@ -66,9 +67,7 @@ public class LegacyGerritServlet extends HttpServlet {
tosend = raw;
}
rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(rsp);
rsp.setContentType("text/html");
rsp.setCharacterEncoding(HtmlDomUtil.ENC);
rsp.setContentLength(tosend.length);

View File

@ -15,6 +15,7 @@
package com.google.gerrit.httpd.raw;
import com.google.gerrit.server.ssh.SshInfo;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@ -60,10 +61,6 @@ public class SshInfoServlet extends HttpServlet {
@Override
protected void doGet(final HttpServletRequest req,
final HttpServletResponse rsp) throws IOException {
rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
final List<HostKey> hostKeys = sshd.getHostKeys();
final String out;
if (!hostKeys.isEmpty()) {
@ -88,6 +85,7 @@ public class SshInfoServlet extends HttpServlet {
out = "NOT_AVAILABLE";
}
CacheHeaders.setNotCacheable(rsp);
rsp.setCharacterEncoding("UTF-8");
rsp.setContentType("text/plain");
final PrintWriter w = rsp.getWriter();

View File

@ -14,7 +14,9 @@
package com.google.gerrit.httpd.raw;
import com.google.common.collect.Maps;
import com.google.gerrit.server.config.SitePaths;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtjsonrpc.server.RPCServletUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@ -26,7 +28,8 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPOutputStream;
import javax.servlet.http.HttpServlet;
@ -37,12 +40,7 @@ import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
@Singleton
public class StaticServlet extends HttpServlet {
private static final long MAX_AGE = 12 * 60 * 60 * 1000L/* milliseconds */;
private static final String CACHE_CTRL =
"public, max-age=" + (MAX_AGE / 1000L);
private static final HashMap<String, String> MIME_TYPES =
new HashMap<String, String>();
private static final Map<String, String> MIME_TYPES = Maps.newHashMap();
static {
MIME_TYPES.put("html", "text/html");
MIME_TYPES.put("htm", "text/html");
@ -147,6 +145,7 @@ public class StaticServlet extends HttpServlet {
final HttpServletResponse rsp) throws IOException {
final File p = local(req);
if (p == null) {
CacheHeaders.setNotCacheable(rsp);
rsp.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
@ -161,8 +160,7 @@ public class StaticServlet extends HttpServlet {
tosend = readFile(p);
}
rsp.setHeader("Cache-Control", CACHE_CTRL);
rsp.setDateHeader("Expires", System.currentTimeMillis() + MAX_AGE);
CacheHeaders.setCacheable(req, rsp, 12, TimeUnit.HOURS);
rsp.setDateHeader("Last-Modified", p.lastModified());
rsp.setContentType(type);
rsp.setContentLength(tosend.length);

View File

@ -71,6 +71,7 @@ import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.util.Providers;
@ -163,9 +164,7 @@ public class RestApiServlet extends HttpServlet {
@Override
protected final void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
res.setHeader("Pragma", "no-cache");
res.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(res);
res.setHeader("Content-Disposition", "attachment");
res.setHeader("X-Content-Type-Options", "nosniff");

View File

@ -14,6 +14,7 @@
package com.google.gerrit.httpd.auth.openid;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@ -44,9 +45,7 @@ class OpenIdLoginServlet extends HttpServlet {
public void doPost(final HttpServletRequest req, final HttpServletResponse rsp)
throws IOException {
try {
rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
rsp.setHeader("Pragma", "no-cache");
rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
CacheHeaders.setNotCacheable(rsp);
impl.doAuth(req, rsp);
} catch (Exception e) {
getServletContext().log("Unexpected error during authentication", e);

View File

@ -49,7 +49,7 @@ limitations under the License.
<jgitVersion>2.2.0.201212191850-r</jgitVersion>
<gwtormVersion>1.5</gwtormVersion>
<gwtjsonrpcVersion>1.3</gwtjsonrpcVersion>
<gwtexpuiVersion>1.2.7</gwtexpuiVersion>
<gwtexpuiVersion>1.3</gwtexpuiVersion>
<gwtVersion>2.5.0</gwtVersion>
<bouncyCastleVersion>140</bouncyCastleVersion>
<slf4jVersion>1.6.1</slf4jVersion>