diff --git a/packages/verified-fetch/src/utils/parse-url-string.ts b/packages/verified-fetch/src/utils/parse-url-string.ts index a3eb8bd3..d406710e 100644 --- a/packages/verified-fetch/src/utils/parse-url-string.ts +++ b/packages/verified-fetch/src/utils/parse-url-string.ts @@ -26,8 +26,9 @@ export interface ParsedUrlQuery extends Record { interface ParsedUrlStringResultsBase extends ResolveResult { protocol: 'ipfs' | 'ipns' query: ParsedUrlQuery + /** - * milliseconds as a number + * seconds as a number */ ttl?: number } @@ -59,9 +60,12 @@ function matchURLString (urlString: string): MatchUrlGroups { } /** - * determines the TTL for the resolved resource. + * determines the TTL for the resolved resource that will be used for the `Cache-Control` header's `max-age` directive. + * max-age is in seconds + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#response_directives * - * If we have ipnsTtlNs, it will be a BigInt representing nanoseconds. We need to convert it back to milliseconds. + * If we have ipnsTtlNs, it will be a BigInt representing "nanoseconds". We need to convert it back to seconds. * * For more TTL nuances: * @@ -74,7 +78,8 @@ function calculateTtl (resolveResult?: IPNSResolveResult | DNSLinkResolveResult) } const dnsLinkTtl = (resolveResult as DNSLinkResolveResult).answer?.TTL const ipnsTtlNs = (resolveResult as IPNSResolveResult).record?.ttl - const ipnsTtl = ipnsTtlNs != null ? Number(BigInt(ipnsTtlNs) / BigInt(1e5)) : undefined + // For some reason, ipns "nanoseconds" are 1e-8 of a second, instead of 1e-9. + const ipnsTtl = ipnsTtlNs != null ? Number(ipnsTtlNs / BigInt(1e8)) : undefined return dnsLinkTtl ?? ipnsTtl } diff --git a/packages/verified-fetch/src/utils/response-headers.ts b/packages/verified-fetch/src/utils/response-headers.ts index b807891b..47574dc8 100644 --- a/packages/verified-fetch/src/utils/response-headers.ts +++ b/packages/verified-fetch/src/utils/response-headers.ts @@ -1,4 +1,9 @@ interface CacheControlHeaderOptions { + /** + * This should be seconds as a number. + * + * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#response_directives + */ ttl?: number protocol: 'ipfs' | 'ipns' response: Response diff --git a/packages/verified-fetch/test/cache-control-header.spec.ts b/packages/verified-fetch/test/cache-control-header.spec.ts index 02bb689b..0cfe1268 100644 --- a/packages/verified-fetch/test/cache-control-header.spec.ts +++ b/packages/verified-fetch/test/cache-control-header.spec.ts @@ -88,7 +88,7 @@ describe('cache-control header', () => { const c = dagCbor(helia) const cid = await c.add(obj) - const oneHourInMs = 1000 * 60 * 60 + const oneHourInSeconds = 60 * 60 const peerId = await createEd25519PeerId() /** @@ -99,13 +99,13 @@ describe('cache-control header', () => { * @see https://github.com/ipfs/js-ipns/blob/16e0e10682fa9a663e0bb493a44d3e99a5200944/src/index.ts#L200 * @see https://github.com/ipfs/js-ipns/pull/308 */ - await name.publish(peerId, cid, { lifetime: oneHourInMs }) + await name.publish(peerId, cid, { lifetime: oneHourInSeconds * 1000 }) // pass to ipns as milliseconds const resp = await verifiedFetch.fetch(`ipns://${peerId}`) expect(resp).to.be.ok() expect(resp.status).to.equal(200) - expect(resp.headers.get('Cache-Control')).to.equal(`public, max-age=${oneHourInMs}`) + expect(resp.headers.get('Cache-Control')).to.equal(`public, max-age=${oneHourInSeconds}`) }) it('should not contain immutable in the cache-control header for a DNSLink name', async () => {