Skip to content
This repository has been archived by the owner on Mar 10, 2020. It is now read-only.

Commit

Permalink
feat: Support specify hash algorithm in files.add (#597)
Browse files Browse the repository at this point in the history
*  support support specify hash alg

* Add test for add with --hash option. Pass raw cid/multihash to ipfs object get/data

* Allow object get/data to accept CID

* Var naming tweaks from review
  • Loading branch information
alanshaw authored and daviddias committed Sep 8, 2017
1 parent 5aa613b commit ed68657
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 18 deletions.
22 changes: 21 additions & 1 deletion src/files/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,27 @@ module.exports = (send) => {
return callback(new Error('"files" must be a buffer, readable stream, or array of objects'))
}

const request = { path: 'add', files: files, qs: opts }
const qs = {}

if (opts['cid-version'] != null) {
qs['cid-version'] = opts['cid-version']
} else if (opts.cidVersion != null) {
qs['cid-version'] = opts.cidVersion
}

if (opts['raw-leaves'] != null) {
qs['raw-leaves'] = opts['raw-leaves']
} else if (opts.rawLeaves != null) {
qs['raw-leaves'] = opts.rawLeaves
}

if (opts.hash != null) {
qs.hash = opts.hash
} else if (opts.hashAlg != null) {
qs.hash = opts.hashAlg
}

const request = { path: 'add', files: files, qs: qs }

// Transform the response stream to DAGNode values
const transform = (res, callback) => DAGNodeStream.streamToValue(send, res, callback)
Expand Down
13 changes: 8 additions & 5 deletions src/object/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const promisify = require('promisify-es6')
const streamToValue = require('../utils/stream-to-value')
const cleanMultihash = require('../utils/clean-multihash')
const CID = require('cids')
const LRU = require('lru-cache')
const lruOptions = {
max: 128
Expand All @@ -11,7 +11,7 @@ const lruOptions = {
const cache = LRU(lruOptions)

module.exports = (send) => {
return promisify((multihash, options, callback) => {
return promisify((cid, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
Expand All @@ -20,21 +20,24 @@ module.exports = (send) => {
options = {}
}

let cidB58Str

try {
multihash = cleanMultihash(multihash, options)
cid = new CID(cid)
cidB58Str = cid.toBaseEncodedString()
} catch (err) {
return callback(err)
}

const node = cache.get(multihash)
const node = cache.get(cidB58Str)

if (node) {
return callback(null, node.data)
}

send({
path: 'object/data',
args: multihash
args: cidB58Str
}, (err, result) => {
if (err) {
return callback(err)
Expand Down
15 changes: 9 additions & 6 deletions src/object/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const dagPB = require('ipld-dag-pb')
const DAGNode = dagPB.DAGNode
const DAGLink = dagPB.DAGLink
const bs58 = require('bs58')
const cleanMultihash = require('../utils/clean-multihash')
const CID = require('cids')
const LRU = require('lru-cache')
const lruOptions = {
max: 128
Expand All @@ -14,7 +14,7 @@ const lruOptions = {
const cache = LRU(lruOptions)

module.exports = (send) => {
return promisify((multihash, options, callback) => {
return promisify((cid, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
Expand All @@ -24,21 +24,24 @@ module.exports = (send) => {
options = {}
}

let cidB58Str

try {
multihash = cleanMultihash(multihash, options)
cid = new CID(cid)
cidB58Str = cid.toBaseEncodedString()
} catch (err) {
return callback(err)
}

const node = cache.get(multihash)
const node = cache.get(cidB58Str)

if (node) {
return callback(null, node)
}

send({
path: 'object/get',
args: multihash
args: cidB58Str
}, (err, result) => {
if (err) {
return callback(err)
Expand All @@ -52,7 +55,7 @@ module.exports = (send) => {
if (err) {
return callback(err)
}
cache.set(multihash, node)
cache.set(cidB58Str, node)
callback(null, node)
})
})
Expand Down
15 changes: 9 additions & 6 deletions src/utils/get-dagnode.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,24 @@
const DAGNode = require('ipld-dag-pb').DAGNode
const parallel = require('async/parallel')
const CID = require('cids')
const mh = require('multihashes')
const streamToValue = require('./stream-to-value')

module.exports = function (send, hash, callback) {
// Until js-ipfs supports object/get and object/data by CID
// we need to convert our CID or multihash hash into a multihash
const multihash = mh.toB58String(new CID(hash).multihash)
let cid

try {
cid = new CID(hash)
} catch (err) {
return callback(err)
}

// Retrieve the object and its data in parallel, then produce a DAGNode
// instance using this information.
parallel([
(done) => {
send({
path: 'object/get',
args: multihash
args: cid.toBaseEncodedString()
}, done)
},
(done) => {
Expand All @@ -26,7 +29,7 @@ module.exports = function (send, hash, callback) {
// See https://github.com/ipfs/go-ipfs/issues/1582 for more details.
send({
path: 'object/data',
args: multihash
args: cid.toBaseEncodedString()
}, done)
}
], (err, res) => {
Expand Down
51 changes: 51 additions & 0 deletions test/files.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,27 @@ const expect = chai.expect
chai.use(dirtyChai)
const isNode = require('detect-node')
const loadFixture = require('aegir/fixtures')
const mh = require('multihashes')
const CID = require('cids')

const FactoryClient = require('./ipfs-factory/client')

const testfile = isNode
? loadFixture(__dirname, '/fixtures/testfile.txt')
: loadFixture(__dirname, 'fixtures/testfile.txt')

// TODO: Test against all algorithms Object.keys(mh.names)
// This subset is known to work with both go-ipfs and js-ipfs as of 2017-09-05
const HASH_ALGS = [
'sha1',
'sha2-256',
'sha2-512',
'keccak-224',
'keccak-256',
'keccak-384',
'keccak-512'
]

describe('.files (the MFS API part)', function () {
this.timeout(120 * 1000)

Expand Down Expand Up @@ -73,6 +87,25 @@ describe('.files (the MFS API part)', function () {
})
})

HASH_ALGS.forEach((name) => {
it(`files.add with hash=${name} and raw-leaves=false`, (done) => {
const content = String(Math.random() + Date.now())
const file = {
path: content + '.txt',
content: Buffer.from(content)
}
const options = { hash: name, 'raw-leaves': false }

ipfs.files.add([file], options, (err, res) => {
if (err) return done(err)
expect(res).to.have.length(1)
const cid = new CID(res[0].hash)
expect(mh.decode(cid.multihash).name).to.equal(name)
done()
})
})
})

it('files.mkdir', (done) => {
ipfs.files.mkdir('/test-folder', done)
})
Expand Down Expand Up @@ -230,6 +263,24 @@ describe('.files (the MFS API part)', function () {
})
})

HASH_ALGS.forEach((name) => {
it(`files.add with hash=${name} and raw-leaves=false`, () => {
const content = String(Math.random() + Date.now())
const file = {
path: content + '.txt',
content: Buffer.from(content)
}
const options = { hash: name, 'raw-leaves': false }

return ipfs.files.add([file], options)
.then((res) => {
expect(res).to.have.length(1)
const cid = new CID(res[0].hash)
expect(mh.decode(cid.multihash).name).to.equal(name)
})
})
})

it('files.mkdir', () => {
return ipfs.files.mkdir('/test-folder')
})
Expand Down

0 comments on commit ed68657

Please sign in to comment.