Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

.add/files.add http-api endpoint #323

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/core/ipfs/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ module.exports = function files (self) {
}),

get: promisify((hash, callback) => {
const exportFile = Exporter(hash, self._dagS)
callback(null, exportFile)
const exportStream = Exporter(hash, self._dagS)
callback(null, exportStream)
})
}
}
1 change: 0 additions & 1 deletion src/core/ipfs/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ module.exports = function object (self) {
if (err) {
return cb(err)
}

cb(null, node.data)
})
}),
Expand Down
124 changes: 123 additions & 1 deletion src/http-api/resources/files.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
'use strict'

const bs58 = require('bs58')
const ndjson = require('ndjson')
const multipart = require('ipfs-multipart')
const debug = require('debug')
const tar = require('tar-stream')
const log = debug('http-api:files')
log.error = debug('http-api:files:error')
const async = require('async')

exports = module.exports

Expand Down Expand Up @@ -42,8 +46,126 @@ exports.cat = {
Code: 0
}).code(500)
}
return reply(stream).header('X-Stream-Output', '1')
})
}
}

exports.get = {
// uses common parseKey method that returns a `key`
parseArgs: exports.parseKey,

// main route handler which is called after the above `parseArgs`, but only if the args were valid
handler: (request, reply) => {
const key = request.pre.args.key

request.server.app.ipfs.files.get(key, (err, stream) => {
if (err) {
log.error(err)
return reply({
Message: 'Failed to get file: ' + err,
Code: 0
}).code(500)
}
var pack = tar.pack()
const files = []
stream.on('data', (data) => {
return reply(data)
files.push(data)
})
const processFile = (file) => {
return (callback) => {
if (!file.content) { // is directory
pack.entry({name: file.path, type: 'directory'})
callback()
} else { // is file
const fileContents = []
file.content.on('data', (data) => {
fileContents.push(data)
})
file.content.on('end', () => {
pack.entry({name: file.path}, Buffer.concat(fileContents))
callback()
})
}
}
}
stream.on('end', () => {
const callbacks = files.map(processFile)
async.series(callbacks, () => {
pack.finalize()
reply(pack).header('X-Stream-Output', '1')
})
})
})
}
}

exports.add = {
handler: (request, reply) => {
if (!request.payload) {
return reply('Array, Buffer, or String is required.').code(400).takeover()
}

const parser = multipart.reqParser(request.payload)

var filesParsed = false
var filesAdded = 0

var serialize = ndjson.serialize()
// hapi doesn't permit object streams: http://hapijs.com/api#replyerr-result
serialize._readableState.objectMode = false

request.server.app.ipfs.files.createAddStream((err, fileAdder) => {
if (err) {
return reply({
Message: err,
Code: 0
}).code(500)
}

fileAdder.on('data', (file) => {
const filePath = file.path ? file.path : file.hash
serialize.write({
Name: filePath,
Hash: file.hash
})
filesAdded++
})

fileAdder.on('end', () => {
if (filesAdded === 0 && filesParsed) {
return reply({
Message: 'Failed to add files.',
Code: 0
}).code(500)
} else {
serialize.end()
return reply(serialize)
.header('x-chunked-output', '1')
.header('content-type', 'application/json')
}
})

parser.on('file', (fileName, fileStream) => {
var filePair = {
path: fileName,
content: fileStream
}
filesParsed = true
fileAdder.write(filePair)
})
parser.on('directory', (directory) => {
fileAdder.write({
path: directory,
content: ''
})
})

parser.on('end', () => {
if (!filesParsed) {
return reply("File argument 'data' is required.").code(400).takeover()
}
fileAdder.end()
})
})
}
Expand Down
26 changes: 26 additions & 0 deletions src/http-api/routes/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = (server) => {
const api = server.select('API')

api.route({
// TODO fix method
method: '*',
path: '/api/v0/cat',
config: {
Expand All @@ -15,4 +16,29 @@ module.exports = (server) => {
handler: resources.files.cat.handler
}
})

api.route({
// TODO fix method
method: '*',
path: '/api/v0/get',
config: {
pre: [
{ method: resources.files.get.parseArgs, assign: 'args' }
],
handler: resources.files.get.handler
}
})

api.route({
// TODO fix method
method: '*',
path: '/api/v0/add',
config: {
payload: {
parse: false,
output: 'stream'
},
handler: resources.files.add.handler
}
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

'use strict'

/*
const test = require('interface-ipfs-core')
const FactoryClient = require('./../../utils/factory-http')

Expand All @@ -17,8 +16,5 @@ const common = {
fc.dismantle(callback)
}
}
*/

// TODO
// needs: https://github.com/ipfs/js-ipfs/pull/323
// test.files(common)
test.files(common)