glacier.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. var AWS = require('../core');
  2. AWS.util.update(AWS.Glacier.prototype, {
  3. /**
  4. * @api private
  5. */
  6. setupRequestListeners: function setupRequestListeners(request) {
  7. if (Array.isArray(request._events.validate)) {
  8. request._events.validate.unshift(this.validateAccountId);
  9. } else {
  10. request.on('validate', this.validateAccountId);
  11. }
  12. request.removeListener('afterBuild',
  13. AWS.EventListeners.Core.COMPUTE_SHA256);
  14. request.on('build', this.addGlacierApiVersion);
  15. request.on('build', this.addTreeHashHeaders);
  16. },
  17. /**
  18. * @api private
  19. */
  20. validateAccountId: function validateAccountId(request) {
  21. if (request.params.accountId !== undefined) return;
  22. request.params = AWS.util.copy(request.params);
  23. request.params.accountId = '-';
  24. },
  25. /**
  26. * @api private
  27. */
  28. addGlacierApiVersion: function addGlacierApiVersion(request) {
  29. var version = request.service.api.apiVersion;
  30. request.httpRequest.headers['x-amz-glacier-version'] = version;
  31. },
  32. /**
  33. * @api private
  34. */
  35. addTreeHashHeaders: function addTreeHashHeaders(request) {
  36. if (request.params.body === undefined) return;
  37. var hashes = request.service.computeChecksums(request.params.body);
  38. request.httpRequest.headers['X-Amz-Content-Sha256'] = hashes.linearHash;
  39. if (!request.httpRequest.headers['x-amz-sha256-tree-hash']) {
  40. request.httpRequest.headers['x-amz-sha256-tree-hash'] = hashes.treeHash;
  41. }
  42. },
  43. /**
  44. * @!group Computing Checksums
  45. */
  46. /**
  47. * Computes the SHA-256 linear and tree hash checksums for a given
  48. * block of Buffer data. Pass the tree hash of the computed checksums
  49. * as the checksum input to the {completeMultipartUpload} when performing
  50. * a multi-part upload.
  51. *
  52. * @example Calculate checksum of 5.5MB data chunk
  53. * var glacier = new AWS.Glacier();
  54. * var data = Buffer.alloc(5.5 * 1024 * 1024);
  55. * data.fill('0'); // fill with zeros
  56. * var results = glacier.computeChecksums(data);
  57. * // Result: { linearHash: '68aff0c5a9...', treeHash: '154e26c78f...' }
  58. * @param data [Buffer, String] data to calculate the checksum for
  59. * @return [map<linearHash:String,treeHash:String>] a map containing
  60. * the linearHash and treeHash properties representing hex based digests
  61. * of the respective checksums.
  62. * @see completeMultipartUpload
  63. */
  64. computeChecksums: function computeChecksums(data) {
  65. if (!AWS.util.Buffer.isBuffer(data)) data = AWS.util.buffer.toBuffer(data);
  66. var mb = 1024 * 1024;
  67. var hashes = [];
  68. var hash = AWS.util.crypto.createHash('sha256');
  69. // build leaf nodes in 1mb chunks
  70. for (var i = 0; i < data.length; i += mb) {
  71. var chunk = data.slice(i, Math.min(i + mb, data.length));
  72. hash.update(chunk);
  73. hashes.push(AWS.util.crypto.sha256(chunk));
  74. }
  75. return {
  76. linearHash: hash.digest('hex'),
  77. treeHash: this.buildHashTree(hashes)
  78. };
  79. },
  80. /**
  81. * @api private
  82. */
  83. buildHashTree: function buildHashTree(hashes) {
  84. // merge leaf nodes
  85. while (hashes.length > 1) {
  86. var tmpHashes = [];
  87. for (var i = 0; i < hashes.length; i += 2) {
  88. if (hashes[i + 1]) {
  89. var tmpHash = AWS.util.buffer.alloc(64);
  90. tmpHash.write(hashes[i], 0, 32, 'binary');
  91. tmpHash.write(hashes[i + 1], 32, 32, 'binary');
  92. tmpHashes.push(AWS.util.crypto.sha256(tmpHash));
  93. } else {
  94. tmpHashes.push(hashes[i]);
  95. }
  96. }
  97. hashes = tmpHashes;
  98. }
  99. return AWS.util.crypto.toHex(hashes[0]);
  100. }
  101. });