Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions packages/client/.aegir.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ const options = {
callCount++
try {

let data
try {
// when passed data from a test where `body=providers.map(prov => JSON.stringify(prov)).join('\n')`
data = { Providers: req.body.split('\n').map(line => JSON.parse(line)) }
} catch (err) {
// when passed data from a test where `body=JSON.stringify({ Providers: providers })`
data = req.body
// if request body content-type was json it's already been parsed
const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body

if (!Array.isArray(data.Providers)) {
throw new Error('Data must be { Providers: [] }')
}

providers.set(req.params.cid, data)
Expand All @@ -50,6 +48,12 @@ const options = {
const providerData = providers.get(req.params.cid) || { Providers: [] }
const acceptHeader = req.headers.accept

if (providerData?.Providers?.length === 0) {
res.statusCode = 404
res.end()
return
}

if (acceptHeader?.includes('application/x-ndjson')) {
res.setHeader('Content-Type', 'application/x-ndjson')
const providers = Array.isArray(providerData.Providers) ? providerData.Providers : []
Expand Down
4 changes: 3 additions & 1 deletion packages/client/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,16 @@ export class DefaultDelegatedRoutingV1HttpApiClient implements DelegatedRoutingV
await onStart.promise

// https://specs.ipfs.tech/routing/http-routing-v1/
const url = new URL(`${this.clientUrl}routing/v1/providers/${cid.toString()}`)
const url = new URL(`${this.clientUrl}routing/v1/providers/${cid}`)

this.#addFilterParams(url, options.filterAddrs, options.filterProtocols)
const getOptions = { headers: { Accept: 'application/x-ndjson' }, signal }
const res = await this.#makeRequest(url.toString(), getOptions)

if (res == null) {
throw new BadResponseError('No response received')
}

if (!res.ok) {
if (res.status === 404) {
// https://specs.ipfs.tech/routing/http-routing-v1/#response-status-codes
Expand Down
20 changes: 15 additions & 5 deletions packages/client/src/routings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,22 @@ export class DelegatedRoutingV1HttpApiClientContentRouting implements ContentRou
}

async * findProviders (cid: CID, options: AbortOptions = {}): AsyncIterable<PeerInfo> {
yield * map(this.client.getProviders(cid, options), (record) => {
return {
id: record.ID,
multiaddrs: record.Addrs ?? []
try {
yield * map(this.client.getProviders(cid, options), (record) => {
return {
id: record.ID,
multiaddrs: record.Addrs ?? []
}
})
} catch (err) {
// NotFoundError means no providers were found so end the iterator instead
// of throwing which means there was an error
if (err instanceof NotFoundError) {
return
}
})

throw err
}
}

async provide (): Promise<void> {
Expand Down
44 changes: 30 additions & 14 deletions packages/client/test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ describe('delegated-routing-v1-http-api-client', () => {
const cid = CID.parse('QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn')

// load providers for the router to fetch
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, {
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid}`, {
method: 'POST',
body: providers.map(prov => JSON.stringify(prov)).join('\n')
body: JSON.stringify({
Providers: providers
})
})

const provs = await all(client.getProviders(cid))
Expand Down Expand Up @@ -84,12 +86,14 @@ describe('delegated-routing-v1-http-api-client', () => {

for (const contentType of contentTypes) {
// Add providers with proper payload structure
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, {
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid}`, {
method: 'POST',
headers: {
'Content-Type': contentType
},
body: JSON.stringify({ Providers: providers })
body: JSON.stringify({
Providers: providers
})
})

await new Promise((resolve) => setTimeout(resolve, 100))
Expand Down Expand Up @@ -122,9 +126,11 @@ describe('delegated-routing-v1-http-api-client', () => {
const cid = CID.parse('QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn')

// load providers for the router to fetch
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, {
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid}`, {
method: 'POST',
body: providers.map(prov => JSON.stringify(prov)).join('\n')
body: JSON.stringify({
Providers: providers
})
})

await all(client.getProviders(cid, { filterProtocols: ['transport-bitswap', 'unknown'], filterAddrs: ['webtransport', '!p2p-circuit'] }))
Expand Down Expand Up @@ -162,9 +168,13 @@ describe('delegated-routing-v1-http-api-client', () => {
const cid = CID.parse('QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn')

// load providers for the router to fetch
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, {
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid}`, {
method: 'POST',
body: 'not json'
body: JSON.stringify({
Providers: [
'not json'
]
})
})

const provs = await all(client.getProviders(cid))
Expand All @@ -188,9 +198,11 @@ describe('delegated-routing-v1-http-api-client', () => {
const cid = CID.parse('QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn')

// load providers for the router to fetch
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, {
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid}`, {
method: 'POST',
body: providers.map(prov => JSON.stringify(prov)).join('\n')
body: JSON.stringify({
Providers: providers
})
})

const provs = await all(client.getProviders(cid))
Expand Down Expand Up @@ -351,9 +363,11 @@ describe('delegated-routing-v1-http-api-client', () => {
}]

// load providers for the router to fetch
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, {
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid}`, {
method: 'POST',
body: providers.map(prov => JSON.stringify(prov)).join('\n')
body: JSON.stringify({
Providers: providers
})
})

// Reset call count before our test
Expand Down Expand Up @@ -404,9 +418,11 @@ describe('delegated-routing-v1-http-api-client', () => {
}]

// load providers for the router to fetch
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, {
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid}`, {
method: 'POST',
body: providers.map(prov => JSON.stringify(prov)).join('\n')
body: JSON.stringify({
Providers: providers
})
})

// Reset call count
Expand Down
32 changes: 28 additions & 4 deletions packages/client/test/routings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,11 @@ describe('libp2p content-routing', () => {
const cid = CID.parse('QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn')

// load providers for the router to fetch
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, {
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid}`, {
method: 'POST',
body: providers.map(prov => JSON.stringify(prov)).join('\n')
body: JSON.stringify({
Providers: providers
})
})

const provs = await all(routing.findProviders(cid))
Expand All @@ -82,6 +84,26 @@ describe('libp2p content-routing', () => {
})))
})

it('should yield no results if no providers exist', async () => {
const routing = getContentRouting(client)

if (routing == null) {
throw new Error('ContentRouting not found')
}

const cid = CID.parse('QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd7')

// load providers for the router to fetch
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid}`, {
method: 'POST',
body: JSON.stringify({
Providers: []
})
})

await expect(all(routing.findProviders(cid))).to.eventually.have.lengthOf(0)
})

it('should respect abort signal when finding providers', async () => {
const routing = getContentRouting(client)

Expand All @@ -97,9 +119,11 @@ describe('libp2p content-routing', () => {
const cid = CID.parse('QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6')

// load providers for the router to fetch
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, {
await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid}`, {
method: 'POST',
body: providers.map(prov => JSON.stringify(prov)).join('\n')
body: JSON.stringify({
Providers: providers
})
})

let findProvidersFinished = false
Expand Down
4 changes: 2 additions & 2 deletions packages/interop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
"lint": "aegir lint",
"dep-check": "aegir dep-check",
"build": "aegir build --bundle false",
"test": "aegir test -t node",
"test:node": "aegir test -t node --cov"
"test": "aegir test -t node -- --exit",
"test:node": "aegir test -t node --cov -- --exit"
},
"devDependencies": {
"@helia/delegated-routing-v1-http-api-client": "^5.0.0",
Expand Down
10 changes: 3 additions & 7 deletions packages/interop/test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,9 @@ describe('delegated-routing-v1-http-api interop', () => {
})

afterEach(async () => {
await stop(client)

if (server != null) {
await server.close()
}

await Promise.all(network.map(async node => node.stop()))
await server?.close()
await stop(client)
})

it('should find providers', async () => {
Expand Down Expand Up @@ -98,7 +94,7 @@ describe('delegated-routing-v1-http-api interop', () => {

// use client to resolve the published record
const record = await client.getIPNS(result.publicKey.toCID())
expect(record.value).to.equal(`/ipfs/${cid.toString()}`)
expect(record.value).to.equal(`/ipfs/${cid}`)
})

it.skip('should put an IPNS record', async () => {
Expand Down