Skip to content

Commit 3f64347

Browse files
committed
Allow hash algorithm to be passed, allow object get/data via CID
1 parent 53aeea2 commit 3f64347

File tree

6 files changed

+60
-44
lines changed

6 files changed

+60
-44
lines changed

src/cli/commands/files/add.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,18 @@ module.exports = {
183183
throw new Error('Implied argument raw-leaves must be passed and set to false when cid-version is > 0')
184184
}
185185

186+
// Temporary restriction on raw-leaves:
187+
// When hash != undefined then raw-leaves MUST be present and false.
188+
//
189+
// This is because raw-leaves is not yet implemented in js-ipfs,
190+
// and go-ipfs changes the value of raw-leaves to true when
191+
// hash != undefined unless explicitly set to false.
192+
//
193+
// This retains feature parity without having to implement raw-leaves.
194+
if (argv.hash && argv.rawLeaves !== false) {
195+
throw new Error('Implied argument raw-leaves must be passed and set to false when hash argument is specified')
196+
}
197+
186198
if (argv.rawLeaves) {
187199
throw new Error('Not implemented: raw-leaves')
188200
}

src/core/components/files.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ module.exports = function files (self) {
2020
shardSplitThreshold: self._options.EXPERIMENTAL.sharding ? 1000 : Infinity
2121
}, options)
2222

