Added basic ETag caching support. Works via stat mtime, but this is inefficient. A better solution would be to assume the '*/upload' act as the primary means of file changing and generate CRC32-based ETags on upload act. Full server reloading would likely clear this cache unless the currently unused 'index.json' (should be renamed) had a cache(d) files section.

master
kts of kettek 2015-10-11 15:20:45 -07:00
parent 56f1385cb5
commit c26af35ac4
1 changed files with 24 additions and 10 deletions

View File

@ -18,6 +18,8 @@ var QCore = function() {
this.index_parts = [];
this.last_part = { start: 0, end: 0 };
this.etags = {}; // etags cache, obj: uri { etag: '...', timestamp: }
this.res_cache = {}; // resource cache ('/view.png' => '03xc345');
this.rules = {};
@ -428,17 +430,29 @@ qwiki.act('', function(req, res) {
var path = 'wiki/'+req.url;
fs.stat(path, function(err, stat) {
if (err == null) {
res.writeHead(200, "OK", {
"Content-Type": mimetype,
"Content-Length": stat.size
});
var rs = fs.createReadStream(path);
rs.on('data', function(chunk) {
res.write(chunk);
});
rs.on('end', function() {
// TODO: etags should actually be based on binary data(CRC32, etc.), not last modified
// TODO: files should not be stat()`d each call, but should be cached and updated when the file updates (how? browser-based upload interface?)
var mtime = stat.mtime.getTime();
if (!(path in qwiki.etags) || qwiki.etags[path] != mtime) {
qwiki.etags[path] = mtime;
}
if ('if-none-match' in req.headers && req.headers['if-none-match'] == qwiki.etags[path]) {
res.writeHead(304, "Not Modified");
res.end();
});
} else {
res.writeHead(200, "OK", {
"Content-Type": mimetype,
"Content-Length": stat.size,
"ETag": mtime
});
var rs = fs.createReadStream(path);
rs.on('data', function(chunk) {
res.write(chunk);
});
rs.on('end', function() {
res.end();
});
}
} else if (err.code == 'ENOENT') {
res.writeHead(404);
res.end();