From 78869517ea169c29f56b739c6f469706cc0361ce Mon Sep 17 00:00:00 2001 From: dtfiedler Date: Tue, 18 Jun 2024 10:05:43 -0700 Subject: [PATCH] feat(head): allow HEAD requests on endpoint The headers include relevant resolved tx id data without the fully resolved record data. It is a cheap way get the resolved tx id and ttl. --- docs/openapi.yaml | 19 +++++++++++++++++++ src/server.ts | 30 +++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 64b0de7..c7db34e 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -68,6 +68,25 @@ paths: schema: '$ref': '#/components/schemas/Info' '/ar-io/resolver/records/{name}': + head: + parameters: + - name: name + in: path + required: true + schema: + type: string + description: |- + The name of the record to resolve + responses: + '200': + description: |- + 200 response + '404': + description: |- + 404 response + '500': + description: |- + 500 response get: responses: '200': diff --git a/src/server.ts b/src/server.ts index 96d978d..ddd062a 100644 --- a/src/server.ts +++ b/src/server.ts @@ -33,7 +33,7 @@ export const app = express(); app.use( cors({ origin: '*', - methods: ['GET'], + methods: ['GET', 'HEAD'], }), ); @@ -85,6 +85,34 @@ app.get('/ar-io/resolver/info', (_req, res) => { }); }); +app.head('/ar-io/resolver/records/:name', async (req, res) => { + try { + log.debug('Checking cache for record', { name: req.params.name }); + const resolvedRecordData = await cache.get(req.params.name); + if (!resolvedRecordData) { + res.status(404).send(); + return; + } + const recordData = JSON.parse(resolvedRecordData.toString()); + res + .status(200) + .set({ + 'Cache-Control': `public, max-age=${recordData.ttlSeconds}`, + 'Content-Type': 'application/json', + 'X-ArNS-Resolved-Id': recordData.txId, + 'X-ArNS-Ttl-Seconds': recordData.ttlSeconds, + }) + .send(); + } catch (err: any) { + log.error('Failed to check for record', { + name: req.params.name, + message: err?.message, + stack: err?.stack, + }); + res.status(500).send(); + } +}); + app.get('/ar-io/resolver/records/:name', async (req, res) => { try { // TODO: use barrier synchronization to prevent multiple requests for the same record