Skip to content
This repository was archived by the owner on Sep 28, 2021. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f284f76

Browse files
achingbrainvasco-santos
authored andcommittedMay 7, 2019
feat: load files/dirs from hamt shards
Use the HAMT support and IPFS overlay build in to the mfs related files commands to enable loading files from HAMT shards.
1 parent 18a6d21 commit f284f76

File tree

1 file changed

+40
-123
lines changed

1 file changed

+40
-123
lines changed
 

‎src/resolver.js

+40-123
Original file line numberDiff line numberDiff line change
@@ -2,151 +2,68 @@
22

33
const mh = require('multihashes')
44
const promisify = require('promisify-es6')
5-
const reduce = require('async/reduce')
65
const CID = require('cids')
7-
const Unixfs = require('ipfs-unixfs')
86
const debug = require('debug')
7+
const tryEach = require('async/tryEach')
8+
const waterfall = require('async/waterfall')
99
const log = debug('jsipfs:http:response:resolver')
1010
log.error = debug('jsipfs:http:response:resolver:error')
11-
1211
const dirView = require('./dir-view')
13-
const pathUtil = require('./utils/path')
1412

15-
function getIndexFiles (links) {
16-
const INDEX_HTML_FILES = [
17-
'index.html',
18-
'index.htm',
19-
'index.shtml'
20-
]
21-
// directory
22-
let indexes = links.filter((link) => INDEX_HTML_FILES.indexOf(link.name) !== -1)
23-
if (indexes.length) {
24-
return indexes
25-
}
26-
// hamt-sharded-directory uses a 2 char prefix
27-
return links.filter((link) => {
28-
return link.name.length > 2 && INDEX_HTML_FILES.indexOf(link.name.substring(2)) !== -1
29-
})
30-
}
13+
const INDEX_HTML_FILES = [
14+
'index.html',
15+
'index.htm',
16+
'index.shtml'
17+
]
3118

3219
const directory = promisify((ipfs, path, cid, callback) => {
33-
cid = new CID(cid)
34-
35-
ipfs.object.get(cid.buffer, (err, dagNode) => {
36-
if (err) {
37-
return callback(err)
20+
// Test if it is a Website
21+
return tryEach(INDEX_HTML_FILES.map(file => {
22+
return (cb) => {
23+
waterfall([
24+
(cb) => ipfs.files.stat(`${path}/${file}`, cb),
25+
(_, cb) => cb(null, { name: file })
26+
], cb)
3827
}
28+
}), (err, res) => {
29+
if (err) {
30+
if (err.message.includes('does not exist')) {
31+
// not a website, just show a directory listing
32+
return ipfs.dag.get(cid, (err, result) => {
33+
if (err) {
34+
return callback(err)
35+
}
3936

40-
// Test if it is a Website
41-
const indexFiles = getIndexFiles(dagNode.links)
37+
return callback(null, dirView.render(path, result.value.links))
38+
})
39+
}
4240

43-
if (indexFiles.length) {
44-
return callback(null, indexFiles)
41+
return callback(err)
4542
}
4643

47-
return callback(null, dirView.render(path, dagNode.links))
44+
callback(err, [ res ])
4845
})
4946
})
5047

5148
const cid = promisify((ipfs, path, callback) => {
52-
const parts = pathUtil.cidArray(path)
53-
let firstCid = parts.shift()
54-
let currentCid
55-
56-
// TODO: replace below with ipfs.resolve(path, {recursive: true})
57-
// (requires changes to js-ipfs/js-ipfs-api)
58-
59-
reduce(
60-
parts,
61-
firstCid,
62-
(memo, item, next) => {
63-
try {
64-
currentCid = new CID(memo)
65-
} catch (err) {
66-
return next(err)
67-
}
68-
69-
log('memo: ', memo)
70-
log('item: ', item)
71-
72-
ipfs.dag.get(currentCid, (err, result) => {
73-
if (err) {
74-
return next(err)
75-
}
76-
77-
const dagNode = result.value
78-
// find multihash/cid of requested named-file in current dagNode's links
79-
let cidOfNextFile
80-
const nextFileName = item
81-
82-
try {
83-
for (let link of dagNode.links) {
84-
if (link.name === nextFileName) {
85-
// found multihash/cid of requested named-file
86-
try {
87-
// assume a Buffer with a valid CID
88-
// (cid is allowed instead of multihash since https://github.com/ipld/js-ipld-dag-pb/pull/80)
89-
cidOfNextFile = new CID(link.cid)
90-
} catch (err) {
91-
// fallback to multihash
92-
cidOfNextFile = new CID(mh.toB58String(link.multihash))
93-
}
94-
break
95-
}
96-
}
97-
} catch (err) {
98-
return next(err)
99-
}
100-
101-
if (!cidOfNextFile) {
102-
const missingLinkErr = new Error(`no link named "${nextFileName}" under ${memo}`)
103-
missingLinkErr.parentDagNode = memo
104-
missingLinkErr.missingLinkName = nextFileName
105-
return next(missingLinkErr)
106-
}
107-
108-
next(null, cidOfNextFile)
109-
})
110-
}, (err, cid) => {
111-
if (err) {
112-
return callback(err)
113-
}
114-
115-
try {
116-
cid = new CID(cid)
117-
} catch (err) {
118-
return callback(err)
119-
}
49+
ipfs.files.stat(path, (err, stats) => {
50+
if (err) {
51+
return callback(err)
52+
}
12053

121-
if (cid.codec === 'raw') {
122-
// no need for additional lookup, its raw data
123-
callback(null, { cid })
124-
}
54+
const cid = new CID(stats.hash)
12555

126-
ipfs.dag.get(cid, (err, dagResult) => {
127-
if (err) {
128-
return callback(err)
129-
}
56+
if (stats.type.includes('directory')) {
57+
const err = new Error('This dag node is a directory')
58+
err.cid = cid
13059

131-
try {
132-
let dagDataObj = Unixfs.unmarshal(dagResult.value.data)
133-
// There are at least two types of directories:
134-
// - "directory"
135-
// - "hamt-sharded-directory" (example: QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX)
136-
if (dagDataObj.type === 'directory' || dagDataObj.type === 'hamt-sharded-directory') {
137-
let isDirErr = new Error('This dag node is a directory')
138-
// store memo of last multihash so it can be used by directory
139-
isDirErr.cid = isDirErr.fileName = cid
140-
isDirErr.dagDirType = dagDataObj.type
141-
return callback(isDirErr)
142-
}
143-
} catch (err) {
144-
return callback(err)
145-
}
60+
return callback(err)
61+
}
14662

147-
callback(null, { cid })
148-
})
63+
callback(err, {
64+
cid
14965
})
66+
})
15067
})
15168

15269
const multihash = promisify((ipfs, path, callback) => {

0 commit comments

Comments
 (0)
This repository has been archived.