@helia/verified-fetch
Version:
A fetch-like API for obtaining verified & trustless IPFS content on the web
60 lines (52 loc) • 1.99 kB
text/typescript
import type { RequestFormatShorthand } from '../types.js'
import type { CID } from 'multiformats/cid'
interface GetETagArg {
cid: CID
reqFormat?: RequestFormatShorthand
rangeStart?: number
rangeEnd?: number
/**
* Weak Etag is used when we can't guarantee byte-for-byte-determinism (generated, or mutable content).
* Some examples:
* - IPNS requests
* - CAR streamed with blocks in non-deterministic order
* - TAR streamed with files in non-deterministic order
*/
weak?: boolean
/**
* A custom prefix to use for the content of the etag. This is needed for some cases (like dir-index-html) where we need to use a custom prefix for the etag.
*/
contentPrefix?: string
}
const getPrefix = ({ weak, reqFormat }: Partial<GetETagArg>): string => {
if (reqFormat === 'tar' || reqFormat === 'car' || reqFormat === 'ipns-record' || weak === true) {
return 'W/'
}
return ''
}
const getFormatSuffix = ({ reqFormat }: Partial<GetETagArg>): string => {
if (reqFormat == null) {
return ''
}
if (reqFormat === 'tar') {
return '.x-tar'
}
return `.${reqFormat}`
}
/**
* etag
* you need to wrap cid with ""
* we use strong Etags for immutable responses and weak one (prefixed with W/ ) for mutable/generated ones (ipns, car, tar, and generated HTML).
* block and car responses should have different etag than deserialized one, so you can add some prefix like we do in existing gateway
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag
* @see https://specs.ipfs.tech/http-gateways/path-gateway/#etag-response-header
*/
export function getETag ({ cid, reqFormat, weak, rangeStart, rangeEnd, contentPrefix }: GetETagArg): string {
const prefix = getPrefix({ weak, reqFormat })
let suffix = getFormatSuffix({ reqFormat })
if (rangeStart != null || rangeEnd != null) {
suffix += `.${rangeStart ?? '0'}-${rangeEnd ?? 'N'}`
}
return `${prefix}"${contentPrefix ?? ''}${cid.toString()}${suffix}"`
}