23-
// CID v0 is for multihashes encoded with sha2-256
24-
if (opts.hashAlg && opts.hashAlg !== 'sha2-256' && opts.cidVersion !== 1) {
23+
if (opts.hashAlg && opts.cidVersion !== 1) {
2524
opts.cidVersion = 1
2625
}
2726

@@ -70,8 +69,10 @@ module.exports = function files (self) {
7069
return callback(new Error('Invalid arguments, data must be an object, Buffer or readable stream'))
7170
}
7271

72+
options = options || {}
73+
7374
// CID v0 is for multihashes encoded with sha2-256
74-
if (options && options.hashAlg && options.hashAlg !== 'sha2-256' && options.cidVersion !== 1) {
75+
if (options.hashAlg && options.cidVersion !== 1) {
7576
options.cidVersion = 1
7677
}
7778

@@ -127,15 +128,15 @@ module.exports = function files (self) {
127128
function prepareFile (self, opts, file, callback) {
128129
opts = opts || {}
129130

130-
waterfall([
131-
(cb) => self.object.get(file.multihash, cb),
132-
(node, cb) => {
133-
let cid = new CID(file.multihash)
131+
let cid = new CID(file.multihash)
134132

135-
if (opts.cidVersion === 1) {
136-
cid = cid.toV1()
137-
}
133+
if (opts.cidVersion === 1) {
134+
cid = cid.toV1()
135+
}
138136

137+
waterfall([
138+
(cb) => self.object.get(cid, cb),
139+
(node, cb) => {
139140
const b58Hash = cid.toBaseEncodedString()
140141

141142
cb(null, {

src/core/components/object.js

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,6 @@ const mh = require('multihashes')
1010
const Unixfs = require('ipfs-unixfs')
1111
const assert = require('assert')
1212

13-
function normalizeMultihash (multihash, enc) {
14-
if (typeof multihash === 'string') {
15-
if (enc === 'base58' || !enc) {
16-
return multihash
17-
}
18-
19-
return new Buffer(multihash, enc)
20-
} else if (Buffer.isBuffer(multihash)) {
21-
return multihash
22-
} else {
23-
throw new Error('unsupported multihash')
24-
}
25-
}
26-
2713
function parseBuffer (buf, encoding, callback) {
2814
switch (encoding) {
2915
case 'json':
@@ -178,20 +164,19 @@ module.exports = function object (self) {
178164
}
179165
}),
180166

181-
get: promisify((multihash, options, callback) => {
167+
get: promisify((hash, options, callback) => {
182168
if (typeof options === 'function') {
183169
callback = options
184170
options = {}
185171
}
186172

187-
let mh
173+
let cid
188174

189175
try {
190-
mh = normalizeMultihash(multihash, options.enc)
176+
cid = new CID(hash)
191177
} catch (err) {
192178
return callback(err)
193179
}
194-
const cid = new CID(mh)
195180

196181
self._ipldResolver.get(cid, (err, result) => {
197182
if (err) {
@@ -204,13 +189,21 @@ module.exports = function object (self) {
204189
})
205190
}),
206191

207-
data: promisify((multihash, options, callback) => {
192+
data: promisify((hash, options, callback) => {
208193
if (typeof options === 'function') {
209194
callback = options
210195
options = {}
211196
}
212197

213-
self.object.get(multihash, options, (err, node) => {
198+
let cid
199+
200+
try {
201+
cid = new CID(hash)
202+
} catch (err) {
203+
return callback(err)
204+
}
205+
206+
self.object.get(cid, options, (err, node) => {
214207
if (err) {
215208
return callback(err)
216209
}

src/http-api/resources/files.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,19 @@ exports.add = {
145145
query: Joi.object()
146146
.keys({
147147
'cid-version': Joi.number().integer().min(0).max(1),
148+
hash: Joi.string().valid(Object.keys(mh.names)),
148149
// Temporary restriction on raw-leaves:
149-
// When cid-version=1 then raw-leaves MUST be present and false.
150+
// When cid-version > 0 or hash != undefined then raw-leaves MUST be
151+
// present and false.
150152
//
151153
// This is because raw-leaves is not yet implemented in js-ipfs,
152154
// and go-ipfs changes the value of raw-leaves to true when
153-
// cid-version > 0 unless explicitly set to false.
155+
// cid-version > 0 or hash != undefined unless explicitly set to false.
154156
//
155157
// This retains feature parity without having to implement raw-leaves.
156-
'raw-leaves': Joi.any().when('cid-version', {
157-
is: 1,
158-
then: Joi.boolean().valid(false).required(),
159-
otherwise: Joi.boolean().valid(false)
160-
}),
161-
hash: Joi.string().valid(Object.keys(mh.names))
158+
'raw-leaves': Joi.boolean().valid(false)
159+
.when('cid-version', { is: 1, then: Joi.required() })
160+
.when('hash', { is: Joi.string(), then: Joi.required() })
162161
})
163162
// TODO: Necessary until validate "recursive", "stream-channels" etc.
164163
.options({ allowUnknown: true })

src/http-api/resources/object.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const DAGLink = dagPB.DAGLink
77
const DAGNode = dagPB.DAGNode
88
const waterfall = require('async/waterfall')
99
const series = require('async/series')
10+
const CID = require('cids')
1011
const debug = require('debug')
1112
const log = debug('jsipfs:http-api:object')
1213
log.error = debug('jsipfs:http-api:object:error')
@@ -20,9 +21,7 @@ exports.parseKey = (request, reply) => {
2021
}
2122

2223
try {
23-
return reply({
24-
key: mh.fromB58String(request.query.arg)
25-
})
24+
return reply({ key: new CID(request.query.arg) })
2625
} catch (err) {
2726
log.error(err)
2827
return reply({

test/cli/files.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ const CID = require('cids')
1010
const mh = require('multihashes')
1111
const runOnAndOff = require('../utils/on-and-off')
1212

13+
// TODO: Test against all algorithms Object.keys(mh.names)
14+
// This subset is known to work with both go-ipfs and js-ipfs as of 2017-09-05
15+
const HASH_ALGS = [
16+
'sha1',
17+
'sha2-256',
18+
'sha2-512',
19+
'keccak-224',
20+
'keccak-256',
21+
'keccak-384',
22+
'keccak-512'
23+
]
24+
1325
describe('files', () => runOnAndOff((thing) => {
1426
let ipfs
1527
const readme = fs.readFileSync(path.join(process.cwd(), '/src/init-files/init-docs/readme'))
@@ -224,9 +236,9 @@ describe('files', () => runOnAndOff((thing) => {
224236
})
225237
})
226238

227-
Object.keys(mh.names).forEach((name) => {
228-
it('add with hash=' + name, () => {
229-
return ipfs('add src/init-files/init-docs/readme --hash=' + name)
239+
HASH_ALGS.forEach((name) => {
240+
it(`add with hash=${name} and raw-leaves=false`, () => {
241+
return ipfs(`add src/init-files/init-docs/readme --hash=${name} --raw-leaves=false`)
230242
.then((out) => {
231243
const hash = out.split(' ')[1]
232244
const cid = new CID(hash)

0 commit comments

Comments
 (0)