Permalink
Browse files

* Implement ETag based conditional GET for forwarded resources.

  (ETag is based on last modified date and file size)
  • Loading branch information...
1 parent cab28b4 commit 1c51121bdc1aeaf5a37c3ce5abc6c49ecff7752a @hns hns committed Jun 3, 2006
Showing with 29 additions and 9 deletions.
  1. +29 −9 src/helma/servlet/AbstractServletClient.java
@@ -493,22 +493,27 @@ void sendForward(HttpServletResponse res, HttpServletRequest req,
throw new IOException("Resource "+forward+" not found");
File file = new File(path);
- // 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) {
- res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
- return;
+ // calculate checksom on last modified date and content length.
+ byte[] checksum = getChecksum(file);
+ 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())) {
+ res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ return;
+ }
+ }
}
int length = (int) file.length();
res.setContentLength(length);
- res.setDateHeader("Last-Modified", lastModified);
res.setContentType(hopres.getContentType());
InputStream in = cx.getResourceAsStream(forward);
if (in == null)
- throw new IOException("Can't read "+path);
+ throw new IOException("Can't read " + path);
try {
OutputStream out = res.getOutputStream();
@@ -533,6 +538,21 @@ void sendForward(HttpServletResponse res, HttpServletRequest req,
}
}
+ private byte[] getChecksum(File file) {
+ byte[] checksum = new byte[16];
+ long n = file.lastModified();
+ for (int i=0; i<8; i++) {
+ checksum[i] = (byte) (n);
+ n >>>= 8;
+ }
+ n = file.length();
+ for (int i=8; i<16; i++) {
+ checksum[i] = (byte) (n);
+ n >>>= 8;
+ }
+ return checksum;
+ }
+
/**
* Used to build the form value array when a multipart (file upload) form has
* multiple values for one form element name.

0 comments on commit 1c51121

Please sign in to comment.