HTTP Caching
This commit is contained in:
parent
09b20cadd8
commit
dc32ca81a9
@ -3,6 +3,7 @@ import { FileMeta } from "../types.ts";
|
|||||||
import { FileData, FileEncoding, SpacePrimitives } from "./space_primitives.ts";
|
import { FileData, FileEncoding, SpacePrimitives } from "./space_primitives.ts";
|
||||||
import { AssetBundle } from "../../plugos/asset_bundle/bundle.ts";
|
import { AssetBundle } from "../../plugos/asset_bundle/bundle.ts";
|
||||||
|
|
||||||
|
const bootTime = Date.now();
|
||||||
export class AssetBundlePlugSpacePrimitives implements SpacePrimitives {
|
export class AssetBundlePlugSpacePrimitives implements SpacePrimitives {
|
||||||
constructor(
|
constructor(
|
||||||
private wrapped: SpacePrimitives,
|
private wrapped: SpacePrimitives,
|
||||||
@ -16,7 +17,7 @@ export class AssetBundlePlugSpacePrimitives implements SpacePrimitives {
|
|||||||
.map((p) => ({
|
.map((p) => ({
|
||||||
name: p,
|
name: p,
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
lastModified: 0,
|
lastModified: bootTime,
|
||||||
perm: "ro",
|
perm: "ro",
|
||||||
size: -1,
|
size: -1,
|
||||||
} as FileMeta)).concat(l);
|
} as FileMeta)).concat(l);
|
||||||
@ -32,7 +33,7 @@ export class AssetBundlePlugSpacePrimitives implements SpacePrimitives {
|
|||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
data: encoding === "string" ? new TextDecoder().decode(data) : data,
|
data: encoding === "string" ? new TextDecoder().decode(data) : data,
|
||||||
meta: {
|
meta: {
|
||||||
lastModified: 0,
|
lastModified: bootTime,
|
||||||
size: data.byteLength,
|
size: data.byteLength,
|
||||||
perm: "ro",
|
perm: "ro",
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
@ -46,7 +47,7 @@ export class AssetBundlePlugSpacePrimitives implements SpacePrimitives {
|
|||||||
if (this.assetBundle.has(name)) {
|
if (this.assetBundle.has(name)) {
|
||||||
const data = this.assetBundle.readFileSync(name);
|
const data = this.assetBundle.readFileSync(name);
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
lastModified: 0,
|
lastModified: bootTime,
|
||||||
size: data.byteLength,
|
size: data.byteLength,
|
||||||
perm: "ro",
|
perm: "ro",
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
|
@ -5,12 +5,13 @@ import type {
|
|||||||
import { renderToText, replaceNodesMatching } from "$sb/lib/tree.ts";
|
import { renderToText, replaceNodesMatching } from "$sb/lib/tree.ts";
|
||||||
import type { FileMeta } from "../../common/types.ts";
|
import type { FileMeta } from "../../common/types.ts";
|
||||||
import { parseMarkdown } from "$sb/silverbullet-syscall/markdown.ts";
|
import { parseMarkdown } from "$sb/silverbullet-syscall/markdown.ts";
|
||||||
|
import { base64EncodedDataUrl } from "../../plugos/asset_bundle/base64.ts";
|
||||||
|
|
||||||
const pagePrefix = "💭 ";
|
const pagePrefix = "💭 ";
|
||||||
|
|
||||||
export async function readFileCloud(
|
export async function readFileCloud(
|
||||||
name: string,
|
name: string,
|
||||||
_encoding: FileEncoding,
|
encoding: FileEncoding,
|
||||||
): Promise<{ data: FileData; meta: FileMeta } | undefined> {
|
): Promise<{ data: FileData; meta: FileMeta } | undefined> {
|
||||||
const originalUrl = name.substring(
|
const originalUrl = name.substring(
|
||||||
pagePrefix.length,
|
pagePrefix.length,
|
||||||
@ -36,10 +37,15 @@ export async function readFileCloud(
|
|||||||
console.error("ERROR", e.message);
|
console.error("ERROR", e.message);
|
||||||
text = e.message;
|
text = e.message;
|
||||||
}
|
}
|
||||||
|
text = await translateLinksWithPrefix(
|
||||||
|
text,
|
||||||
|
`${pagePrefix}${originalUrl.split("/")[0]}/`,
|
||||||
|
);
|
||||||
|
console.log("Got this", text);
|
||||||
return {
|
return {
|
||||||
data: await translateLinksWithPrefix(
|
data: encoding === "string" ? text : base64EncodedDataUrl(
|
||||||
text,
|
"text/markdown",
|
||||||
`${pagePrefix}${originalUrl.split("/")[0]}/`,
|
new TextEncoder().encode(text),
|
||||||
),
|
),
|
||||||
meta: {
|
meta: {
|
||||||
name,
|
name,
|
||||||
|
@ -228,11 +228,12 @@ export async function reindexSpace() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function clearPageIndex(page: string) {
|
export async function clearPageIndex(page: string) {
|
||||||
console.log("Clearing page index for page", page);
|
// console.log("Clearing page index for page", page);
|
||||||
await index.clearPageIndexForPage(page);
|
await index.clearPageIndexForPage(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseIndexTextRepublish({ name, text }: IndexEvent) {
|
export async function parseIndexTextRepublish({ name, text }: IndexEvent) {
|
||||||
|
console.log("Reindexing", name);
|
||||||
await events.dispatchEvent("page:index", {
|
await events.dispatchEvent("page:index", {
|
||||||
name,
|
name,
|
||||||
tree: await markdown.parseMarkdown(text),
|
tree: await markdown.parseMarkdown(text),
|
||||||
|
@ -215,16 +215,26 @@ export class HttpServer {
|
|||||||
// Serve static files (javascript, css, html)
|
// Serve static files (javascript, css, html)
|
||||||
this.app.use(async ({ request, response }, next) => {
|
this.app.use(async ({ request, response }, next) => {
|
||||||
if (request.url.pathname === "/") {
|
if (request.url.pathname === "/") {
|
||||||
|
if (request.headers.get("If-Modified-Since") === staticLastModified) {
|
||||||
|
response.status = 304;
|
||||||
|
return;
|
||||||
|
}
|
||||||
response.headers.set("Content-type", "text/html");
|
response.headers.set("Content-type", "text/html");
|
||||||
response.body = this.assetBundle.readTextFileSync(
|
response.body = this.assetBundle.readTextFileSync(
|
||||||
"web/index.html",
|
"web/index.html",
|
||||||
);
|
);
|
||||||
response.headers.set("Last-Modified", staticLastModified);
|
response.headers.set("Last-Modified", staticLastModified);
|
||||||
response.headers.set("ETag", await etag.calculate(response.body));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const assetName = `web${request.url.pathname}`;
|
const assetName = `web${request.url.pathname}`;
|
||||||
|
if (
|
||||||
|
this.assetBundle.has(assetName) &&
|
||||||
|
request.headers.get("If-Modified-Since") === staticLastModified
|
||||||
|
) {
|
||||||
|
response.status = 304;
|
||||||
|
return;
|
||||||
|
}
|
||||||
response.status = 200;
|
response.status = 200;
|
||||||
response.headers.set(
|
response.headers.set(
|
||||||
"Content-type",
|
"Content-type",
|
||||||
@ -233,9 +243,9 @@ export class HttpServer {
|
|||||||
const data = this.assetBundle.readFileSync(
|
const data = this.assetBundle.readFileSync(
|
||||||
assetName,
|
assetName,
|
||||||
);
|
);
|
||||||
|
response.headers.set("Cache-Control", "no-cache");
|
||||||
response.headers.set("Content-length", "" + data.length);
|
response.headers.set("Content-length", "" + data.length);
|
||||||
response.headers.set("Last-Modified", staticLastModified);
|
response.headers.set("Last-Modified", staticLastModified);
|
||||||
response.headers.set("ETag", await etag.calculate(data));
|
|
||||||
|
|
||||||
if (request.method === "GET") {
|
if (request.method === "GET") {
|
||||||
response.body = data;
|
response.body = data;
|
||||||
@ -299,7 +309,7 @@ export class HttpServer {
|
|||||||
});
|
});
|
||||||
|
|
||||||
fsRouter
|
fsRouter
|
||||||
.get("\/(.+)", async ({ params, response }) => {
|
.get("\/(.+)", async ({ params, response, request }) => {
|
||||||
const name = params[0];
|
const name = params[0];
|
||||||
console.log("Loading file", name);
|
console.log("Loading file", name);
|
||||||
try {
|
try {
|
||||||
@ -307,12 +317,23 @@ export class HttpServer {
|
|||||||
name,
|
name,
|
||||||
"arraybuffer",
|
"arraybuffer",
|
||||||
);
|
);
|
||||||
|
const lastModifiedHeader = new Date(attachmentData.meta.lastModified)
|
||||||
|
.toUTCString();
|
||||||
|
if (request.headers.get("If-Modified-Since") === lastModifiedHeader) {
|
||||||
|
response.status = 304;
|
||||||
|
return;
|
||||||
|
}
|
||||||
response.status = 200;
|
response.status = 200;
|
||||||
response.headers.set(
|
response.headers.set(
|
||||||
"X-Last-Modified",
|
"X-Last-Modified",
|
||||||
"" + attachmentData.meta.lastModified,
|
"" + attachmentData.meta.lastModified,
|
||||||
);
|
);
|
||||||
|
response.headers.set("Cache-Control", "no-cache");
|
||||||
response.headers.set("X-Permission", attachmentData.meta.perm);
|
response.headers.set("X-Permission", attachmentData.meta.perm);
|
||||||
|
response.headers.set(
|
||||||
|
"Last-Modified",
|
||||||
|
lastModifiedHeader,
|
||||||
|
);
|
||||||
response.headers.set("Content-Type", attachmentData.meta.contentType);
|
response.headers.set("Content-Type", attachmentData.meta.contentType);
|
||||||
response.body = attachmentData.data as ArrayBuffer;
|
response.body = attachmentData.data as ArrayBuffer;
|
||||||
} catch {
|
} catch {
|
||||||
@ -343,7 +364,6 @@ export class HttpServer {
|
|||||||
response.body = "Write failed";
|
response.body = "Write failed";
|
||||||
console.error("Pipeline failed", err);
|
console.error("Pipeline failed", err);
|
||||||
}
|
}
|
||||||
console.log("Done with put", name);
|
|
||||||
})
|
})
|
||||||
.options("\/(.+)", async ({ response, params }) => {
|
.options("\/(.+)", async ({ response, params }) => {
|
||||||
const name = params[0];
|
const name = params[0];
|
||||||
|
Loading…
Reference in New Issue
Block a user