Binary Hashing (Android) (#401)

binary hashing android
This commit is contained in:
Geoffrey Goh
2016-06-24 19:40:32 -07:00
committed by GitHub
parent 660d6985d5
commit eb510663e5

View File

@@ -1,10 +1,10 @@
/*
* This script generates a hash of all the React Native bundled assets and writes it into
* into the APK. The hash in "updateCheck" requests to prevent downloading an identical
* into the APK. The hash in "updateCheck" requests to prevent downloading an identical
* update to the one already present in the binary.
*
* It first creates a snapshot of the contents in the resource directory by creating
* a map with the modified time of all the files in the directory. It then compares this
*
* It first creates a snapshot of the contents in the resource directory by creating
* a map with the modified time of all the files in the directory. It then compares this
* snapshot with the one saved earlier in "recordFilesBeforeBundleCommand.js" to figure
* out which files were generated by the "react-native bundle" command. It then computes
* the hash for each file to generate a manifest, and then computes a hash over the entire
@@ -49,44 +49,53 @@ var manifest = [];
if (bundleGeneratedAssetFiles.length) {
bundleGeneratedAssetFiles.forEach(function(assetFile) {
// Generate hash for each asset file
var readStream = fs.createReadStream(resourcesDir + assetFile);
var hashStream = crypto.createHash(HASH_ALGORITHM);
addFileToManifest(resourcesDir, assetFile, manifest, function() {
if (manifest.length === bundleGeneratedAssetFiles.length) {
// Generate hash for JS bundle
addFileToManifest(path.dirname(jsBundleFilePath), path.basename(jsBundleFilePath), manifest, function() {
// ...and the JS bundle "meta"
var jsBundleMetaFilePath = jsBundleFilePath + ".meta";
addFileToManifest(path.dirname(jsBundleMetaFilePath), path.basename(jsBundleMetaFilePath), manifest, function() {
manifest = manifest.sort();
var finalHash = crypto.createHash(HASH_ALGORITHM)
.update(JSON.stringify(manifest))
.digest("hex");
readStream.pipe(hashStream)
.on("error", function(error) {
throw error;
})
.on("finish", function() {
hashStream.end();
var buffer = hashStream.read();
var fileHash = buffer.toString("hex");
manifest.push(CODE_PUSH_FOLDER_PREFIX + assetFile.replace(/\\/g, "/") + ":" + fileHash);
if (manifest.length === bundleGeneratedAssetFiles.length) {
// Generate hash for JS bundle
readStream = fs.createReadStream(jsBundleFilePath);
hashStream = crypto.createHash(HASH_ALGORITHM);
readStream.pipe(hashStream)
.on("error", function(error) {
throw error;
})
.on("finish", function() {
hashStream.end();
var buffer = hashStream.read();
var fileHash = buffer.toString("hex");
manifest.push(CODE_PUSH_FOLDER_PREFIX + "/" + path.basename(jsBundleFilePath) + ":" + fileHash);
manifest = manifest.sort();
var finalHash = crypto.createHash(HASH_ALGORITHM)
.update(JSON.stringify(manifest))
.digest("hex");
var savedResourcesManifestPath = assetsDir + "/" + CODE_PUSH_HASH_FILE_NAME;
fs.writeFileSync(savedResourcesManifestPath, finalHash);
});
}
});
var savedResourcesManifestPath = assetsDir + "/" + CODE_PUSH_HASH_FILE_NAME;
fs.writeFileSync(savedResourcesManifestPath, finalHash);
});
});
}
});
});
}
function addFileToManifest(folder, assetFile, manifest, done) {
var fullFilePath = path.join(folder, assetFile);
if (!fileExists(fullFilePath)) {
done();
return;
}
var readStream = fs.createReadStream(path.join(folder, assetFile));
var hashStream = crypto.createHash(HASH_ALGORITHM);
readStream.pipe(hashStream)
.on("error", function(error) {
throw error;
})
.on("finish", function() {
hashStream.end();
var buffer = hashStream.read();
var fileHash = buffer.toString("hex");
manifest.push(path.join(CODE_PUSH_FOLDER_PREFIX, assetFile).replace(/\\/g, "/") + ":" + fileHash);
done();
});
}
function fileExists(file) {
try { return fs.statSync(file).isFile(); }
catch (e) { return false; }
}
fs.unlinkSync(TEMP_FILE_PATH);