loopback-component-storage/lib/storage-handler.js

139 lines
3.6 KiB
JavaScript
Raw Normal View History

var IncomingForm = require('formidable');
var StringDecoder = require('string_decoder').StringDecoder;
2013-07-01 17:54:53 +00:00
/**
* Handle multipart/form-data upload to the storage service
2014-04-07 23:17:19 +00:00
* @param {Object} provider The storage service provider
2014-01-10 19:34:37 +00:00
* @param {Request} req The HTTP request
* @param {Response} res The HTTP response
* @param {String} container The container name
2014-04-07 23:17:19 +00:00
* @callback {Function} cb Callback function
* @header storageService.upload(provider, req, res, container, cb)
2013-07-01 17:54:53 +00:00
*/
2014-01-10 19:34:37 +00:00
exports.upload = function (provider, req, res, container, cb) {
2014-01-24 17:44:58 +00:00
var form = new IncomingForm(this.options);
container = container || req.params.container;
var fields = {}, files = {};
form.handlePart = function (part) {
var self = this;
if (part.filename === undefined) {
var value = ''
, decoder = new StringDecoder(this.encoding);
part.on('data', function (buffer) {
self._fieldsSize += buffer.length;
if (self._fieldsSize > self.maxFieldsSize) {
self._error(new Error('maxFieldsSize exceeded, received ' + self._fieldsSize + ' bytes of field data'));
return;
}
2014-01-24 17:44:58 +00:00
value += decoder.write(buffer);
});
part.on('end', function () {
var values = fields[part.name];
if (values === undefined) {
values = [value];
fields[part.name] = values;
} else {
values.push(value);
}
self.emit('field', part.name, value);
});
return;
}
2014-01-24 17:44:58 +00:00
this._flushing++;
2013-06-27 15:31:03 +00:00
2014-01-24 17:44:58 +00:00
var file = {
container: container,
name: part.filename,
type: part.mime
};
2013-06-27 15:31:03 +00:00
2014-01-24 17:44:58 +00:00
self.emit('fileBegin', part.name, file);
var headers = {};
if ('content-type' in part.headers) {
headers['content-type'] = part.headers['content-type'];
}
var writer = provider.upload({container: container, remote: part.filename});
var endFunc = function () {
self._flushing--;
var values = files[part.name];
if (values === undefined) {
values = [file];
files[part.name] = values;
} else {
values.push(file);
}
self.emit('file', part.name, file);
self._maybeEnd();
};
2014-01-24 17:44:58 +00:00
/*
part.on('data', function (buffer) {
self.pause();
writer.write(buffer, function () {
// pkgcloud stream doesn't make callbacks
});
self.resume();
});
part.on('end', function () {
writer.end(); // pkgcloud stream doesn't make callbacks
endFunc();
});
*/
part.pipe(writer, { end: false });
part.on("end", function () {
writer.end();
endFunc();
});
2014-01-24 17:44:58 +00:00
};
form.parse(req, function (err, _fields, _files) {
if (err) {
console.error(err);
}
cb && cb(err, {files: files, fields: fields});
});
}
/**
2014-04-07 23:17:19 +00:00
* Handle download from a container/file.
* @param {Object} provider The storage service provider
2014-01-10 19:34:37 +00:00
* @param {Request} req The HTTP request
* @param {Response} res The HTTP response
* @param {String} container The container name
* @param {String} file The file name
2014-04-07 23:17:19 +00:00
* @callback {Function} cb Callback function.
* @header storageService.download(provider, req, res, container, file, cb)
*/
2014-01-24 17:44:58 +00:00
exports.download = function (provider, req, res, container, file, cb) {
var reader = provider.download({
container: container || req && req.params.container,
remote: file || req && req.params.file
});
res.type(file);
2014-01-24 17:44:58 +00:00
reader.pipe(res);
reader.on('error', function (err) {
if (err.code === 'ENOENT') {
res.type('application/json');
res.send(404, { error: err });
return;
}
res.type('application/json');
2014-01-24 17:44:58 +00:00
res.send(500, { error: err });
});
}