Skip to content

Commit

Permalink
feat: support IPFS/IPNS paths, Gateways, etc
Browse files Browse the repository at this point in the history
Adds support for fetching resources in the form:

- IPFS Path, e.g. `/ipfs/<CID>`
- IPNS Path, e.g. `/ipns/<PeerId>`
- IPFS Gateway Path, e.g. `http://example.com/ipfs/<CID>`
- IPNS Gateway Path, e.g. `http://example.com/ipns/<PeerId>`
- IPFS Subdomain Gateway Path, e.g. `http://<CID>.ipfs.example.com`
- IPNS Subdomain Gateway Path, e.g. `http://<PeerId>.ipns.example.com`
  • Loading branch information
achingbrain committed Feb 29, 2024
1 parent fd86e6a commit 44933f6
Show file tree
Hide file tree
Showing 2 changed files with 368 additions and 7 deletions.
23 changes: 16 additions & 7 deletions packages/verified-fetch/src/utils/parse-url-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ export interface ParsedUrlStringResults {
}

const URL_REGEX = /^(?<protocol>ip[fn]s):\/\/(?<cidOrPeerIdOrDnsLink>[^/$?]+)\/?(?<path>[^$?]*)\??(?<queryString>.*)$/
const PATH_REGEX = /^\/(?<protocol>ip[fn]s)\/(?<cidOrPeerIdOrDnsLink>[^/$?]+)\/?(?<path>[^$?]*)\??(?<queryString>.*)$/
const PATH_GATEWAY_REGEX = /^http(s?):\/\/(.*)\/(?<protocol>ip[fn]s)\/(?<cidOrPeerIdOrDnsLink>[^/$?]+)\/?(?<path>[^$?]*)\??(?<queryString>.*)$/
const SUBDOMAIN_GATEWAY_REGEX = /^http(s?):\/\/(?<cidOrPeerIdOrDnsLink>[^/$?]+)\.(?<protocol>ip[fn]s)\.([^/?]*)\/?(?<path>[^$?]*)\??(?<queryString>.*)$/

function matchURLString (urlString: string): Record<string, string> {
for (const pattern of [URL_REGEX, PATH_REGEX, PATH_GATEWAY_REGEX, SUBDOMAIN_GATEWAY_REGEX]) {
const match = urlString.match(pattern)

if (match?.groups != null) {
return match.groups
}
}

throw new TypeError(`Invalid URL: ${urlString}, please use ipfs:// or ipns:// URLs only.`)
}

/**
* A function that parses ipfs:// and ipns:// URLs, returning an object with easily recognizable properties.
Expand All @@ -41,13 +56,7 @@ const URL_REGEX = /^(?<protocol>ip[fn]s):\/\/(?<cidOrPeerIdOrDnsLink>[^/$?]+)\/?
*/
export async function parseUrlString ({ urlString, ipns, logger }: ParseUrlStringInput, options?: ParseUrlStringOptions): Promise<ParsedUrlStringResults> {
const log = logger.forComponent('helia:verified-fetch:parse-url-string')
const match = urlString.match(URL_REGEX)

if (match == null || match.groups == null) {
throw new TypeError(`Invalid URL: ${urlString}, please use ipfs:// or ipns:// URLs only.`)
}

const { protocol, cidOrPeerIdOrDnsLink, path: urlPath, queryString } = match.groups
const { protocol, cidOrPeerIdOrDnsLink, path: urlPath, queryString } = matchURLString(urlString)

let cid: CID | undefined
let resolvedPath: string | undefined
Expand Down
Loading

0 comments on commit 44933f6

Please sign in to comment.