Skip to content

Commit

Permalink
feat: support for http-path multiaddr (#131)
Browse files Browse the repository at this point in the history
* copied mutliaddr func

* add test for malformed http-path address

* formatting

* fmt

* fmt

---------

Co-authored-by: Nikolas Haimerl <[email protected]>
  • Loading branch information
2 people authored and pyropy committed Feb 26, 2025
1 parent 77c91ab commit 3a9c768
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 8 deletions.
35 changes: 28 additions & 7 deletions indexer/lib/vendored/multiaddr.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,31 @@
* @returns {string} Parsed URI, e.g. `http://127.0.0.1:80`
*/
export function multiaddrToHttpUrl (addr) {
const [, hostType, hostValue, ipProtocol, port, scheme, ...rest] = addr.split('/')
const [multiAddr, httpPathMultiAddr] = addr.split('/http-path')
const [, hostType, hostValue, ...multiAddrParts] = multiAddr.split('/')
let scheme, path, rest, port
if (addr.includes('/http-path')) {
[scheme, ...rest] = multiAddrParts
try {
// Remove leading slash and parse URI-encoded path
// See https://github.com/multiformats/multiaddr/blob/cab92e8e6da2e70c5f1b8aa59976e71e6922b392/protocols/http-path.md#usage
path = decodeURIComponent(httpPathMultiAddr.substring(1))
} catch (err) {
throw Object.assign(
new Error(`Cannot parse "${addr}": unsupported http path`, { cause: err }),
{ code: 'INVALID_HTTP_PATH' }
)
}
} else {
let ipProtocol
;[ipProtocol, port, scheme, ...rest] = multiAddrParts

if (ipProtocol !== 'tcp') {
throw Object.assign(
new Error(`Cannot parse "${addr}": unsupported protocol "${ipProtocol}"`),
{ code: 'UNSUPPORTED_MULTIADDR_PROTO' }
)
if (ipProtocol !== 'tcp') {
throw Object.assign(
new Error(`Cannot parse "${addr}": unsupported protocol "${ipProtocol}"`),
{ code: 'UNSUPPORTED_MULTIADDR_PROTO' }
)
}
}

if (scheme !== 'http' && scheme !== 'https') {
Expand All @@ -29,7 +47,10 @@ export function multiaddrToHttpUrl (addr) {
)
}

return `${scheme}://${getUriHost(hostType, hostValue)}${getUriPort(scheme, port)}`
let url = `${scheme}://${getUriHost(hostType, hostValue)}`
if (port) url += getUriPort(scheme, port)
if (path) url += path
return url
}

function getUriHost (hostType, hostValue) {
Expand Down
21 changes: 20 additions & 1 deletion indexer/test/advertisement-walker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ const knownAdvertisement = {
payloadCid: 'bafkreigrnnl64xuevvkhknbhrcqzbdvvmqnchp7ae2a4ulninsjoc5svoq',
pieceCid: 'baga6ea4seaqlwzed5tgjtyhrugjziutzthx2wrympvsuqhfngwdwqzvosuchmja'
}

describe('processNextAdvertisement', () => {
it('ignores non-HTTP(s) addresses and explains the problem in the status', async () => {
/** @type {ProviderInfo} */
Expand All @@ -58,6 +57,26 @@ describe('processNextAdvertisement', () => {
})
})

it('ignores malformed http-path addresses and explains the problem in the status', async () => {
/** @type {ProviderInfo} */
const providerInfo = {
providerAddress: '/dns/meridian.space/http/http-path/invalid%path',
lastAdvertisementCID: 'baguqeeraTEST'
}

const result = await processNextAdvertisement({
providerId,
providerInfo,
walkerState: undefined
})
assert.deepStrictEqual(result, {
finished: true,
newState: {
status: 'Index provider advertises over an unsupported protocol: /dns/meridian.space/http/http-path/invalid%path'
}
})
})

it('handles a new index provider not seen before', async () => {
/** @type {ProviderInfo} */
const providerInfo = {
Expand Down

0 comments on commit 3a9c768

Please sign in to comment.