Use ETag and If-None-Match for /detail caching

Last-Modified is only second level precision and may allow a client to
fail to see subsequent updates within the same second window.  Improve
the caching check by using an ETag string that is computed from the
full timestamp and the row version fields of Change.

Change-Id: I58fc95b5396baa1d8afb676ff672c9f19b835f1c
This commit is contained in:
Shawn Pearce
2013-07-19 14:28:13 -07:00
parent 4dc3cb5031
commit bc03a8f3b4
4 changed files with 41 additions and 4 deletions

View File

@@ -360,9 +360,19 @@ public class RestApiServlet extends HttpServlet {
}
}
private boolean notModified(HttpServletRequest req, RestResource rsrc) {
if (rsrc instanceof RestResource.HasLastModified
&& "GET".equals(req.getMethod())) {
private static boolean notModified(HttpServletRequest req, RestResource rsrc) {
if (!"GET".equals(req.getMethod())) {
return false;
}
if (rsrc instanceof RestResource.HasETag) {
String have = req.getHeader(HttpHeaders.IF_NONE_MATCH);
if (have != null) {
return have.equals(((RestResource.HasETag) rsrc).getETag());
}
}
if (rsrc instanceof RestResource.HasLastModified) {
Timestamp m = ((RestResource.HasLastModified) rsrc).getLastModified();
long d = req.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
@@ -400,6 +410,11 @@ public class RestApiServlet extends HttpServlet {
private static void addResourceStateHeaders(
HttpServletResponse res, RestResource rsrc) {
if (rsrc instanceof RestResource.HasETag) {
res.setHeader(
HttpHeaders.ETAG,
((RestResource.HasETag) rsrc).getETag());
}
if (rsrc instanceof RestResource.HasLastModified) {
res.setDateHeader(
HttpHeaders.LAST_MODIFIED,