Author: dbkr
Date: 2008-04-12 17:54:07 +0000 (Sat, 12 Apr 2008)
New Revision: 19252
Modified:
trunk/freenet/src/freenet/clients/http/StaticToadlet.java
trunk/freenet/src/freenet/clients/http/ToadletContext.java
trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
Log:
Allow some caching for static files - send sensible last-modified times too.
Modified: trunk/freenet/src/freenet/clients/http/StaticToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/StaticToadlet.java 2008-04-12
16:50:32 UTC (rev 19251)
+++ trunk/freenet/src/freenet/clients/http/StaticToadlet.java 2008-04-12
17:54:07 UTC (rev 19252)
@@ -1,9 +1,12 @@
package freenet.clients.http;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
+import java.net.URL;
+import java.util.Date;
import freenet.client.DefaultMIMETypes;
import freenet.l10n.L10n;
@@ -58,12 +61,32 @@
strm.close();
os.close();
- ctx.sendReplyHeaders(200, "OK", null,
DefaultMIMETypes.guessMIMEType(path, false), data.size());
+ URL url = getClass().getResource(ROOT_PATH+path);
+ Date mTime = getUrlMTime(url);
+
+ ctx.sendReplyHeaders(200, "OK", null,
DefaultMIMETypes.guessMIMEType(path, false), data.size(), mTime);
ctx.writeData(data);
data.free();
}
+ /**
+ * Try to find the modification time for a URL, or return null if not
possible
+ * We usually load our resources from the JAR, or possibly from a file
in some setups, so we check the modification time of
+ * the JAR for resources in a jar and the mtime for files.
+ */
+ private Date getUrlMTime(URL url) {
+ if (url.getProtocol().equals("jar")) {
+ File f = new File(url.getPath().substring(0,
url.getPath().indexOf('!')));
+ return new Date(f.lastModified());
+ } else if (url.getProtocol().equals("file")) {
+ File f = new File(url.getPath());
+ return new Date(f.lastModified());
+ } else {
+ return null;
+ }
+ }
+
private String l10n(String key) {
return L10n.getString("StaticToadlet."+key);
}
Modified: trunk/freenet/src/freenet/clients/http/ToadletContext.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ToadletContext.java 2008-04-12
16:50:32 UTC (rev 19251)
+++ trunk/freenet/src/freenet/clients/http/ToadletContext.java 2008-04-12
17:54:07 UTC (rev 19252)
@@ -1,6 +1,7 @@
package freenet.clients.http;
import java.io.IOException;
+import java.util.Date;
import freenet.support.HTMLNode;
import freenet.support.MultiValueTable;
@@ -20,7 +21,10 @@
* @param mvt Any extra headers.
* @param mimeType The MIME type of the reply.
* @param length The length of the reply.
+ * @param mTime The modification time of the data being sent or null
for 'now' and disabling caching
*/
+ void sendReplyHeaders(int code, String desc, MultiValueTable mvt,
String mimeType, long length, Date mTime) throws ToadletContextClosedException,
IOException;
+
void sendReplyHeaders(int code, String desc, MultiValueTable mvt,
String mimeType, long length) throws ToadletContextClosedException, IOException;
/**
Modified: trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
2008-04-12 16:50:32 UTC (rev 19251)
+++ trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
2008-04-12 17:54:07 UTC (rev 19252)
@@ -104,7 +104,7 @@
private static void sendHTMLError(OutputStream os, int code, String
httpReason, String htmlMessage, boolean disconnect, MultiValueTable mvt) throws
IOException {
if(mvt == null) mvt = new MultiValueTable();
byte[] messageBytes = htmlMessage.getBytes("UTF-8");
- sendReplyHeaders(os, code, httpReason, mvt, "text/html;
charset=UTF-8", messageBytes.length, disconnect);
+ sendReplyHeaders(os, code, httpReason, mvt, "text/html;
charset=UTF-8", messageBytes.length, null, disconnect);
os.write(messageBytes);
}
@@ -123,8 +123,12 @@
}
public void sendReplyHeaders(int replyCode, String replyDescription,
MultiValueTable mvt, String mimeType, long contentLength) throws
ToadletContextClosedException, IOException {
+ sendReplyHeaders(replyCode, replyDescription, mvt, mimeType,
contentLength, null);
+ }
+
+ public void sendReplyHeaders(int replyCode, String replyDescription,
MultiValueTable mvt, String mimeType, long contentLength, Date mTime) throws
ToadletContextClosedException, IOException {
if(closed) throw new ToadletContextClosedException();
- sendReplyHeaders(sockOutputStream, replyCode, replyDescription,
mvt, mimeType, contentLength, shouldDisconnect);
+ sendReplyHeaders(sockOutputStream, replyCode, replyDescription,
mvt, mimeType, contentLength, mTime, shouldDisconnect);
}
public PageMaker getPageMaker() {
@@ -135,7 +139,7 @@
return headers;
}
- static void sendReplyHeaders(OutputStream sockOutputStream, int
replyCode, String replyDescription, MultiValueTable mvt, String mimeType, long
contentLength, boolean disconnect) throws IOException {
+ static void sendReplyHeaders(OutputStream sockOutputStream, int
replyCode, String replyDescription, MultiValueTable mvt, String mimeType, long
contentLength, Date mTime, boolean disconnect) throws IOException {
// Construct headers
if(mvt == null)
mvt = new MultiValueTable();
@@ -147,17 +151,30 @@
}
if(contentLength >= 0)
mvt.put("content-length", Long.toString(contentLength));
- // FIXME allow caching on a config option.
- // For now cater to the paranoid.
- // Also this may fix a wierd bug...
- // All keys are lower-case
- mvt.put("expires", "Thu, 01 Jan 1970 00:00:00 GMT");
- // Sent now, expires now.
- String time = makeHTTPDate(System.currentTimeMillis());
- mvt.put("last-modified", time);
- mvt.put("date", time);
- mvt.put("pragma", "no-cache");
- mvt.put("cache-control", "max-age=0, must-revalidate, no-cache,
no-store, post-check=0, pre-check=0");
+
+ String expiresTime;
+ if (mTime == null) {
+ expiresTime = "Thu, 01 Jan 1970 00:00:00 GMT";
+ } else {
+ // use an expiry time of 1 day, somewhat arbitrarily
+ expiresTime = makeHTTPDate(mTime.getTime() + (24 * 60 *
60 * 1000));
+ }
+ mvt.put("expires", expiresTime);
+
+ String nowString = makeHTTPDate(System.currentTimeMillis());
+ String lastModString;
+ if (mTime == null) {
+ lastModString = nowString;
+ } else {
+ lastModString = makeHTTPDate(mTime.getTime());
+ }
+
+ mvt.put("last-modified", lastModString);
+ mvt.put("date", nowString);
+ if (mTime == null) {
+ mvt.put("pragma", "no-cache");
+ mvt.put("cache-control", "max-age=0, must-revalidate,
no-cache, no-store, post-check=0, pre-check=0");
+ }
if(disconnect)
mvt.put("connection", "close");
else