Merge pull request #174 from strongloop/refactor-download

Refactor download
This commit is contained in:
Miroslav Bajtoš 2016-11-11 16:57:48 +01:00 committed by GitHub
commit cb87b9cf94
2 changed files with 77 additions and 55 deletions

View File

@ -204,16 +204,6 @@ exports.upload = function(provider, req, res, options, cb) {
});
};
function handleError(res, err) {
if (err.code === 'ENOENT') {
res.type('application/json');
res.status(404).send({error: err});
return;
}
res.type('application/json');
res.status(500).send({error: err});
}
/**
* Handle download from a container/file.
* @param {Object} provider The storage service provider
@ -233,57 +223,71 @@ exports.download = function(provider, req, res, container, file, cb) {
var range = null;
if (req) {
if (req.headers) {
range = req.headers.range || '';
if (!req) {
// TODO(rfeng/bajtos) We should let the caller now about the problem!
return;
}
if (req.headers) {
range = req.headers.range || '';
}
if (!range) {
return download(params);
}
provider.getFile(params.container, params.remote, function(err, stats) {
if (err) {
return cb(processError(err, params.remote));
}
if (range) {
provider.getFile(params.container, params.remote, function(err, stats) {
if (err) {
handleError(res, err);
} else {
var total = stats.size;
setupPartialDownload(params, stats, res);
download(params);
});
var parts = range.replace(/bytes=/, '').split('-');
var partialstart = parts[0];
var partialend = parts[1];
function download(params) {
var reader = provider.download(params);
params.start = parseInt(partialstart, 10);
params.end = partialend ? parseInt(partialend, 10) : total - 1;
res.type(fileName);
var chunksize = (params.end - params.start) + 1;
reader.pipe(res);
res.status(206);
res.set('Content-Range', 'bytes ' + params.start + '-' + params.end + '/' + total);
res.set('Accept-Ranges', 'bytes');
res.set('Content-Length', chunksize);
reader.on('error', function onReaderError(err) {
cb(processError(err, params.remote));
cb = function() {}; // avoid double-callback
});
var reader = provider.download(params);
res.type(fileName);
reader.pipe(res);
reader.on('error', function(err) {
handleError(res, err);
});
reader.on('end', function() {
cb();
});
}
});
} else {
var reader = provider.download(params);
res.type(fileName);
reader.pipe(res);
reader.on('error', function(err) {
handleError(res, err);
});
reader.on('end', function() {
cb();
});
}
reader.on('end', function onReaderEnd() {
cb();
cb = function() {}; // avoid double-callback
});
}
};
function setupPartialDownload(params, stats, res) {
var total = stats.size;
var parts = range.replace(/bytes=/, '').split('-');
var partialstart = parts[0];
var partialend = parts[1];
params.start = parseInt(partialstart, 10);
params.end = partialend ? parseInt(partialend, 10) : total - 1;
var chunksize = (params.end - params.start) + 1;
res.status(206);
res.set('Content-Range', 'bytes ' + params.start + '-' + params.end + '/' + total);
res.set('Accept-Ranges', 'bytes');
res.set('Content-Length', chunksize);
};
function processError(err, fileName) {
if (err.code === 'ENOENT') {
err.statusCode = err.status = 404;
// Hide the original message reported e.g. by FS provider, as it may
// contain sensitive information.
err.message = 'File not found: ' + fileName;
}
return err;
}

View File

@ -314,6 +314,24 @@ describe('storage service', function() {
});
});
it('should run a function after a download failed', function(done) {
var hookCalled = false;
var Container = app.models.Container;
Container.afterRemoteError('download', function(ctx, cb) {
hookCalled = true;
cb();
});
request('http://localhost:' + app.get('port'))
.get('/containers/album1/download/does-not-exist')
.expect(404, function(err, res) {
if (err) return done(err);
assert(hookCalled, 'afterRemoteEror hook was not called');
done();
});
});
it('should delete a file', function(done) {
request('http://localhost:' + app.get('port'))
.del('/containers/album1/files/test.jpg')