* Implement both ETag and Last-Modified based conditional requests as some browsers
(e.g. Safari) don't seem to support ETags for embedded images and stuff.
This commit is contained in:
parent
9491159dbb
commit
16eca87022
1 changed files with 35 additions and 26 deletions
|
@ -490,23 +490,15 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
ServletContext cx = getServletConfig().getServletContext();
|
ServletContext cx = getServletConfig().getServletContext();
|
||||||
String path = cx.getRealPath(forward);
|
String path = cx.getRealPath(forward);
|
||||||
if (path == null)
|
if (path == null)
|
||||||
throw new IOException("Resource "+forward+" not found");
|
throw new IOException("Resource " + forward + " not found");
|
||||||
|
|
||||||
File file = new File(path);
|
File file = new File(path);
|
||||||
// calculate checksom on last modified date and content length.
|
// check if the client has an up-to-date copy so we can
|
||||||
byte[] checksum = getChecksum(file);
|
// send a not-modified response
|
||||||
String etag = "\"" + new String(Base64.encode(checksum)) + "\"";
|
if (checkNotModified(file, req, res)) {
|
||||||
res.setHeader("ETag", etag);
|
|
||||||
String etagHeader = req.getHeader("If-None-Match");
|
|
||||||
if (etagHeader != null) {
|
|
||||||
StringTokenizer st = new StringTokenizer(etagHeader, ", \r\n");
|
|
||||||
while (st.hasMoreTokens()) {
|
|
||||||
if (etag.equals(st.nextToken())) {
|
|
||||||
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
int length = (int) file.length();
|
int length = (int) file.length();
|
||||||
res.setContentLength(length);
|
res.setContentLength(length);
|
||||||
res.setContentType(hopres.getContentType());
|
res.setContentType(hopres.getContentType());
|
||||||
|
@ -538,7 +530,10 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getChecksum(File file) {
|
private boolean checkNotModified(File file, HttpServletRequest req, HttpServletResponse res) {
|
||||||
|
// we do two rounds of conditional requests:
|
||||||
|
// first ETag based, then based on last modified date.
|
||||||
|
// calculate ETag checksum on last modified date and content length.
|
||||||
byte[] checksum = new byte[16];
|
byte[] checksum = new byte[16];
|
||||||
long n = file.lastModified();
|
long n = file.lastModified();
|
||||||
for (int i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
|
@ -550,7 +545,27 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
checksum[i] = (byte) (n);
|
checksum[i] = (byte) (n);
|
||||||
n >>>= 8;
|
n >>>= 8;
|
||||||
}
|
}
|
||||||
return checksum;
|
String etag = "\"" + new String(Base64.encode(checksum)) + "\"";
|
||||||
|
res.setHeader("ETag", etag);
|
||||||
|
String etagHeader = req.getHeader("If-None-Match");
|
||||||
|
if (etagHeader != null) {
|
||||||
|
StringTokenizer st = new StringTokenizer(etagHeader, ", \r\n");
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
if (etag.equals(st.nextToken())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// as a fallback, since some browsers don't support ETag based
|
||||||
|
// conditional GET for embedded images and stuff, check last modified date.
|
||||||
|
// date headers don't do milliseconds, round to seconds
|
||||||
|
long lastModified = (file.lastModified() / 1000) * 1000;
|
||||||
|
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
|
||||||
|
if (lastModified == ifModifiedSince) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
res.setDateHeader("Last-Modified", lastModified);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -810,12 +825,7 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
if (protocol == null) {
|
if (protocol == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return protocol.endsWith("1.1");
|
||||||
if (protocol.endsWith("1.1")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getPathInfo(HttpServletRequest req)
|
String getPathInfo(HttpServletRequest req)
|
||||||
|
@ -856,11 +866,10 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Return servlet info
|
||||||
*
|
* @return the servlet info
|
||||||
* @return ...
|
|
||||||
*/
|
*/
|
||||||
public String getServletInfo() {
|
public String getServletInfo() {
|
||||||
return new String("Helma Servlet Client");
|
return "Helma Servlet Client";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue