From 7077e69bf72ba503476319d3b94c6913ff73cf7c Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Wed, 14 Sep 2022 23:18:55 +0000 Subject: [PATCH] Fix caching for all of the requests. The free wifi I get at Bacchus from Angela's Bridal isn't great. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3981 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- core/core.js | 301 +++++++++++++++++++++++++++++---------------------- 1 file changed, 173 insertions(+), 128 deletions(-) diff --git a/core/core.js b/core/core.js index 3dee1102..ba5f5648 100644 --- a/core/core.js +++ b/core/core.js @@ -415,9 +415,24 @@ async function staticFileHandler(request, response, blobId, uri) { if (uri === kStaticFiles[i].uri) { var path = kStaticFiles[i].path || uri.substring(1); var type = kStaticFiles[i].type || guessType(path); - var data = await File.readFile("core/" + path); - response.writeHead(200, Object.assign({"Content-Type": type, "Content-Length": data.byteLength}, kStaticFiles[i].headers || {})); - response.end(data); + + let stat = await File.stat('core/' + path); + let id = `${stat.mtime}_${stat.size}`; + + if (request.headers['if-none-match'] === '"' + id + '"') { + response.writeHead(304, {}); + response.end(); + } else { + var data = await File.readFile('core/' + path); + response.writeHead(200, Object.assign( + { + 'Content-Type': type, + 'Content-Length': data.byteLength, + 'etag': '"' + id + '"', + }, + kStaticFiles[i].headers || {})); + response.end(data); + } return; } } @@ -443,9 +458,21 @@ async function staticDirectoryHandler(request, response, directory, uri) { } try { - var data = await File.readFile(directory + filename); - response.writeHead(200, {"Content-Type": k_mime_types[filename.split('.').pop()] || 'text/plain', "Content-Length": data.byteLength}); - response.end(data); + let stat = await File.stat(directory + filename); + let id = `${stat.mtime}_${stat.size}`; + + if (request.headers['if-none-match'] === '"' + id + '"') { + response.writeHead(304, {}); + response.end(); + } else { + var data = await File.readFile(directory + filename); + response.writeHead(200, { + 'Content-Type': k_mime_types[filename.split('.').pop()] || 'text/plain', + 'Content-Length': data.byteLength, + 'etag': '"' + id + '"', + }); + response.end(data); + } } catch { response.writeHead(404, {"Content-Type": "text/plain; charset=utf-8", "Content-Length": "File not found".length}); response.end("File not found"); @@ -513,16 +540,26 @@ function guessType(path) { } async function blobHandler(request, response, blobId, uri) { - var found = false; - if (!found) { - for (var i in kStaticFiles) { - if (uri === kStaticFiles[i].uri && kStaticFiles[i].path) { - found = true; - var data = await File.readFile("core/" + kStaticFiles[i].path); - response.writeHead(200, {"Content-Type": kStaticFiles[i].type, "Content-Length": data.byteLength}); + for (var i in kStaticFiles) { + if (uri === kStaticFiles[i].uri && kStaticFiles[i].path) { + let stat = await File.stat('core/' + kStaticFiles[i].path); + let id = `${stat.mtime}_${stat.size}`; + + if (request.headers['if-none-match'] === '"' + id + '"') { + response.writeHead(304, {}); + response.end(); + } else { + var data = await File.readFile('core/' + kStaticFiles[i].path); + response.writeHead(200, Object.assign( + { + 'Content-Type': kStaticFiles[i].type, + 'Content-Length': data.byteLength, + 'etag': '"' + id + '"', + }, + kStaticFiles[i].headers || {})); response.end(data); - break; } + return; } } @@ -532,133 +569,141 @@ async function blobHandler(request, response, blobId, uri) { return; } - if (!found) { - var process; - if (uri == "/view") { - var data; - if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { - var id = await new Database(match[1]).get('path:' + match[2]); - if (id) { - if (request.headers['if-none-match'] && request.headers['if-none-match'] == '"' + id + '"') { - response.writeHead(304, {}); - response.end(); - } else { - data = await getBlobOrContent(id); - if (match[3]) { - var appObject = JSON.parse(data); - data = appObject.files[match[3]]; - } - sendData(response, data, undefined, {etag: '"' + id + '"'}); - } + var process; + if (uri == "/view") { + var data; + if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { + var id = await new Database(match[1]).get('path:' + match[2]); + if (id) { + if (request.headers['if-none-match'] === '"' + id + '"') { + response.writeHead(304, {}); + response.end(); } else { - sendData(response, data); + data = await getBlobOrContent(id); + if (match[3]) { + var appObject = JSON.parse(data); + data = appObject.files[match[3]]; + } + sendData(response, data, undefined, {etag: '"' + id + '"'}); } } else { - data = await getBlobOrContent(blobId); - sendData(response, data); - } - } else if (uri == "/save") { - let newBlobId = await ssb.blobStore(request.body); - - var match; - if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { - var user = match[1]; - var appName = match[2]; - var credentials = auth.query(request.headers); - if (credentials && credentials.session && - (credentials.session.name == user || - (credentials.permissions.administration && user == 'core'))) { - var database = new Database(user); - var apps = new Set(); - let apps_original = database.get('apps'); - try { - apps = new Set(JSON.parse(apps_original)); - } catch { - } - if (!apps.has(appName)) { - apps.add(appName); - } - apps = JSON.stringify([...apps].sort()); - if (apps != apps_original) { - database.set('apps', apps); - } - database.set('path:' + appName, newBlobId); + if (request.headers['if-none-match'] === '"' + blobId + '"') { + response.writeHead(304, {}); + response.end(); } else { - response.writeHead(401, {"Content-Type": "text/plain; charset=utf-8"}); - response.end("401 Unauthorized"); - return; + sendData(response, data, undefined, {etag: '"' + blobId + '"'}); } } - - response.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"}); - response.end("/" + newBlobId); - } else if (uri == "/delete") { - let match; - if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { - var user = match[1]; - var appName = match[2]; - var credentials = auth.query(request.headers); - if (credentials && credentials.session && - (credentials.session.name == user || - (credentials.permissions.administration && user == 'core'))) { - var database = new Database(user); - var apps = new Set(); - try { - apps = new Set(JSON.parse(database.get('apps'))); - } catch { - } - if (apps.delete(appName)) { - database.set('apps', JSON.stringify([...apps])); - } - database.remove('path:' + appName); - } else { - response.writeHead(401, {"Content-Type": "text/plain; charset=utf-8"}); - response.end("401 Unauthorized"); - return; - } - } - - response.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"}); - response.end('OK'); } else { - var data; - var type; - var headers; - if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { - var db = new Database(match[1]); - var id = await db.get('path:' + match[2]); - if (id) { - if (request.headers['if-none-match'] && request.headers['if-none-match'] == '"' + id + '"') { - headers = { - 'Access-Control-Allow-Origin': '*', - }; - response.writeHead(304, headers); - response.end(); - } else { - data = utf8Decode(await getBlobOrContent(id)); - var appObject = JSON.parse(data); - data = appObject.files[uri.substring(1)]; - data = await getBlobOrContent(data); - type = guessType(uri); - headers = { - 'ETag': '"' + id + '"', - 'Access-Control-Allow-Origin': '*', - }; - sendData(response, data, type, headers); - } + if (request.headers['if-none-match'] === '"' + blobId + '"') { + response.writeHead(304, {}); + response.end(); + } else { + data = await getBlobOrContent(blobId); + sendData(response, data, undefined, {etag: '"' + blobId + '"'}); + } + } + } else if (uri == "/save") { + let newBlobId = await ssb.blobStore(request.body); + + var match; + if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { + var user = match[1]; + var appName = match[2]; + var credentials = auth.query(request.headers); + if (credentials && credentials.session && + (credentials.session.name == user || + (credentials.permissions.administration && user == 'core'))) { + var database = new Database(user); + var apps = new Set(); + let apps_original = database.get('apps'); + try { + apps = new Set(JSON.parse(apps_original)); + } catch { + } + if (!apps.has(appName)) { + apps.add(appName); + } + apps = JSON.stringify([...apps].sort()); + if (apps != apps_original) { + database.set('apps', apps); + } + database.set('path:' + appName, newBlobId); + } else { + response.writeHead(401, {"Content-Type": "text/plain; charset=utf-8"}); + response.end("401 Unauthorized"); + return; + } + } + + response.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"}); + response.end("/" + newBlobId); + } else if (uri == "/delete") { + let match; + if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { + var user = match[1]; + var appName = match[2]; + var credentials = auth.query(request.headers); + if (credentials && credentials.session && + (credentials.session.name == user || + (credentials.permissions.administration && user == 'core'))) { + var database = new Database(user); + var apps = new Set(); + try { + apps = new Set(JSON.parse(database.get('apps'))); + } catch { + } + if (apps.delete(appName)) { + database.set('apps', JSON.stringify([...apps])); + } + database.remove('path:' + appName); + } else { + response.writeHead(401, {"Content-Type": "text/plain; charset=utf-8"}); + response.end("401 Unauthorized"); + return; + } + } + + response.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"}); + response.end('OK'); + } else { + var data; + var type; + var headers; + if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { + var db = new Database(match[1]); + var id = await db.get('path:' + match[2]); + if (id) { + if (request.headers['if-none-match'] && request.headers['if-none-match'] == '"' + id + '"') { + headers = { + 'Access-Control-Allow-Origin': '*', + }; + response.writeHead(304, headers); + response.end(); } else { + data = utf8Decode(await getBlobOrContent(id)); + var appObject = JSON.parse(data); + data = appObject.files[uri.substring(1)]; + data = await getBlobOrContent(data); + type = guessType(uri); + headers = { + 'ETag': '"' + id + '"', + 'Access-Control-Allow-Origin': '*', + }; sendData(response, data, type, headers); } } else { - data = utf8Decode(await getBlobOrContent(blobId)); - var appObject = JSON.parse(data); - data = appObject.files[uri.substring(1)]; - data = await getBlobOrContent(data); - headers = { - 'Access-Control-Allow-Origin': '*', - }; sendData(response, data, type, headers); } + } else { + data = utf8Decode(await getBlobOrContent(blobId)); + var appObject = JSON.parse(data); + data = appObject.files[uri.substring(1)]; + data = await getBlobOrContent(data); + headers = { + 'Access-Control-Allow-Origin': '*', + }; + sendData(response, data, type, headers); } } }