From d8a6c22c606cdef80cf92739b14cc17ae2b42d31 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 23 Jan 2019 12:40:00 -0800 Subject: [PATCH 1/3] fix: add support for resolving to the middle of an IPLD block see: https://github.com/ipfs/interface-ipfs-core/pull/385 --- src/core/components/resolve.js | 29 ++++++++--------- test/core/resolve.spec.js | 57 ++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 test/core/resolve.spec.js diff --git a/src/core/components/resolve.js b/src/core/components/resolve.js index bd23a33b20..8354f3f796 100644 --- a/src/core/components/resolve.js +++ b/src/core/components/resolve.js @@ -34,17 +34,15 @@ module.exports = (self) => { const path = split.slice(3).join('/') - resolve(cid, path, (err, cid) => { + resolve(cid, path, (err, cid, remainder) => { if (err) return cb(err) - if (!cid) return cb(new Error('found non-link at given path')) - cb(null, `/ipfs/${cidToString(cid, { base: opts.cidBase })}`) + cb(null, `/ipfs/${cidToString(cid, { base: opts.cidBase })}${remainder ? '/' + remainder : ''}`) }) }) // Resolve the given CID + path to a CID. function resolve (cid, path, callback) { - let value - + let value, remainder doUntil( (cb) => { self.block.get(cid, (err, block) => { @@ -59,28 +57,27 @@ module.exports = (self) => { r.resolver.resolve(block.data, path, (err, result) => { if (err) return cb(err) value = result.value - path = result.remainderPath + remainder = result.remainderPath cb() }) }) }, () => { - const endReached = !path || path === '/' - - if (endReached) { - return true - } - - if (value) { + if (value && value['/']) { + // If we've hit a CID, replace the current CID. cid = new CID(value['/']) + path = remainder + } else { + // We've hit a value. Return the current CID and the remaining path. + return true } - return false + // Continue resolving unless the path is empty. + return !path || path === '/' }, (err) => { if (err) return callback(err) - if (value && value['/']) return callback(null, new CID(value['/'])) - callback() + callback(null, cid, path) } ) } diff --git a/test/core/resolve.spec.js b/test/core/resolve.spec.js new file mode 100644 index 0000000000..7950e0daa9 --- /dev/null +++ b/test/core/resolve.spec.js @@ -0,0 +1,57 @@ +/* eslint max-nested-callbacks: ["error", 8] */ +/* eslint-env mocha */ +'use strict' + +const chai = require('chai') +const dirtyChai = require('dirty-chai') +const expect = chai.expect +chai.use(dirtyChai) + +const IPFSFactory = require('ipfsd-ctl') +const IPFS = require('../../src/core') + +describe('resolve', () => { + let ipfsd, ipfs + + before(function (done) { + this.timeout(20 * 1000) + + const factory = IPFSFactory.create({ type: 'proc' }) + + factory.spawn({ + exec: IPFS, + initOptions: { bits: 512 }, + config: { Bootstrap: [] } + }, (err, _ipfsd) => { + expect(err).to.not.exist() + ipfsd = _ipfsd + ipfs = _ipfsd.api + done() + }) + }) + + after((done) => { + if (ipfsd) { + ipfsd.stop(done) + } else { + done() + } + }) + + it('should resolve an IPFS path non-link', (done) => { + const content = { path: { to: { file: 'foobar' } } } + const options = { format: 'dag-cbor', hashAlg: 'sha2-256' } + + ipfs.dag.put(content, options, (err, cid) => { + expect(err).to.not.exist() + + // FIXME: This should be /ipld/... but that's not supported yet. + const path = `/ipfs/${cid.toBaseEncodedString()}/path/to/file` + ipfs.resolve(path, (err, resolved) => { + expect(err).to.not.exist() + expect(resolved).to.equal(path) + done() + }) + }) + }) +}) From e99b7ee43467c107e7246147a54c3764ef4e420b Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 19 Feb 2019 13:33:46 +0000 Subject: [PATCH 2/3] fix: resolve when value is a CID or a {'/': 'string cid'} License: MIT Signed-off-by: Alan Shaw --- .aegir.js | 2 +- package.json | 2 +- src/core/components/resolve.js | 17 ++++++---- test/core/resolve.spec.js | 57 ---------------------------------- test/gateway/index.js | 2 +- 5 files changed, 14 insertions(+), 66 deletions(-) delete mode 100644 test/core/resolve.spec.js diff --git a/.aegir.js b/.aegir.js index 43915d90d6..c09767c77d 100644 --- a/.aegir.js +++ b/.aegir.js @@ -15,7 +15,7 @@ module.exports = { }, karma: { files: [{ - pattern: 'node_modules/interface-ipfs-core/js/test/fixtures/**/*', + pattern: 'node_modules/interface-ipfs-core/test/fixtures/**/*', watched: false, served: true, included: false diff --git a/package.json b/package.json index f3bde79f98..6a56c95e8f 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "execa": "^1.0.0", "form-data": "^2.3.3", "hat": "0.0.3", - "interface-ipfs-core": "~0.96.0", + "interface-ipfs-core": "^0.97.0", "ipfsd-ctl": "~0.41.0", "libp2p-websocket-star": "~0.10.2", "ncp": "^2.0.0", diff --git a/src/core/components/resolve.js b/src/core/components/resolve.js index 8354f3f796..1ca80e8249 100644 --- a/src/core/components/resolve.js +++ b/src/core/components/resolve.js @@ -34,15 +34,16 @@ module.exports = (self) => { const path = split.slice(3).join('/') - resolve(cid, path, (err, cid, remainder) => { + resolve(cid, path, (err, res) => { if (err) return cb(err) - cb(null, `/ipfs/${cidToString(cid, { base: opts.cidBase })}${remainder ? '/' + remainder : ''}`) + const { cid, remainderPath } = res + cb(null, `/ipfs/${cidToString(cid, { base: opts.cidBase })}${remainderPath ? '/' + remainderPath : ''}`) }) }) // Resolve the given CID + path to a CID. function resolve (cid, path, callback) { - let value, remainder + let value, remainderPath doUntil( (cb) => { self.block.get(cid, (err, block) => { @@ -57,7 +58,7 @@ module.exports = (self) => { r.resolver.resolve(block.data, path, (err, result) => { if (err) return cb(err) value = result.value - remainder = result.remainderPath + remainderPath = result.remainderPath cb() }) }) @@ -66,7 +67,11 @@ module.exports = (self) => { if (value && value['/']) { // If we've hit a CID, replace the current CID. cid = new CID(value['/']) - path = remainder + path = remainderPath + } else if (CID.isCID(value)) { + // If we've hit a CID, replace the current CID. + cid = value + path = remainderPath } else { // We've hit a value. Return the current CID and the remaining path. return true @@ -77,7 +82,7 @@ module.exports = (self) => { }, (err) => { if (err) return callback(err) - callback(null, cid, path) + callback(null, { cid, remainderPath: path }) } ) } diff --git a/test/core/resolve.spec.js b/test/core/resolve.spec.js deleted file mode 100644 index 7950e0daa9..0000000000 --- a/test/core/resolve.spec.js +++ /dev/null @@ -1,57 +0,0 @@ -/* eslint max-nested-callbacks: ["error", 8] */ -/* eslint-env mocha */ -'use strict' - -const chai = require('chai') -const dirtyChai = require('dirty-chai') -const expect = chai.expect -chai.use(dirtyChai) - -const IPFSFactory = require('ipfsd-ctl') -const IPFS = require('../../src/core') - -describe('resolve', () => { - let ipfsd, ipfs - - before(function (done) { - this.timeout(20 * 1000) - - const factory = IPFSFactory.create({ type: 'proc' }) - - factory.spawn({ - exec: IPFS, - initOptions: { bits: 512 }, - config: { Bootstrap: [] } - }, (err, _ipfsd) => { - expect(err).to.not.exist() - ipfsd = _ipfsd - ipfs = _ipfsd.api - done() - }) - }) - - after((done) => { - if (ipfsd) { - ipfsd.stop(done) - } else { - done() - } - }) - - it('should resolve an IPFS path non-link', (done) => { - const content = { path: { to: { file: 'foobar' } } } - const options = { format: 'dag-cbor', hashAlg: 'sha2-256' } - - ipfs.dag.put(content, options, (err, cid) => { - expect(err).to.not.exist() - - // FIXME: This should be /ipld/... but that's not supported yet. - const path = `/ipfs/${cid.toBaseEncodedString()}/path/to/file` - ipfs.resolve(path, (err, resolved) => { - expect(err).to.not.exist() - expect(resolved).to.equal(path) - done() - }) - }) - }) -}) diff --git a/test/gateway/index.js b/test/gateway/index.js index 54e47e0ba1..0f9ac1812b 100644 --- a/test/gateway/index.js +++ b/test/gateway/index.js @@ -12,7 +12,7 @@ const path = require('path') const hat = require('hat') const fileType = require('file-type') -const bigFile = loadFixture('js/test/fixtures/15mb.random', 'interface-ipfs-core') +const bigFile = loadFixture('test/fixtures/15mb.random', 'interface-ipfs-core') const directoryContent = { 'index.html': loadFixture('test/gateway/test-folder/index.html'), 'nested-folder/hello.txt': loadFixture('test/gateway/test-folder/nested-folder/hello.txt'), From 02db2301ce5adf5c88981f3d8ed449d371fb694b Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 19 Feb 2019 13:43:23 +0000 Subject: [PATCH 3/3] chore: appease linter License: MIT Signed-off-by: Alan Shaw --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6a56c95e8f..a64d1b08c6 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "execa": "^1.0.0", "form-data": "^2.3.3", "hat": "0.0.3", - "interface-ipfs-core": "^0.97.0", + "interface-ipfs-core": "~0.97.0", "ipfsd-ctl": "~0.41.0", "libp2p-websocket-star": "~0.10.2", "ncp": "^2.0.0",