Skip to content

Commit

Permalink
fix: append query path to path resolved from IPNS name (#3)
Browse files Browse the repository at this point in the history
If an IPNS name resolves to a CID+path, and the requested URL also
has a path, the resolved path should be the path from the IPNS
record joined with the path from the requested URL, not the other
way round.
  • Loading branch information
achingbrain committed Feb 29, 2024
1 parent b9b959b commit fd86e6a
Show file tree
Hide file tree
Showing 4 changed files with 406 additions and 341 deletions.
1 change: 1 addition & 0 deletions packages/verified-fetch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
"@helia/json": "^3.0.1",
"@helia/utils": "^0.0.2",
"@ipld/car": "^5.3.0",
"@libp2p/interface-compliance-tests": "^5.3.2",
"@libp2p/logger": "^4.0.7",
"@libp2p/peer-id-factory": "^4.0.7",
"@sgtpooki/file-type": "^1.0.1",
Expand Down
51 changes: 33 additions & 18 deletions packages/verified-fetch/src/utils/parse-url-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,19 @@ export async function parseUrlString ({ urlString, ipns, logger }: ParseUrlStrin
resolvedPath = resolveResult?.path
log.trace('resolved %s to %c', cidOrPeerIdOrDnsLink, cid)
ipnsCache.set(cidOrPeerIdOrDnsLink, resolveResult, 60 * 1000 * 2)
} catch (err) {
} catch (err: any) {
log.error('Could not resolve DnsLink for "%s"', cidOrPeerIdOrDnsLink, err)
errors.push(err as Error)
errors.push(err)
}
}
}
}

if (cid == null) {
if (errors.length === 1) {
throw errors[0]
}

throw new AggregateError(errors, `Invalid resource. Cannot determine CID from URL "${urlString}"`)
}

Expand All @@ -129,26 +133,37 @@ export async function parseUrlString ({ urlString, ipns, logger }: ParseUrlStrin
}
}

/**
* join the path from resolve result & given path.
* e.g. /ipns/<peerId>/ that is resolved to /ipfs/<cid>/<path1>, when requested as /ipns/<peerId>/<path2>, should be
* resolved to /ipfs/<cid>/<path1>/<path2>
*/
const pathParts = []
return {
protocol,
cid,
path: joinPaths(resolvedPath, urlPath),
query
}
}

if (urlPath.length > 0) {
pathParts.push(urlPath)
/**
* join the path from resolve result & given path.
* e.g. /ipns/<peerId>/ that is resolved to /ipfs/<cid>/<path1>, when requested as /ipns/<peerId>/<path2>, should be
* resolved to /ipfs/<cid>/<path1>/<path2>
*/
function joinPaths (resolvedPath: string | undefined, urlPath: string): string {
let path = ''

if (resolvedPath != null) {
path += resolvedPath
}

if (resolvedPath != null && resolvedPath.length > 0) {
pathParts.push(resolvedPath)
if (urlPath.length > 0) {
path = `${path.length > 0 ? `${path}/` : path}${urlPath}`
}
const path = pathParts.join('/')

return {
protocol,
cid,
path,
query
// replace duplicate forward slashes
path = path.replace(/\/(\/)+/g, '/')

// strip trailing forward slash if present
if (path.startsWith('/')) {
path = path.substring(1)
}

return path
}
Loading

0 comments on commit fd86e6a

Please sign in to comment.