mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 07:17:18 +00:00
refactor(image-stream): get rid of read-chunk (#1243)
We also took the opportunity to make `utils.getArchiveMimeType()` asynchronous. Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This commit is contained in:
parent
d5ec71c5da
commit
4a3a123f42
@ -67,9 +67,7 @@ const errors = require('../shared/errors');
|
||||
* });
|
||||
*/
|
||||
exports.getFromFilePath = (file) => {
|
||||
return Bluebird.try(() => {
|
||||
const type = utils.getArchiveMimeType(file);
|
||||
|
||||
return utils.getArchiveMimeType(file).then((type) => {
|
||||
if (!_.has(handlers, type)) {
|
||||
throw errors.createUserError('Invalid image', `The ${type} format is not supported`);
|
||||
}
|
||||
|
@ -17,7 +17,8 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const readChunk = require('read-chunk');
|
||||
const Bluebird = require('bluebird');
|
||||
const fs = Bluebird.promisifyAll(require('fs'));
|
||||
const archiveType = require('archive-type');
|
||||
|
||||
/**
|
||||
@ -26,18 +27,34 @@ const archiveType = require('archive-type');
|
||||
* @public
|
||||
*
|
||||
* @param {String} file - file path
|
||||
* @returns {String} mime type
|
||||
* @fulfil {String} - mime type
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
* utils.getArchiveMimeType('path/to/raspberrypi.img.gz');
|
||||
* utils.getArchiveMimeType('path/to/raspberrypi.img.gz').then((mimeType) => {
|
||||
* console.log(mimeType);
|
||||
* });
|
||||
*/
|
||||
exports.getArchiveMimeType = (file) => {
|
||||
|
||||
// `archive-type` only needs the first 261 bytes
|
||||
// See https://github.com/kevva/archive-type
|
||||
const MAGIC_NUMBER_BUFFER_START = 0;
|
||||
const MAGIC_NUMBER_BUFFER_END = 261;
|
||||
const chunk = readChunk.sync(file, MAGIC_NUMBER_BUFFER_START, MAGIC_NUMBER_BUFFER_END);
|
||||
const ARCHIVE_TYPE_IDENTIFICATION_BYTES_LENGTH = 261;
|
||||
|
||||
return _.get(archiveType(chunk), [ 'mime' ], 'application/octet-stream');
|
||||
return Bluebird.using(fs.openAsync(file, 'r').disposer((fileDescriptor) => {
|
||||
return fs.closeAsync(fileDescriptor);
|
||||
}), (fileDescriptor) => {
|
||||
const BUFFER_START = 0;
|
||||
const chunk = new Buffer(ARCHIVE_TYPE_IDENTIFICATION_BYTES_LENGTH);
|
||||
|
||||
return fs.readAsync(
|
||||
fileDescriptor,
|
||||
chunk,
|
||||
BUFFER_START,
|
||||
ARCHIVE_TYPE_IDENTIFICATION_BYTES_LENGTH,
|
||||
null
|
||||
).then(() => {
|
||||
return _.get(archiveType(chunk), [ 'mime' ], 'application/octet-stream');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
5
npm-shrinkwrap.json
generated
5
npm-shrinkwrap.json
generated
@ -5521,11 +5521,6 @@
|
||||
"resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"read-chunk": {
|
||||
"version": "2.0.0",
|
||||
"from": "read-chunk@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.0.0.tgz"
|
||||
},
|
||||
"read-only-stream": {
|
||||
"version": "2.0.0",
|
||||
"from": "read-only-stream@>=2.0.0 <3.0.0",
|
||||
|
@ -90,7 +90,6 @@
|
||||
"node-ipc": "^8.9.2",
|
||||
"node-stream-zip": "^1.3.4",
|
||||
"path-is-inside": "^1.0.2",
|
||||
"read-chunk": "^2.0.0",
|
||||
"redux": "^3.5.2",
|
||||
"redux-localstorage": "^0.4.1",
|
||||
"resin-cli-form": "^1.4.1",
|
||||
|
@ -25,29 +25,44 @@ describe('ImageStream: Utils', function() {
|
||||
|
||||
describe('.getArchiveMimeType()', function() {
|
||||
|
||||
it('should return application/x-bzip2 for a bz2 archive', function() {
|
||||
it('should resolve application/x-bzip2 for a bz2 archive', function(done) {
|
||||
const file = path.join(DATA_PATH, 'bz2', 'raspberrypi.img.bz2');
|
||||
m.chai.expect(utils.getArchiveMimeType(file)).to.equal('application/x-bzip2');
|
||||
utils.getArchiveMimeType(file).then((type) => {
|
||||
m.chai.expect(type).to.equal('application/x-bzip2');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should return application/x-xz for a xz archive', function() {
|
||||
it('should resolve application/x-xz for a xz archive', function(done) {
|
||||
const file = path.join(DATA_PATH, 'xz', 'raspberrypi.img.xz');
|
||||
m.chai.expect(utils.getArchiveMimeType(file)).to.equal('application/x-xz');
|
||||
utils.getArchiveMimeType(file).then((type) => {
|
||||
m.chai.expect(type).to.equal('application/x-xz');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should return application/gzip for a gz archive', function() {
|
||||
it('should resolve application/gzip for a gz archive', function(done) {
|
||||
const file = path.join(DATA_PATH, 'gz', 'raspberrypi.img.gz');
|
||||
m.chai.expect(utils.getArchiveMimeType(file)).to.equal('application/gzip');
|
||||
utils.getArchiveMimeType(file).then((type) => {
|
||||
m.chai.expect(type).to.equal('application/gzip');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should return application/zip for a zip archive', function() {
|
||||
it('should resolve application/zip for a zip archive', function(done) {
|
||||
const file = path.join(DATA_PATH, 'zip', 'zip-directory-rpi-only.zip');
|
||||
m.chai.expect(utils.getArchiveMimeType(file)).to.equal('application/zip');
|
||||
utils.getArchiveMimeType(file).then((type) => {
|
||||
m.chai.expect(type).to.equal('application/zip');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should return application/octet-stream for an uncompress image', function() {
|
||||
it('should resolve application/octet-stream for an uncompress image', function(done) {
|
||||
const file = path.join(DATA_PATH, 'images', 'raspberrypi.img');
|
||||
m.chai.expect(utils.getArchiveMimeType(file)).to.equal('application/octet-stream');
|
||||
utils.getArchiveMimeType(file).then((type) => {
|
||||
m.chai.expect(type).to.equal('application/octet-stream');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user