-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: add gateway route to daemon #968
Changes from all commits
0913191
45cc11b
94cec9b
7cae803
b773cdc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
'use strict' | ||
|
||
const filesize = require('filesize') | ||
|
||
const mainStyle = require('./style') | ||
const pathUtil = require('../utils/path') | ||
|
||
function getParentDirectoryURL (originalParts) { | ||
const parts = originalParts.slice() | ||
|
||
if (parts.length > 1) { | ||
parts.pop() | ||
} | ||
|
||
return [ '', 'ipfs' ].concat(parts).join('/') | ||
} | ||
|
||
function buildFilesList (path, links) { | ||
const rows = links.map((link) => { | ||
let row = [ | ||
`<div class="ipfs-icon ipfs-_blank"> </div>`, | ||
`<a href="${pathUtil.joinURLParts(path, link.name)}">${link.name}</a>`, | ||
filesize(link.size) | ||
] | ||
|
||
row = row.map((cell) => `<td>${cell}</td>`).join('') | ||
|
||
return `<tr>${row}</tr>` | ||
}) | ||
|
||
return rows.join('') | ||
} | ||
|
||
function buildTable (path, links) { | ||
const parts = pathUtil.splitPath(path) | ||
const parentDirectoryURL = getParentDirectoryURL(parts) | ||
|
||
return ` | ||
<table class="table table-striped"> | ||
<tbody> | ||
<tr> | ||
<td class="narrow"> | ||
<div class="ipfs-icon ipfs-_blank"> </div> | ||
</td> | ||
<td class="padding"> | ||
<a href="${parentDirectoryURL}">..</a> | ||
</td> | ||
<td></td> | ||
</tr> | ||
${buildFilesList(path, links)} | ||
</tbody> | ||
</table> | ||
` | ||
} | ||
|
||
function render (path, links) { | ||
return ` | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>${path}</title> | ||
<style>${mainStyle}</style> | ||
</head> | ||
<body> | ||
<div id="header" class="row"> | ||
<div class="col-xs-2"> | ||
<div id="logo" class="ipfs-logo"></div> | ||
</div> | ||
</div> | ||
<br> | ||
<div class="col-xs-12"> | ||
<div class="panel panel-default"> | ||
<div class="panel-heading"> | ||
<strong>Index of ${path}</strong> | ||
</div> | ||
${buildTable(path, links)} | ||
</div> | ||
</div> | ||
</body> | ||
</html> | ||
` | ||
} | ||
|
||
exports = module.exports | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it seems like a bad start to do htm templating using string manipulation. can we use an actual templating engine please? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems to be only three "templates" here for the gateway, would be overkill to include a entire template engine for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels like a bad precedent, it starts with three templates, but always grows, so I would rather have something setup properly from the start There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @dignifiedquire, worst case scenario, if complexity doesn't grow and we don't need those templates, we can easily remove them and switch back to this style, which is better than having to rework a bunch of ad-hoc templates ;) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: http://handlebarsjs.com/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's planning for something we don't know, rather than going with a simple solution that works now and migrate to something more complex once we really have the need for it. Three templates (in my mind) does not justify including a template engine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be achieved as a separate PR |
||
exports.render = render |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
'use strict' | ||
|
||
const mh = require('multihashes') | ||
const promisify = require('promisify-es6') | ||
const reduce = require('async/reduce') | ||
const CID = require('cids') | ||
const Unixfs = require('ipfs-unixfs') | ||
const debug = require('debug') | ||
const log = debug('jsipfs:http-gateway:resolver') | ||
log.error = debug('jsipfs:http-gateway:resolver:error') | ||
|
||
const dirView = require('./dir-view') | ||
const pathUtil = require('./utils/path') | ||
|
||
function getIndexFiles (links) { | ||
const INDEX_HTML_FILES = [ | ||
'index.html', | ||
'index.htm', | ||
'index.shtml' | ||
] | ||
|
||
return links.filter((link) => INDEX_HTML_FILES.indexOf(link.name) !== -1) | ||
} | ||
|
||
const resolveDirectory = promisify((ipfs, path, multihash, callback) => { | ||
mh.validate(mh.fromB58String(multihash)) | ||
|
||
ipfs.object.get(multihash, { enc: 'base58' }, (err, dagNode) => { | ||
if (err) { return callback(err) } | ||
|
||
const indexFiles = getIndexFiles(dagNode.links) | ||
|
||
if (indexFiles.length > 0) { | ||
return callback(null, indexFiles) | ||
} | ||
|
||
return callback(null, dirView.render(path, dagNode.links)) | ||
}) | ||
}) | ||
|
||
const resolveMultihash = promisify((ipfs, path, callback) => { | ||
const parts = pathUtil.splitPath(path) | ||
let firstMultihash = parts.shift() | ||
let currentCid | ||
|
||
reduce(parts, firstMultihash, (memo, item, next) => { | ||
try { | ||
currentCid = new CID(mh.fromB58String(memo)) | ||
} catch (err) { | ||
return next(err) | ||
} | ||
|
||
log('memo: ', memo) | ||
log('item: ', item) | ||
|
||
ipfs.dag.get(currentCid, (err, result) => { | ||
if (err) { return next(err) } | ||
|
||
let dagNode = result.value | ||
// find multihash of requested named-file in current dagNode's links | ||
let multihashOfNextFile | ||
let nextFileName = item | ||
|
||
const links = dagNode.links | ||
|
||
for (let link of links) { | ||
if (link.name === nextFileName) { | ||
// found multihash of requested named-file | ||
multihashOfNextFile = mh.toB58String(link.multihash) | ||
log('found multihash: ', multihashOfNextFile) | ||
break | ||
} | ||
} | ||
|
||
if (!multihashOfNextFile) { | ||
return next(new Error(`no link named "${nextFileName}" under ${memo}`)) | ||
} | ||
|
||
next(null, multihashOfNextFile) | ||
}) | ||
}, (err, result) => { | ||
if (err) { return callback(err) } | ||
|
||
let cid | ||
try { | ||
cid = new CID(mh.fromB58String(result)) | ||
} catch (err) { | ||
return callback(err) | ||
} | ||
|
||
ipfs.dag.get(cid, (err, dagResult) => { | ||
if (err) return callback(err) | ||
|
||
let dagDataObj = Unixfs.unmarshal(dagResult.value.data) | ||
if (dagDataObj.type === 'directory') { | ||
let isDirErr = new Error('This dag node is a directory') | ||
// add memo (last multihash) as a fileName so it can be used by resolveDirectory | ||
isDirErr.fileName = result | ||
return callback(isDirErr) | ||
} | ||
|
||
callback(null, { multihash: result }) | ||
}) | ||
}) | ||
}) | ||
|
||
module.exports = { | ||
resolveDirectory: resolveDirectory, | ||
resolveMultihash: resolveMultihash | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes sense to call this
http
module nowdaemon
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@diasdavid Yeah it does, but in
go-ipfs
it'shttp
, so should we stick to the reference implementation ? I don't mind the rename thoughgo-ipfs
Edit: added link.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep http then :)