2013-06-26 21:43:53 +00:00
|
|
|
var IncomingForm = require('formidable');
|
|
|
|
var StringDecoder = require('string_decoder').StringDecoder;
|
|
|
|
|
2013-07-01 17:54:53 +00:00
|
|
|
/**
|
2013-07-02 15:57: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
|
2015-01-29 14:32:51 +00:00
|
|
|
* @param {Object} [options] The container name
|
2014-04-07 23:17:19 +00:00
|
|
|
* @callback {Function} cb Callback function
|
2015-01-29 14:32:51 +00:00
|
|
|
* @header storageService.upload(provider, req, res, options, cb)
|
2013-07-01 17:54:53 +00:00
|
|
|
*/
|
2015-01-29 14:32:51 +00:00
|
|
|
exports.upload = function (provider, req, res, options, cb) {
|
|
|
|
if (!cb && 'function' === typeof options) {
|
|
|
|
cb = options;
|
|
|
|
options = {};
|
|
|
|
}
|
|
|
|
|
2014-01-24 17:44:58 +00:00
|
|
|
var form = new IncomingForm(this.options);
|
2015-01-29 14:32:51 +00:00
|
|
|
container = options.container || req.params.container;
|
2014-01-24 17:44:58 +00:00
|
|
|
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;
|
2013-06-26 21:43:53 +00:00
|
|
|
}
|
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;
|
|
|
|
}
|
2013-06-26 21:43:53 +00:00
|
|
|
|
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
|
|
|
|
2015-01-29 14:32:51 +00:00
|
|
|
if ('function' === typeof options.getFilename) {
|
|
|
|
file.name = options.getFilename(file, req, res);
|
|
|
|
}
|
|
|
|
|
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'];
|
|
|
|
}
|
2015-01-29 14:32:51 +00:00
|
|
|
|
|
|
|
var writer = provider.upload({container: container, remote: file.name});
|
2014-01-24 17:44:58 +00:00
|
|
|
|
|
|
|
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();
|
2013-06-26 21:43:53 +00:00
|
|
|
};
|
|
|
|
|
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();
|
2013-06-26 21:43:53 +00:00
|
|
|
});
|
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});
|
|
|
|
});
|
2013-06-26 21:43:53 +00:00
|
|
|
}
|
|
|
|
|
2013-07-02 15:57:53 +00:00
|
|
|
/**
|
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)
|
2013-07-02 15:57:53 +00:00
|
|
|
*/
|
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
|
|
|
|
});
|
2014-12-25 05:21:20 +00:00
|
|
|
|
2014-01-30 06:39:01 +00:00
|
|
|
res.type(file);
|
2014-01-24 17:44:58 +00:00
|
|
|
reader.pipe(res);
|
|
|
|
reader.on('error', function (err) {
|
2014-12-25 05:21:20 +00:00
|
|
|
if (err.code === 'ENOENT') {
|
|
|
|
res.type('application/json');
|
|
|
|
res.send(404, { error: err });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-01-30 06:39:01 +00:00
|
|
|
res.type('application/json');
|
2014-01-24 17:44:58 +00:00
|
|
|
res.send(500, { error: err });
|
|
|
|
});
|
2013-06-26 21:43:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|