UNPKG

ks3-js-sdk

Version:

js sdk for ks3

59 lines (48 loc) 386 kB
/* * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["KS3"] = factory(); else root["KS3"] = factory(); })(self, () => { return /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./index.js": /*!******************!*\ !*** ./index.js ***! \******************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { eval("var core = __webpack_require__(/*! ./src/core.js */ \"./src/core.js\");\nvar advance = __webpack_require__(/*! ./src/advance.js */ \"./src/advance.js\");\nvar request = __webpack_require__(/*! ./src/request */ \"./src/request.js\");\nvar utils = __webpack_require__(/*! ./src/utils */ \"./src/utils.js\");\nvar event = __webpack_require__(/*! ./src/event */ \"./src/event.js\");\nvar task = __webpack_require__(/*! ./src/task */ \"./src/task.js\");\n/**\n * 需要提炼成KS3实例可访问的全局变量 todo\n */\nvar defaultConfig = {\n AK: '',\n SK: '',\n protocol: '',\n //是否为内网\n region: '',\n bucket: '',\n forcePathStyle: false,\n //是否使用二级域名\n domain: false,\n //是否使用自定义域名\n chunkSize: 5 * 1024 * 1024,\n // 分块上传的最小单位 每个分块要求为5MB≤PartSize<500MB之间\n retryTimes: 2,\n // 分块上传重试次数\n parallelLimit: 10,\n // 分块上传并发个数\n fileParallelLimit: 3,\n // 同一个实例下上传的文件并发数\n progressInterval: 1000,\n // 回调时间间隔\n timeout: 0,\n // 超时时长 默认不限制超时时长 单位:毫秒\n securityToken: '' //从STS服务获取的临时身份凭证(SecurityToken)\n};\nvar KS3 = function (config) {\n this.config = Object.assign({}, defaultConfig, config);\n utils.each(core.methods, function (fn, apiName) {\n KS3.prototype[apiName] = core.methods[apiName];\n });\n event.init(this);\n task.init(this);\n};\nadvance.init(KS3, task);\nKS3.request = request;\nKS3.utils = utils;\nmodule.exports = KS3;\n\n//# sourceURL=webpack://KS3/./index.js?"); /***/ }), /***/ "./lib/md5.js": /*!********************!*\ !*** ./lib/md5.js ***! \********************/ /***/ ((module, exports, __webpack_require__) => { eval("var __WEBPACK_AMD_DEFINE_RESULT__;/* https://github.com/emn178/js-md5 */\n(function () {\n 'use strict';\n\n var WINDOW = typeof window === 'object';\n var root = WINDOW ? window : {};\n if (root.JS_MD5_NO_WINDOW) {\n WINDOW = false;\n }\n var WEB_WORKER = !WINDOW && typeof self === 'object';\n if (WEB_WORKER) {\n root = self;\n }\n var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && \"object\" === 'object' && module.exports;\n var AMD = true && __webpack_require__.amdO;\n var ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';\n var HEX_CHARS = '0123456789abcdef'.split('');\n var EXTRA = [128, 32768, 8388608, -2147483648];\n var SHIFT = [0, 8, 16, 24];\n var OUTPUT_TYPES = ['hex', 'array', 'digest', 'buffer', 'arrayBuffer', 'base64'];\n var BASE64_ENCODE_CHAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');\n var blocks = [],\n buffer8;\n if (ARRAY_BUFFER) {\n var buffer = new ArrayBuffer(68);\n buffer8 = new Uint8Array(buffer);\n blocks = new Uint32Array(buffer);\n }\n if (root.JS_MD5_NO_NODE_JS || !Array.isArray) {\n Array.isArray = function (obj) {\n return Object.prototype.toString.call(obj) === '[object Array]';\n };\n }\n if (ARRAY_BUFFER && (root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {\n ArrayBuffer.isView = function (obj) {\n return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;\n };\n }\n\n /**\n * @method hex\n * @memberof md5\n * @description Output hash as hex string\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {String} Hex string\n * @example\n * md5.hex('The quick brown fox jumps over the lazy dog');\n * // equal to\n * md5('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method digest\n * @memberof md5\n * @description Output hash as bytes array\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Array} Bytes array\n * @example\n * md5.digest('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method array\n * @memberof md5\n * @description Output hash as bytes array\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Array} Bytes array\n * @example\n * md5.array('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method arrayBuffer\n * @memberof md5\n * @description Output hash as ArrayBuffer\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {ArrayBuffer} ArrayBuffer\n * @example\n * md5.arrayBuffer('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method buffer\n * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.\n * @memberof md5\n * @description Output hash as ArrayBuffer\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {ArrayBuffer} ArrayBuffer\n * @example\n * md5.buffer('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method base64\n * @memberof md5\n * @description Output hash as base64 string\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {String} base64 string\n * @example\n * md5.base64('The quick brown fox jumps over the lazy dog');\n */\n var createOutputMethod = function (outputType) {\n return function (message, isBinStr) {\n return new Md5(true).update(message, isBinStr)[outputType]();\n };\n };\n\n /**\n * @method create\n * @memberof md5\n * @description Create Md5 object\n * @returns {Md5} Md5 object.\n * @example\n * var hash = md5.create();\n */\n /**\n * @method update\n * @memberof md5\n * @description Create and update Md5 object\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Md5} Md5 object.\n * @example\n * var hash = md5.update('The quick brown fox jumps over the lazy dog');\n * // equal to\n * var hash = md5.create();\n * hash.update('The quick brown fox jumps over the lazy dog');\n */\n var createMethod = function () {\n var method = createOutputMethod('hex');\n method.getCtx = method.create = function () {\n return new Md5();\n };\n method.update = function (message) {\n return method.create().update(message);\n };\n for (var i = 0; i < OUTPUT_TYPES.length; ++i) {\n var type = OUTPUT_TYPES[i];\n method[type] = createOutputMethod(type);\n }\n return method;\n };\n\n /**\n * Md5 class\n * @class Md5\n * @description This is internal class.\n * @see {@link md5.create}\n */\n function Md5(sharedMemory) {\n if (sharedMemory) {\n blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n this.blocks = blocks;\n this.buffer8 = buffer8;\n } else {\n if (ARRAY_BUFFER) {\n var buffer = new ArrayBuffer(68);\n this.buffer8 = new Uint8Array(buffer);\n this.blocks = new Uint32Array(buffer);\n } else {\n this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n }\n }\n this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0;\n this.finalized = this.hashed = false;\n this.first = true;\n }\n\n /**\n * @method update\n * @memberof Md5\n * @instance\n * @description Update hash\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Md5} Md5 object.\n * @see {@link md5.update}\n */\n Md5.prototype.update = function (message, isBinStr) {\n if (this.finalized) {\n return;\n }\n var code,\n index = 0,\n i,\n length = message.length,\n blocks = this.blocks;\n var buffer8 = this.buffer8;\n while (index < length) {\n if (this.hashed) {\n this.hashed = false;\n blocks[0] = blocks[16];\n blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n }\n if (ARRAY_BUFFER) {\n for (i = this.start; index < length && i < 64; ++index) {\n code = message.charCodeAt(index);\n if (isBinStr || code < 0x80) {\n buffer8[i++] = code;\n } else if (code < 0x800) {\n buffer8[i++] = 0xc0 | code >> 6;\n buffer8[i++] = 0x80 | code & 0x3f;\n } else if (code < 0xd800 || code >= 0xe000) {\n buffer8[i++] = 0xe0 | code >> 12;\n buffer8[i++] = 0x80 | code >> 6 & 0x3f;\n buffer8[i++] = 0x80 | code & 0x3f;\n } else {\n code = 0x10000 + ((code & 0x3ff) << 10 | message.charCodeAt(++index) & 0x3ff);\n buffer8[i++] = 0xf0 | code >> 18;\n buffer8[i++] = 0x80 | code >> 12 & 0x3f;\n buffer8[i++] = 0x80 | code >> 6 & 0x3f;\n buffer8[i++] = 0x80 | code & 0x3f;\n }\n }\n } else {\n for (i = this.start; index < length && i < 64; ++index) {\n code = message.charCodeAt(index);\n if (isBinStr || code < 0x80) {\n blocks[i >> 2] |= code << SHIFT[i++ & 3];\n } else if (code < 0x800) {\n blocks[i >> 2] |= (0xc0 | code >> 6) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];\n } else if (code < 0xd800 || code >= 0xe000) {\n blocks[i >> 2] |= (0xe0 | code >> 12) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | code >> 6 & 0x3f) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];\n } else {\n code = 0x10000 + ((code & 0x3ff) << 10 | message.charCodeAt(++index) & 0x3ff);\n blocks[i >> 2] |= (0xf0 | code >> 18) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | code >> 12 & 0x3f) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | code >> 6 & 0x3f) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];\n }\n }\n }\n this.lastByteIndex = i;\n this.bytes += i - this.start;\n if (i >= 64) {\n this.start = i - 64;\n this.hash();\n this.hashed = true;\n } else {\n this.start = i;\n }\n }\n if (this.bytes > 4294967295) {\n this.hBytes += this.bytes / 4294967296 << 0;\n this.bytes = this.bytes % 4294967296;\n }\n return this;\n };\n Md5.prototype.finalize = function () {\n if (this.finalized) {\n return;\n }\n this.finalized = true;\n var blocks = this.blocks,\n i = this.lastByteIndex;\n blocks[i >> 2] |= EXTRA[i & 3];\n if (i >= 56) {\n if (!this.hashed) {\n this.hash();\n }\n blocks[0] = blocks[16];\n blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n }\n blocks[14] = this.bytes << 3;\n blocks[15] = this.hBytes << 3 | this.bytes >>> 29;\n this.hash();\n };\n Md5.prototype.hash = function () {\n var a,\n b,\n c,\n d,\n bc,\n da,\n blocks = this.blocks;\n if (this.first) {\n a = blocks[0] - 680876937;\n a = (a << 7 | a >>> 25) - 271733879 << 0;\n d = (-1732584194 ^ a & 2004318071) + blocks[1] - 117830708;\n d = (d << 12 | d >>> 20) + a << 0;\n c = (-271733879 ^ d & (a ^ -271733879)) + blocks[2] - 1126478375;\n c = (c << 17 | c >>> 15) + d << 0;\n b = (a ^ c & (d ^ a)) + blocks[3] - 1316259209;\n b = (b << 22 | b >>> 10) + c << 0;\n } else {\n a = this.h0;\n b = this.h1;\n c = this.h2;\n d = this.h3;\n a += (d ^ b & (c ^ d)) + blocks[0] - 680876936;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ a & (b ^ c)) + blocks[1] - 389564586;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ d & (a ^ b)) + blocks[2] + 606105819;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ c & (d ^ a)) + blocks[3] - 1044525330;\n b = (b << 22 | b >>> 10) + c << 0;\n }\n a += (d ^ b & (c ^ d)) + blocks[4] - 176418897;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ a & (b ^ c)) + blocks[5] + 1200080426;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ d & (a ^ b)) + blocks[6] - 1473231341;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ c & (d ^ a)) + blocks[7] - 45705983;\n b = (b << 22 | b >>> 10) + c << 0;\n a += (d ^ b & (c ^ d)) + blocks[8] + 1770035416;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ a & (b ^ c)) + blocks[9] - 1958414417;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ d & (a ^ b)) + blocks[10] - 42063;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ c & (d ^ a)) + blocks[11] - 1990404162;\n b = (b << 22 | b >>> 10) + c << 0;\n a += (d ^ b & (c ^ d)) + blocks[12] + 1804603682;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ a & (b ^ c)) + blocks[13] - 40341101;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ d & (a ^ b)) + blocks[14] - 1502002290;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ c & (d ^ a)) + blocks[15] + 1236535329;\n b = (b << 22 | b >>> 10) + c << 0;\n a += (c ^ d & (b ^ c)) + blocks[1] - 165796510;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ c & (a ^ b)) + blocks[6] - 1069501632;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ b & (d ^ a)) + blocks[11] + 643717713;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ a & (c ^ d)) + blocks[0] - 373897302;\n b = (b << 20 | b >>> 12) + c << 0;\n a += (c ^ d & (b ^ c)) + blocks[5] - 701558691;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ c & (a ^ b)) + blocks[10] + 38016083;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ b & (d ^ a)) + blocks[15] - 660478335;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ a & (c ^ d)) + blocks[4] - 405537848;\n b = (b << 20 | b >>> 12) + c << 0;\n a += (c ^ d & (b ^ c)) + blocks[9] + 568446438;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ c & (a ^ b)) + blocks[14] - 1019803690;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ b & (d ^ a)) + blocks[3] - 187363961;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ a & (c ^ d)) + blocks[8] + 1163531501;\n b = (b << 20 | b >>> 12) + c << 0;\n a += (c ^ d & (b ^ c)) + blocks[13] - 1444681467;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ c & (a ^ b)) + blocks[2] - 51403784;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ b & (d ^ a)) + blocks[7] + 1735328473;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ a & (c ^ d)) + blocks[12] - 1926607734;\n b = (b << 20 | b >>> 12) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[5] - 378558;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[8] - 2022574463;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[11] + 1839030562;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[14] - 35309556;\n b = (b << 23 | b >>> 9) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[1] - 1530992060;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[4] + 1272893353;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[7] - 155497632;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[10] - 1094730640;\n b = (b << 23 | b >>> 9) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[13] + 681279174;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[0] - 358537222;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[3] - 722521979;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[6] + 76029189;\n b = (b << 23 | b >>> 9) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[9] - 640364487;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[12] - 421815835;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[15] + 530742520;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[2] - 995338651;\n b = (b << 23 | b >>> 9) + c << 0;\n a += (c ^ (b | ~d)) + blocks[0] - 198630844;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[7] + 1126891415;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[14] - 1416354905;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[5] - 57434055;\n b = (b << 21 | b >>> 11) + c << 0;\n a += (c ^ (b | ~d)) + blocks[12] + 1700485571;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[3] - 1894986606;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[10] - 1051523;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[1] - 2054922799;\n b = (b << 21 | b >>> 11) + c << 0;\n a += (c ^ (b | ~d)) + blocks[8] + 1873313359;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[15] - 30611744;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[6] - 1560198380;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[13] + 1309151649;\n b = (b << 21 | b >>> 11) + c << 0;\n a += (c ^ (b | ~d)) + blocks[4] - 145523070;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[11] - 1120210379;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[2] + 718787259;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[9] - 343485551;\n b = (b << 21 | b >>> 11) + c << 0;\n if (this.first) {\n this.h0 = a + 1732584193 << 0;\n this.h1 = b - 271733879 << 0;\n this.h2 = c - 1732584194 << 0;\n this.h3 = d + 271733878 << 0;\n this.first = false;\n } else {\n this.h0 = this.h0 + a << 0;\n this.h1 = this.h1 + b << 0;\n this.h2 = this.h2 + c << 0;\n this.h3 = this.h3 + d << 0;\n }\n };\n\n /**\n * @method hex\n * @memberof Md5\n * @instance\n * @description Output hash as hex string\n * @returns {String} Hex string\n * @see {@link md5.hex}\n * @example\n * hash.hex();\n */\n Md5.prototype.hex = function () {\n this.finalize();\n var h0 = this.h0,\n h1 = this.h1,\n h2 = this.h2,\n h3 = this.h3;\n return HEX_CHARS[h0 >> 4 & 0x0F] + HEX_CHARS[h0 & 0x0F] + HEX_CHARS[h0 >> 12 & 0x0F] + HEX_CHARS[h0 >> 8 & 0x0F] + HEX_CHARS[h0 >> 20 & 0x0F] + HEX_CHARS[h0 >> 16 & 0x0F] + HEX_CHARS[h0 >> 28 & 0x0F] + HEX_CHARS[h0 >> 24 & 0x0F] + HEX_CHARS[h1 >> 4 & 0x0F] + HEX_CHARS[h1 & 0x0F] + HEX_CHARS[h1 >> 12 & 0x0F] + HEX_CHARS[h1 >> 8 & 0x0F] + HEX_CHARS[h1 >> 20 & 0x0F] + HEX_CHARS[h1 >> 16 & 0x0F] + HEX_CHARS[h1 >> 28 & 0x0F] + HEX_CHARS[h1 >> 24 & 0x0F] + HEX_CHARS[h2 >> 4 & 0x0F] + HEX_CHARS[h2 & 0x0F] + HEX_CHARS[h2 >> 12 & 0x0F] + HEX_CHARS[h2 >> 8 & 0x0F] + HEX_CHARS[h2 >> 20 & 0x0F] + HEX_CHARS[h2 >> 16 & 0x0F] + HEX_CHARS[h2 >> 28 & 0x0F] + HEX_CHARS[h2 >> 24 & 0x0F] + HEX_CHARS[h3 >> 4 & 0x0F] + HEX_CHARS[h3 & 0x0F] + HEX_CHARS[h3 >> 12 & 0x0F] + HEX_CHARS[h3 >> 8 & 0x0F] + HEX_CHARS[h3 >> 20 & 0x0F] + HEX_CHARS[h3 >> 16 & 0x0F] + HEX_CHARS[h3 >> 28 & 0x0F] + HEX_CHARS[h3 >> 24 & 0x0F];\n };\n\n /**\n * @method toString\n * @memberof Md5\n * @instance\n * @description Output hash as hex string\n * @returns {String} Hex string\n * @see {@link md5.hex}\n * @example\n * hash.toString();\n */\n Md5.prototype.toString = Md5.prototype.hex;\n\n /**\n * @method digest\n * @memberof Md5\n * @instance\n * @description Output hash as bytes array\n * @returns {Array} Bytes array\n * @see {@link md5.digest}\n * @example\n * hash.digest();\n */\n Md5.prototype.digest = function (format) {\n if (format === 'hex') return this.hex();\n this.finalize();\n var h0 = this.h0,\n h1 = this.h1,\n h2 = this.h2,\n h3 = this.h3;\n var res = [h0 & 0xFF, h0 >> 8 & 0xFF, h0 >> 16 & 0xFF, h0 >> 24 & 0xFF, h1 & 0xFF, h1 >> 8 & 0xFF, h1 >> 16 & 0xFF, h1 >> 24 & 0xFF, h2 & 0xFF, h2 >> 8 & 0xFF, h2 >> 16 & 0xFF, h2 >> 24 & 0xFF, h3 & 0xFF, h3 >> 8 & 0xFF, h3 >> 16 & 0xFF, h3 >> 24 & 0xFF];\n return res;\n };\n\n /**\n * @method array\n * @memberof Md5\n * @instance\n * @description Output hash as bytes array\n * @returns {Array} Bytes array\n * @see {@link md5.array}\n * @example\n * hash.array();\n */\n Md5.prototype.array = Md5.prototype.digest;\n\n /**\n * @method arrayBuffer\n * @memberof Md5\n * @instance\n * @description Output hash as ArrayBuffer\n * @returns {ArrayBuffer} ArrayBuffer\n * @see {@link md5.arrayBuffer}\n * @example\n * hash.arrayBuffer();\n */\n Md5.prototype.arrayBuffer = function () {\n this.finalize();\n var buffer = new ArrayBuffer(16);\n var blocks = new Uint32Array(buffer);\n blocks[0] = this.h0;\n blocks[1] = this.h1;\n blocks[2] = this.h2;\n blocks[3] = this.h3;\n return buffer;\n };\n\n /**\n * @method buffer\n * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.\n * @memberof Md5\n * @instance\n * @description Output hash as ArrayBuffer\n * @returns {ArrayBuffer} ArrayBuffer\n * @see {@link md5.buffer}\n * @example\n * hash.buffer();\n */\n Md5.prototype.buffer = Md5.prototype.arrayBuffer;\n\n /**\n * @method base64\n * @memberof Md5\n * @instance\n * @description Output hash as base64 string\n * @returns {String} base64 string\n * @see {@link md5.base64}\n * @example\n * hash.base64();\n */\n Md5.prototype.base64 = function () {\n var v1,\n v2,\n v3,\n base64Str = '',\n bytes = this.array();\n for (var i = 0; i < 15;) {\n v1 = bytes[i++];\n v2 = bytes[i++];\n v3 = bytes[i++];\n base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] + BASE64_ENCODE_CHAR[(v1 << 4 | v2 >>> 4) & 63] + BASE64_ENCODE_CHAR[(v2 << 2 | v3 >>> 6) & 63] + BASE64_ENCODE_CHAR[v3 & 63];\n }\n v1 = bytes[i];\n base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] + BASE64_ENCODE_CHAR[v1 << 4 & 63] + '==';\n return base64Str;\n };\n var exports = createMethod();\n if (COMMON_JS) {\n module.exports = exports;\n } else {\n /**\n * @method md5\b\n * @description Md5 hash function, export to global in browsers.\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {String} md5 hashes\n * @example\n * md5(''); // d41d8cd98f00b204e9800998ecf8427e\n * md5('The quick brown fox jumps over the lazy dog'); // 9e107d9d372bb6826bd81d3542a419d6\n * md5('The quick brown fox jumps over the lazy dog.'); // e4d909c290d0fb1ca068ffaddf22cbd0\n *\n * // It also supports UTF-8 encoding\n * md5('中文'); // a7bac2239fcdcb3a067903d8077c4a07\n *\n * // It also supports byte `Array`, `Uint8Array`, `ArrayBuffer`\n * md5([]); // d41d8cd98f00b204e9800998ecf8427e\n * md5(new Uint8Array([])); // d41d8cd98f00b204e9800998ecf8427e\n */\n root.md5 = exports;\n if (AMD) {\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {\n return exports;\n }).call(exports, __webpack_require__, exports, module),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n }\n }\n})();\n\n//# sourceURL=webpack://KS3/./lib/md5.js?"); /***/ }), /***/ "./src/advance.js": /*!************************!*\ !*** ./src/advance.js ***! \************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { eval("var utils = __webpack_require__(/*! ./utils.js */ \"./src/utils.js\");\nvar submitRequest = __webpack_require__(/*! ./requestSender */ \"./src/requestSender.js\");\nvar EventProxy = (__webpack_require__(/*! ./event */ \"./src/event.js\").EventProxy);\nvar session = __webpack_require__(/*! ./session */ \"./src/session.js\");\nvar {\n getUploadIdAndPartList,\n uploadSliceList,\n uploadSliceComplete\n} = __webpack_require__(/*! ./chunk */ \"./src/chunk.js\");\n\n/**\n * 获取请求地址\n * @params {*} params - { region, bucket, domain, resource, protocol, key }\n * @returns\n * @description\n * - `${this.config.protocol}://${bucket}.${domain}/${resource}`\n * - resource: key + suffix\n */\nfunction getUrl(params) {\n var region = params.region || this.config.region;\n var bucket = params.bucket || this.config.bucket;\n var domain = params.domain || '';\n var resource = params.resource || '';\n var key = params.key;\n var protocol = params.protocol || this.config.protocol;\n if (protocol) {\n protocol += ':';\n } else {\n protocol = location.protocol === 'http' ? 'http:' : 'https:';\n }\n if (!domain) {\n const ENDPOINT_KEY = Object.keys(utils.ENDPOINT);\n if (ENDPOINT_KEY.indexOf(region) > -1) {\n domain = utils.ENDPOINT[region];\n } else {\n // 输入的region不在既定的map中 则设置为默认的domain\n domain = region;\n }\n } else {\n domain = region;\n }\n\n // 去掉域名最后的斜杆\n if (domain.slice(-1) === '/') {\n domain = domain.slice(0, -1);\n }\n if (!this.config.forcePathStyle) {\n domain = bucket + '.' + domain;\n } else {\n domain = domain + '/' + bucket;\n }\n var url = `${protocol}//${domain}`;\n if (key) {\n url += `/${utils.encodeKey(key)}`;\n }\n if (resource) {\n url += `${resource}`;\n }\n return url;\n}\n\n/**\n * 高级上传文件\n * @param params\n * @params {String} params.bucket bucket名称,必须\n * @params {String} params.key object key,必须\n * @params {String} params.region region名称,必须\n * @params {String} params.acl 文件预设ACL(private | public-read),默认值private,非必须\n * @params {String} params.body 上传的文件,非必须\n * @params {Boolean} params.encryption 是否加密文件,非必须\n * @params {String} params.storageClass 对象的存储类型,非必须\n * @params {String} params.headers 自定义header信息,非必须\n * @params {String} params.sliceSize 多大的文件使用分片上传,默认 10MB\n * @params {Function} params.onTaskReady 上传任务准备完成回调,非必须\n * @params {Function} params.onProgress 上传进度监听函数,非必须\n * @params {Function} params.onFileFinish 上传任务准备完成回调,非必须\n * @param callback (err, data)\n */\nasync function uploadFile(params, callback) {\n var self = this;\n\n // 判断多大的文件使用分片上传\n var sliceSize = params.sliceSize || 10 * 1024 * 1024;\n var taskList = [];\n var Body = params.body;\n var fileSize = Body.size || Body.length || 0;\n var fileInfo = {\n taskId: ''\n };\n\n // 整理 option,用于返回给回调\n utils.each(params, function (v, k) {\n if (typeof v !== 'object' && typeof v !== 'function') {\n fileInfo[k] = v;\n }\n });\n\n // 处理文件 onTaskReady\n var _onTaskReady = params.onTaskReady;\n var onTaskReady = function (tid) {\n fileInfo.taskId = tid;\n _onTaskReady && _onTaskReady(tid);\n };\n params.onTaskReady = onTaskReady;\n\n // 添加上传任务,超过阈值使用分块上传,小于等于则简单上传\n var api = fileSize > sliceSize ? 'sliceUploadFile' : 'putUploadFile';\n\n // 处理文件完成\n var _onFileFinish = params.onFileFinish;\n var onFileFinish = function (err, data) {\n _onFileFinish && _onFileFinish(err, data, fileInfo);\n callback && callback(err, data);\n };\n taskList.push({\n api,\n params,\n callback: onFileFinish\n });\n\n // 添加任务至队列\n self._addTasks(taskList);\n}\n\n/**\n * 新 put 上传方法,基于 requestSender,支持暂停\n * @param params\n * @params {String} params.bucket bucket名称,必须\n * @params {String} params.region region名称,必须\n * @params {String} params.key object key,必须\n * @params {String} params.body 上传的文件,必须\n * @params {String} params.acl 文件预设ACL(private | public-read),默认值private,非必须\n * @params {Boolean} params.encryption 是否加密文件,非必须\n * @params {String} params.storageClass 对象的存储类型,非必须\n * @params {String} params.headers 自定义header信息,非必须\n * @params {Function} params.onProgress 上传进度监听函数,非必须\n * @param callback callback(err, res)\n * */\nasync function putUploadFile(params, callback) {\n var self = this;\n var fileSize = params.contentLength; // contentLength 不必填,addTask 的时候自动计算并添加到 params 中\n if (params.key === null || params.key === undefined) {\n throw Error('require the params of key!');\n }\n if (params.body === null || params.body === undefined) {\n throw Error('require the params of body!');\n }\n if (!params.bucket && !this.config.bucket) {\n throw Error('require the params of bucket or defaultConfig of bucket!');\n }\n if (!params.region && !this.config.region) {\n throw Error('require the params of region or defaultConfig of region!');\n }\n var headers = params.headers || {};\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = params.body && params.body.type ? params.body.type : '';\n }\n if (params.acl) {\n if (['private', 'public-read'].indexOf(params.acl) == -1) {\n throw Error('The value of acl can only be private or public-read!');\n }\n headers['x-kss-acl'] = params.acl;\n }\n if (params.encryption) {\n headers['x-kss-server-side-encryption'] = 'AES256';\n }\n if (params.storageClass) {\n headers['x-kss-storage-class'] = params.storageClass; // 存储类型\n }\n var onProgress = utils.throttleOnProgress.call(this, 0, params.onProgress);\n var bucket = params.bucket || this.config.bucket;\n var region = params.region || this.config.region;\n var url = getUrl.bind(this)({\n bucket,\n region,\n key: params.key\n });\n var reqParams = {\n taskId: params.taskId,\n method: 'PUT',\n bucket,\n url,\n qs: {},\n headers: headers,\n body: params.body,\n onProgress,\n onCancel: params.onCancel\n };\n if (!reqParams.headers['x-kss-date']) {\n reqParams.headers['x-kss-date'] = params.date ? params.date : new Date().toUTCString();\n }\n reqParams.date = reqParams.headers['x-kss-date'];\n var signature = params.signature || utils.getAuth(this.config.SK, reqParams.bucket, params.key, '', reqParams.method, reqParams.headers, reqParams.date);\n reqParams.headers['Authorization'] = `KSS ${this.config.AK}:${signature}`;\n if (params.authorization) {\n reqParams.headers['Authorization'] = params.authorization;\n }\n submitRequest.call(self, reqParams, function (err, data) {\n if (err) {\n onProgress(null, true);\n callback && callback(err, data);\n return;\n }\n onProgress({\n loaded: fileSize,\n total: fileSize\n }, true);\n callback && callback(err, data);\n });\n}\n\n/**\n * 分片上传对象(断点续传)\n * @param params\n * @params {String} params.bucket bucket名称,必须\n * @params {String} params.region region名称,必须\n * @params {String} params.key object key,必须\n * @params {String} params.body 上传的文件,必须\n * @params {String} params.acl 文件预设ACL(private | public-read),默认值private,非必须\n * @params {Boolean} params.encryption 是否加密文件,非必须\n * @params {Number} params.maxPartNumber 分块最大数量\n * @params {String} params.storageClass 对象的存储类型,非必须\n * @params {Number} params.chunkSize 分块上传的最小单位,默认 5MB,会根据文件大小动态调整\n * @params {String} params.headers 自定义header信息,非必须\n * @params {Function} params.onProgress 上传进度监听函数,非必须\n * @param callback callback(err, data)\n */\nasync function sliceUploadFile(params, callback) {\n var self = this;\n var ep = new EventProxy();\n var taskId = params.taskId;\n var bucket = params.bucket || this.config.bucket;\n var region = params.region || this.config.region;\n var key = params.key;\n var body = params.body;\n var chunkSize = params.chunkSize || self.config.chunkSize; // 单片大小\n var chunkRetryTimes = self.config.retryTimes || 3; // 单片大小\n var MaxPartNumber = params.maxPartNumber || 10000;\n var asyncLimit = Math.min(self.config.parallelLimit || 1, 256); // 分片并发数量\n var storageClass = params.storageClass; // 存储类型\n var encryption = params.encryption;\n var UploadIdCacheLimit = 50; // uploadId 缓存最大数量,一般不修改故不开放给用户\n var fileSize;\n var onProgress;\n if (!key) {\n throw Error('require the params of key!');\n }\n if (!body) {\n throw Error('require the params of body!');\n }\n if (!bucket) {\n throw Error('require the params of bucket or defaultConfig of bucket!');\n }\n if (!region) {\n throw Error('require the params of region or defaultConfig of region!');\n }\n ep.on('error', function (errData) {\n if (!self._isRunningTask(taskId)) return;\n return callback(errData);\n });\n\n // 上传分块完成,开始 uploadSliceComplete 操作\n ep.on('upload_complete', function (UploadCompleteData) {\n var _UploadCompleteData = utils.extend({\n UploadId: params.UploadData.UploadId || ''\n }, UploadCompleteData);\n callback(null, _UploadCompleteData);\n });\n\n // 上传分块完成,开始 uploadSliceComplete 操作\n ep.on('upload_slice_complete', function (UploadData) {\n var metaHeaders = {};\n uploadSliceComplete.call(self, {\n bucket: bucket,\n region: region,\n key: key,\n UploadId: UploadData.UploadId,\n SliceList: UploadData.SliceList,\n Headers: params.headers || {}\n }, function (err, data) {\n if (!self._isRunningTask(taskId)) return;\n session.removeUsing(UploadData.UploadId);\n if (err) {\n onProgress(null, true);\n return ep.emit('error', err);\n }\n session.removeUploadId.call(self, UploadData.UploadId);\n onProgress({\n loaded: fileSize,\n total: fileSize\n }, true);\n ep.emit('upload_complete', data);\n });\n });\n\n // 获取 UploadId 完成,开始上传每个分片\n ep.on('get_upload_data_finish', function (UploadData) {\n // 处理 UploadId 缓存\n var uuid = session.getFileId(body, params.chunkSize, bucket, key);\n uuid && session.saveUploadId.call(self, uuid, UploadData.UploadId, UploadIdCacheLimit); // 缓存 UploadId\n session.setUsing(UploadData.UploadId); // 标记 UploadId 为正在使用\n\n // 获取 UploadId\n onProgress(null, true); // 任务状态开始 uploading\n uploadSliceList.call(self, {\n taskId: taskId,\n bucket: bucket,\n region: region,\n key: key,\n Body: body,\n FileSize: fileSize,\n SliceSize: chunkSize,\n asyncLimit: asyncLimit,\n chunkRetryTimes: chunkRetryTimes,\n encryption: encryption,\n UploadData: UploadData,\n Headers: params.Headers,\n onProgress: onProgress\n }, function (err, data) {\n if (!self._isRunningTask(taskId)) return;\n if (err) {\n onProgress(null, true);\n return ep.emit('error', err);\n }\n ep.emit('upload_slice_complete', data);\n });\n });\n\n // 开始获取文件 UploadId,里面会视情况计算 ETag,并比对,保证文件一致性,也优化上传\n ep.on('get_file_size_finish', function () {\n onProgress = utils.throttleOnProgress.call(self, fileSize, params.onProgress);\n if (params.UploadData && params.UploadData.UploadId) {\n ep.emit('get_upload_data_finish', params.UploadData);\n } else {\n var _params = {\n taskId: taskId,\n bucket: bucket,\n region: region,\n key: key,\n headers: params.headers,\n storageClass: storageClass,\n body: body,\n fileSize: fileSize,\n // 文件大小\n sliceSize: chunkSize,\n // 分片大小\n ...params\n };\n\n // 没有 uploadId,第一次上传 \n getUploadIdAndPartList.call(self, _params, function (err, UploadData) {\n if (!self._isRunningTask(taskId)) return;\n if (err) return ep.emit('error', err);\n params.UploadData.UploadId = UploadData.UploadId;\n params.UploadData.PartList = UploadData.PartList;\n ep.emit('get_upload_data_finish', params.UploadData);\n });\n }\n });\n\n // 获取上传文件大小\n fileSize = params.contentLength;\n delete params.contentLength;\n !params.headers && (params.headers = {});\n utils.each(params.Headers, function (item, key) {\n if (key.toLowerCase() === 'content-length') {\n delete params.headers[key];\n }\n });\n\n // 控制分片大小\n (function () {\n var SIZE = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 1024 * 2, 1024 * 4, 1024 * 5];\n var autoChunkSize = 1024 * 1024; // 初始 1MB\n for (var i = 0; i < SIZE.length; i++) {\n autoChunkSize = SIZE[i] * 1024 * 1024;\n if (fileSize / autoChunkSize <= MaxPartNumber) break;\n }\n params.chunkSize = params.sliceSize = chunkSize = Math.max(chunkSize, autoChunkSize);\n })();\n\n // 开始上传\n if (fileSize === 0) {\n params.body = '';\n params.contentLength = 0;\n params.skipTask = true;\n self.putUploadFile(params, callback);\n } else {\n ep.emit('get_file_size_finish');\n }\n}\n\n// 上传分片方法: 基于 requestSender,支持暂停\nfunction uploadSlicePart(params, callback) {\n if (params.key === null || params.key === undefined) {\n throw Error('require the params of key!');\n }\n if (!params.bucket && !this.config.bucket) {\n throw Error('require the params of bucket or defaultConfig of bucket!');\n }\n if (!params.region && !this.config.region) {\n throw Error('require the params of region or defaultConfig of region!');\n }\n if (!params.partNumber) {\n throw Error('require the params of partNumber!');\n }\n if (!params.uploadId) {\n throw Error('require the params of uploadId!');\n }\n var headers = {};\n if (params.uploadType === 'copyPart') {\n headers['x-kss-copy-source'] = '/' + params.sourceBucket + '/' + utils.encodeKey(params.sourceKey);\n headers['x-kss-copy-source-range'] = params.range;\n }\n headers = Object.assign(headers, params.headers);\n var resource = `?partNumber=${params.partNumber}&uploadId=${params.uploadId}`;\n var bucket = params.bucket || this.config.bucket;\n var region = params.region || this.config.region;\n var url = getUrl.bind(this)({\n bucket,\n region,\n key: params.key,\n resource: resource\n });\n // var onProgress = utils.throttleOnProgress.call(this, 0, params.onProgress);\n var reqParams = {\n taskId: params.taskId,\n method: 'PUT',\n bucket,\n url,\n qs: {},\n headers: headers,\n onProgress: params.onProgress\n };\n if (params.uploadType === 'upload') {\n reqParams.body = params.body;\n }\n if (!reqParams.headers['x-kss-date']) {\n reqParams.headers['x-kss-date'] = params.date ? params.date : new Date().toUTCString();\n }\n reqParams.date = reqParams.headers['x-kss-date'];\n var signature = params.signature || utils.getAuth(this.config.SK, reqParams.bucket, params.key, resource, reqParams.method, reqParams.headers, reqParams.date);\n reqParams.headers['Authorization'] = `KSS ${this.config.AK}:${signature}`;\n var self = this;\n submitRequest.call(self, reqParams, function (err, data) {\n callback && callback(err, data);\n });\n}\nvar API_MAP = {\n putUploadFile,\n sliceUploadFile,\n uploadSlicePart,\n uploadFile\n};\nmodule.exports.init = function (ks3, task) {\n task.transferToTaskMethod(API_MAP, 'putUploadFile');\n task.transferToTaskMethod(API_MAP, 'sliceUploadFile');\n utils.each(API_MAP, function (fn, apiName) {\n ks3.prototype[apiName] = API_MAP[apiName];\n });\n};\n\n//# sourceURL=webpack://KS3/./src/advance.js?"); /***/ }), /***/ "./src/chunk.js": /*!**********************!*\ !*** ./src/chunk.js ***! \**********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"getUploadIdAndPartList\": () => (/* binding */ getUploadIdAndPartList),\n/* harmony export */ \"uploadSliceComplete\": () => (/* binding */ uploadSliceComplete),\n/* harmony export */ \"uploadSliceList\": () => (/* binding */ uploadSliceList)\n/* harmony export */ });\nvar util = __webpack_require__(/*! ./utils */ \"./src/utils.js\");\nvar EventProxy = (__webpack_require__(/*! ./event */ \"./src/event.js\").EventProxy);\nvar session = __webpack_require__(/*! ./session */ \"./src/session.js\");\nconst Async = __webpack_require__(/*! async */ \"./node_modules/async/dist/async.mjs\");\n\n// 获取上传任务的 UploadId 和 分片列表\nfunction getUploadIdAndPartList(params, callback) {\n var taskId = params.taskId;\n var bucket = params.bucket;\n var region = params.region;\n var key = params.key;\n var storageClass = params.storageClass;\n var self = this;\n\n // 计算 ETag\n var ETagMap = {};\n var FileSize = params.fileSize;\n var SliceSize = params.sliceSize; // 这里的 sliceSize 就是 chunkSize\n var SliceCount = Math.ceil(FileSize / SliceSize);\n var FinishSliceCount = 0; // 结束分片的数量\n var FinishSize = 0; // 结束分片的总大小\n var getChunkETag = function (PartNumber, callback) {\n var start = SliceSize * (PartNumber - 1);\n var end = Math.min(start + SliceSize, FileSize);\n var ChunkSize = end - start;\n if (ETagMap[PartNumber]) {\n callback(null, {\n PartNumber: PartNumber,\n ETag: ETagMap[PartNumber],\n Size: ChunkSize\n });\n } else {\n util.fileSliceForUpload(params.body, start, end, false, function (chunkItem) {\n util.getFileMd5(chunkItem, function (err, md5) {\n if (err) return callback(util.error(err));\n var ETag = String(md5);\n ETagMap[PartNumber] = ETag;\n FinishSliceCount += 1;\n FinishSize += ChunkSize;\n callback(null, {\n PartNumber: PartNumber,\n ETag: ETag,\n Size: ChunkSize\n });\n });\n });\n }\n };\n\n // 通过和文件的 md5 对比,判断 UploadId 是否可用\n var isAvailableUploadList = function (PartList, callback) {\n var PartCount = PartList.length;\n // 如果没有分片,通过\n if (PartCount === 0) {\n return callback(null, true);\n }\n // 检查分片数量\n if (PartCount > SliceCount) {\n return callback(null, false);\n }\n // 检查分片大小\n if (PartCount > 1) {\n var PartSliceSize = Math.max(PartList[0].Size, PartList[1].Size);\n if (PartSliceSize !== SliceSize) {\n return callback(null, false);\n }\n }\n // 逐个分片计算并检查 ETag 是否一致\n var next = function (index) {\n if (index < PartCount) {\n var Part = PartList[index];\n getChunkETag(Part.PartNumber, function (err, chunk) {\n if (chunk && chunk.ETag === Part.ETag && chunk.Size === Part.Size) {\n next(index + 1);\n } else {\n callback(null, false);\n }\n });\n } else {\n callback(null, true);\n }\n };\n next(0);\n };\n var ep = new EventProxy();\n ep.on('error', function (errData) {\n if (!self._isRunningTask(taskId)) return;\n return callback(errData);\n });\n\n // 存在 UploadId 构造待上传 partList 列表\n ep.on('upload_id_available', function (UploadData) {\n // 转换成 map\n var map = {};\n var list = [];\n util.each(UploadData.PartList, function (item) {\n map[item.PartNumber] = item;\n });\n for (var PartNumber = 1; PartNumber <= SliceCount; PartNumber++) {\n var item = map[PartNumber];\n if (item) {\n item.PartNumber = PartNumber;\n item.Uploaded = true;\n } else {\n item = {\n PartNumber: PartNumber,\n ETag: null,\n Uploaded: false\n };\n }\n list.push(item);\n }\n UploadData.PartList = list;\n callback(null, UploadData);\n });\n\n // 不存在 UploadId, 初始化生成 UploadId\n ep.on('no_available_upload_id', function () {\n if (!self._isRunningTask(taskId)) return;\n var _params = util.extend({\n bucket: bucket,\n region: region,\n key: key,\n storageClass: storageClass,\n body: params.body,\n encryption: params.encryption,\n acl: params.acl,\n headers: params.headers\n }, params);\n var headers = params.Headers;\n _params.Headers = headers;\n // 初始化分片上传\n self.initiateMultipartUpload(_params).then(res => {\n if (!self._isRunningTask(taskId)) return;\n if (res.error) return ep.emit('error', res.error);\n if (!res.body) return ep.emit('error', new Error('no such upload id'));\n var data = res.body.InitiateMultipartUploadResult;\n var UploadId = data.UploadId;\n if (!UploadId) {\n return callback(util.error(new Error('no such upload id')));\n }\n ep.emit('upload_id_available', {\n UploadId: UploadId,\n PartList: []\n });\n });\n });\n\n // 如果已存在 UploadId,找一个可以用的 UploadId\n ep.on('has_and_check_upload_id', function (UploadIdList) {\n // 串行地,找一个内容一致的 UploadId\n UploadIdList = UploadIdList.reverse();\n Async.eachLimit(UploadIdList, 1, function (UploadId, asyncCallback) {\n if (!self._isRunningTask(taskId)) return;\n // 如果正在上传,跳过\n if (session.using[UploadId]) {\n asyncCallback(); // 检查下一个 UploadId\n return;\n }\n // 判断 UploadId 是否可用\n wholeMultipartListPart.call(self, {\n bucket: bucket,\n region: region,\n key: key,\n UploadId: UploadId,\n tracker: params.tracker\n }, function (err, PartListData) {\n if (!self._isRunningTask(taskId)) return;\n if (err) {\n session.removeUsing(UploadId);\n return ep.emit('error', err);\n }\n // 已上传的分片\n var PartList = PartListData.PartList;\n PartList.forEach(function (item) {\n item.PartNumber *= 1;\n item.Size *= 1;\n item.ETag = item.ETag || '';\n });\n isAvailableUploadList(PartList, function (err, isAvailable) {\n if (!self._isRunningTask(taskId)) return;\n if (err) return ep.emit('error', err);\n if (isAvailable) {\n asyncCallback({\n UploadId: UploadId,\n PartList: PartList\n }); // 马上结束\n } else {\n asyncCallback(); // 检查下一个 UploadId\n }\n });\n });\n }, function (AvailableUploadData) {\n if (!self._isRunningTask(taskId)) return;\n if (AvailableUploadData && AvailableUploadData.UploadId) {\n ep.emit('upload_id_available', AvailableUploadData);\n } else {\n ep.emit('no_available_upload_id');\n }\n });\n });\n\n // 在本地缓存找可用的 UploadId\n ep.on('seek_local_avail_upload_id', function (RemoteUploadIdList) {\n // 在本地找可用的 UploadId\n var uuid = session.getFileId(params.body, params.chunkSize, bucket, key);\n var LocalUploadIdList = session.getUploadIdList.call(self, uuid);\n if (!uuid || !LocalUploadIdList) {\n ep.emit('has_and_check_upload_id', RemoteUploadIdList);\n return;\n }\n var next = function (index) {\n // 如果本地找不到可用 UploadId,再一个个遍历校验远端\n if (index >= LocalUploadIdList.length) {\n ep.emit('has_and_check_upload_id', RemoteUploadIdList);\n return;\n }\n var UploadId = LocalUploadIdList[index];\n // 如果不在远端 UploadId 列表里,跳过并删除\n if (!util.isInArray(RemoteUploadIdList, UploadId)) {\n session.removeUploadId.call(self, UploadId);\n next(index + 1);\n return;\n }\n // 如果正在上传,跳过\n if (session.using[UploadId]) {\n next(index + 1);\n return;\n }\n // 判断 UploadId 是否存在线上\n wholeMultipartListPart.call(self, {\n bucket: bucket,\n region: region,\n key: key,\n UploadId: UploadId\n // tracker: params.tracker,\n }, function (err, PartListData) {\n if (!self._isRunningTask(taskId)) return;\n if (err) {\n // 如果 UploadId 获取会出错,跳过并删除\n session.removeUploadId.call(self, UploadId);\n next(index + 1);\n } else {\n // 找到可用 UploadId\n ep.emit('upload_id_available', {\n UploadId: UploadId,\n PartList: PartListData.PartList\n });\n }\n });\n };\n next(0);\n });\n\n // 获取线上 UploadId 列表\n ep.on('get_remote_upload_id_list', function () {\n // 获取符合条件的 UploadId 列表,因为同一个文件可以有多个上传任务。\n wholeMultipartList.call(self, {\n bucket: bucket,\n region: region,\n key: key\n }, function (err, data) {\n if (!self._isRunningTask(taskId)) return;\n if (err) return ep.emit('error', err);\n // 整理远端 UploadId 列表\n var RemoteUploadIdList = util.filter(data.UploadList, function (item) {\n return item.Key === key && (!storageClass || item.StorageClass.toUpperCase() === storageClass.toUpperCase());\n }).reverse().map(function (item) {\n return item.UploadId || item.UploadID;\n });\n if (RemoteUploadIdList.length) {\n ep.emit('seek