diff --git a/server/api/v1/object/[id]/index.get.ts b/server/api/v1/object/[id]/index.get.ts index b060d5e..7bb63ab 100644 --- a/server/api/v1/object/[id]/index.get.ts +++ b/server/api/v1/object/[id]/index.get.ts @@ -11,6 +11,16 @@ export default defineEventHandler(async (h3) => { if (!object) throw createError({ statusCode: 404, statusMessage: "Object not found" }); + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/ETag + const etagValue = h3.headers.get("If-None-Match"); + if (etagValue !== null) { + // would compare if etag is valid, but objects should never change + setResponseStatus(h3, 304); + return null; + } + + // just return object id has etag since object should never change + setHeader(h3, "ETag", id); setHeader(h3, "Content-Type", object.mime); setHeader( h3, diff --git a/server/api/v1/object/[id]/index.head.ts b/server/api/v1/object/[id]/index.head.ts new file mode 100644 index 0000000..a981568 --- /dev/null +++ b/server/api/v1/object/[id]/index.head.ts @@ -0,0 +1,24 @@ +import aclManager from "~/server/internal/acls"; +import objectHandler from "~/server/internal/objects"; + +// this request method is purely used by the browser to check if etag values are still valid +export default defineEventHandler(async (h3) => { + const id = getRouterParam(h3, "id"); + if (!id) throw createError({ statusCode: 400, statusMessage: "Invalid ID" }); + + const userId = await aclManager.getUserIdACL(h3, ["object:read"]); + + const object = await objectHandler.fetchWithPermissions(id, userId); + if (!object) + throw createError({ statusCode: 404, statusMessage: "Object not found" }); + + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/ETag + const etagValue = h3.headers.get("If-None-Match"); + if (etagValue !== null) { + // would compare if etag is valid, but objects should never change + setResponseStatus(h3, 304); + return null; + } + + return null; +});