Deliver content-length and file not found errors for file downloads
This commit is contained in:
22
src/apps.js
22
src/apps.js
@@ -1136,10 +1136,28 @@ function downloadFile(appId, filePath, callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
var filename = path.basename(filePath);
|
||||
exec(appId, { cmd: ['cat', filePath ], tty: false }, function (error, stream) {
|
||||
exec(appId, { cmd: [ 'stat', '--printf=%F-%s', filePath ], tty: true }, function (error, stream) {
|
||||
if (error) return callback(error);
|
||||
|
||||
return callback(null, stream, filename);
|
||||
var data = '';
|
||||
stream.setEncoding('utf8');
|
||||
stream.on('data', function (d) { data += d; });
|
||||
stream.on('end', function () {
|
||||
var parts = data.split('-');
|
||||
if (parts.length !== 2) return callback(new AppsError(AppsError.NOT_FOUND, 'file does not exist'));
|
||||
|
||||
var type = parts[0];
|
||||
if (type !== 'regular file') return callback(new AppsError(AppsError.NOT_FOUND, 'only files can be downloaded'));
|
||||
|
||||
var size = parseInt(parts[1], 10);
|
||||
if (isNaN(size)) return callback(new AppsError(AppsError.NOT_FOUND, 'file does not exist'));
|
||||
|
||||
exec(appId, { cmd: [ 'cat', filePath ], tty: false }, function (error, stream) {
|
||||
if (error) return callback(error);
|
||||
|
||||
return callback(null, stream, { filename: filename, size: size });
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -557,14 +557,15 @@ function downloadFile(req, res, next) {
|
||||
|
||||
if (typeof req.query.file !== 'string' || !req.query.file) return next(new HttpError(400, 'file query argument must be provided'));
|
||||
|
||||
apps.downloadFile(req.params.id, req.query.file, function (error, result, filename) {
|
||||
apps.downloadFile(req.params.id, req.query.file, function (error, result, info) {
|
||||
if (error && error.reason === AppsError.NOT_FOUND) return next(new HttpError(404, error.message));
|
||||
if (error) return next(new HttpError(500, error));
|
||||
|
||||
// TODO get real content type and size
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'Content-Disposition': 'attachment; filename="' + filename + '"'
|
||||
// 'Content-Length': stat.size
|
||||
'Content-Disposition': 'attachment; filename="' + info.filename + '"',
|
||||
'Content-Length': info.size
|
||||
});
|
||||
|
||||
result.pipe(res);
|
||||
|
||||
Reference in New Issue
Block a user