From 7015586c96f36ef1873395740765ddc25b954616 Mon Sep 17 00:00:00 2001 From: Friedel Ziegelmayer Date: Fri, 16 Sep 2016 18:30:54 +0200 Subject: [PATCH] fix(files.get): fix the command --- src/cli/commands/files/get.js | 52 +++++++++++++++++++++--------- src/http-api/resources/files.js | 56 ++++++++++++++++----------------- 2 files changed, 64 insertions(+), 44 deletions(-) diff --git a/src/cli/commands/files/get.js b/src/cli/commands/files/get.js index b8d746c03f..c5e0aa9051 100644 --- a/src/cli/commands/files/get.js +++ b/src/cli/commands/files/get.js @@ -7,6 +7,8 @@ log.error = debug('cli:files:error') var fs = require('fs') const path = require('path') const pathExists = require('path-exists') +const pull = require('pull-stream') +const toPull = require('stream-to-pull-stream') function checkArgs (hash, outPath) { // format the output directory @@ -33,30 +35,38 @@ function ensureDir (dir, cb) { .catch(cb) } -function fileHandler (result, dir) { - return function onFile (file) { +function fileHandler (dir) { + return function onFile (file, cb) { + const lastSlash = file.path.lastIndexOf('/') // Check to see if the result is in a directory - if (file.path.lastIndexOf('/') === -1) { + if (lastSlash === -1) { const dirPath = path.join(dir, file.path) // Check to see if the result is a directory - if (file.dir === false) { + if (file.content) { file.content.pipe(fs.createWriteStream(dirPath)) + .once('error', cb) + .once('end', cb) } else { - ensureDir(dirPath, (err) => { - if (err) { - throw err - } - }) + ensureDir(dirPath, cb) } } else { - const filePath = file.path.substring(0, file.path.lastIndexOf('/') + 1) + const filePath = file.path.substring(0, lastSlash + 1) const dirPath = path.join(dir, filePath) + ensureDir(dirPath, (err) => { if (err) { - throw err + return cb(err) } - file.content.pipe(fs.createWriteStream(dirPath)) + if (file.content) { + const filename = file.path.substring(lastSlash) + const target = path.join(dirPath, filename) + + file.content.pipe(fs.createWriteStream(target)) + .once('error', cb) + .once('end', cb) + } + cb() }) } } @@ -76,17 +86,29 @@ module.exports = { }, handler (argv) { - const dir = checkArgs(argv.ipfsPath, argv.output) + const ipfsPath = argv['ipfs-path'] + const dir = checkArgs(ipfsPath, argv.output) utils.getIPFS((err, ipfs) => { if (err) { throw err } - ipfs.files.get(argv.ipfsPath, (err, result) => { + + ipfs.files.get(ipfsPath, (err, stream) => { if (err) { throw err } - result.on('data', fileHandler(result, dir)) + + pull( + toPull.source(stream), + pull.asyncMap(fileHandler(dir)), + pull.onEnd((err) => { + console.log('finished writing') + if (err) { + throw err + } + }) + ) }) }) } diff --git a/src/http-api/resources/files.js b/src/http-api/resources/files.js index 3c3cbd1e5e..ac52d19cc2 100644 --- a/src/http-api/resources/files.js +++ b/src/http-api/resources/files.js @@ -7,10 +7,10 @@ const tar = require('tar-stream') const log = debug('http-api:files') log.error = debug('http-api:files:error') const pull = require('pull-stream') -const toStream = require('pull-stream-to-stream') const toPull = require('stream-to-pull-stream') const pushable = require('pull-pushable') const EOL = require('os').EOL +const through = require('through2') exports = module.exports @@ -72,7 +72,7 @@ exports.get = { const ipfs = request.server.app.ipfs const pack = tar.pack() - ipfs.files.getPull(key, (err, stream) => { + ipfs.files.get(key, (err, stream) => { if (err) { log.error(err) @@ -83,35 +83,33 @@ exports.get = { return } - pull( - stream, - pull.asyncMap((file, cb) => { - const header = {name: file.path} - - if (!file.content) { - header.type = 'directory' - pack.entry(header) - cb() - } else { - header.size = file.size - toStream.source(file.content) - .pipe(pack.entry(header, cb)) - } - }), - pull.onEnd((err) => { - if (err) { - log.error(err) - - reply({ - Message: 'Failed to get file: ' + err, - Code: 0 - }).code(500) - return + stream.pipe(through.obj((file, enc, cb) => { + const header = {name: file.path} + + if (!file.content) { + header.type = 'directory' + pack.entry(header) + cb() + } else { + header.size = file.size + const packStream = pack.entry(header, cb) + if (!packStream) { + // this happens if the request is aborted + // we just skip things then + return cb() } + file.content.pipe(packStream) + } + }), () => { + if (err) { + log.error(err) + pack.emit('error', err) + pack.destroy() + return + } - pack.finalize() - }) - ) + pack.finalize() + }) // the reply must read the tar stream, // to pull values through