ks3-js-sdk
Version:
js sdk for ks3
883 lines (806 loc) • 26.6 kB
JavaScript
var md5 = require('../lib/md5');
/*
* url endpoints for different regions
* Endpoint与Region的对应关系(官方文档): https://docs.ksyun.com/documents/6761
*/
const ENDPOINT = {
BEIJING : 'ks3-cn-beijing.ksyuncs.com',
SHANGHAI: 'ks3-cn-shanghai.ksyuncs.com',
GUANGZHOU: 'ks3-cn-guangzhou.ksyuncs.com',
HONGKONG: 'ks3-cn-hk-1.ksyuncs.com',
RUSSIA: 'ks3-rus.ksyuncs.com',
SINGAPORE: 'ks3-sgp.ksyuncs.com',
JR_BEIJING: 'ks3-jr-beijing.ksyuncs.com',
JR_SHANGHAI: 'ks3-jr-shanghai.ksyuncs.com',
GOV_BEIJING: 'ks3-gov-beijing.ksyuncs.com'
};
/**
* 给url添加请求参数
* @param url
* @param obj
* @returns {string} 带请求参数的url
*/
function addURLParam(url, obj){
url += url.indexOf("?") == -1 ? "?" : "";
var ret = [];
for(var key in obj){
key = encodeURIComponent(key);
var value = obj[key];
if(value && Object.prototype.toString.call(value) == '[object String]'){
ret.push(key + '=' + encodeURIComponent(value));
}
}
return url + ret.join('&');
};
/**
* key 进行encodeURIComponent编码,'/'不能被编码
*
*/
function encodeKey(key) {
var newKey = encodeURIComponent(key);
newKey = newKey.replace(/%2F/g, '/');
if (newKey.startsWith('/')) newKey = newKey.replace('/', '%2F')
// '//'needs convert to '/%2F'
if (newKey.includes('//')) newKey = newKey.replace(/\/\//g, '/%2F')
newKey = newKey.replace(/\!/g, '%21').replace(/\*/g, '%2A').replace(/\'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29');
return newKey
}
/*基于Javascript的Base64加解密算法*/
const Base64 = {
encTable :[ /*Base64编码表*/
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O' ,'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
],
// decTable:[ /*Base64解码表*/
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
// -1, -1, -1, 62, -1, -1, -1, 63, 52, 53,
// 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
// -1, -1, -1, -1, -1, 00, 01, 02, 03, 04,
// 05, 06, 07, 08, 09, 10, 11, 12, 13, 14,
// 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
// 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
// 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
// 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
// 49, 50, 51, -1, -1, -1, -1, -1
// ],
encUTF8: function(str) { /*将任意字符串按UTF8编码*/
var code, res =[], len =str.length;
var byte1, byte2, byte3, byte4, byte5, byte6;
for (var i = 0; i < len; i++) {
//Unicode码:按范围确定字节数
code = str.charCodeAt(i);
//单字节ascii字符:U+00000000 – U+0000007F 0xxxxxxx
if (code > 0x0000 && code <= 0x007F) res.push(code);
//双字节字符:U+00000080 – U+000007FF 110xxxxx 10xxxxxx
else if (code >= 0x0080 && code <= 0x07FF) {
byte1 = 0xC0 | ((code >> 6) & 0x1F);
byte2 = 0x80 | (code & 0x3F);
res.push(byte1, byte2);
}
//三字节字符:U+00000800 – U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
else if (code >= 0x0800 && code <= 0xFFFF) {
byte1 = 0xE0 | ((code >> 12) & 0x0F);
byte2 = 0x80 | ((code >> 6) & 0x3F);
byte3 = 0x80 | (code & 0x3F);
res.push(byte1, byte2, byte3);
}
//四字节字符:U+00010000 – U+001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if (code >= 0x00010000 && code <= 0x001FFFFF) {
byte1 =0xF0 | ((code>>18) & 0x07);
byte2 =0x80 | ((code>>12) & 0x3F);
byte3 =0x80 | ((code>>6) & 0x3F);
byte4 =0x80 | (code & 0x3F);
res.push(byte1, byte2, byte3, byte4);
}
//五字节字符:U+00200000 – U+03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if (code >= 0x00200000 && code <= 0x03FFFFFF) {
byte1 =0xF0 | ((code>>24) & 0x03);
byte2 =0xF0 | ((code>>18) & 0x3F);
byte3 =0x80 | ((code>>12) & 0x3F);
byte4 =0x80 | ((code>>6) & 0x3F);
byte5 =0x80 | (code & 0x3F);
res.push(byte1, byte2, byte3, byte4, byte5);
}
//六字节字符:U+04000000 – U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if (code >= 0x04000000 && code <= 0x7FFFFFFF) {
byte1 =0xF0 | ((code>>30) & 0x01);
byte2 =0xF0 | ((code>>24) & 0x3F);
byte3 =0xF0 | ((code>>18) & 0x3F);
byte4 =0x80 | ((code>>12) & 0x3F);
byte5 =0x80 | ((code>>6) & 0x3F);
byte6 =0x80 | (code & 0x3F);
res.push(byte1, byte2, byte3, byte4, byte5, byte6);
}
}
return res;
},
encode: function(str) {
/**
* 将任意字符串用Base64加密
* str:要加密的字符串
* utf8编码格式
*/
if (!str) return '';
var bytes = this.encUTF8(str);
var i = 0, len = bytes.length, res = [];
var c1, c2, c3;
while (i < len) {
c1 = bytes[i++] & 0xFF;
res.push(Base64.encTable[c1 >> 2]);
//结尾剩一个字节补2个=
if (i == len) {
res.push(Base64.encTable[(c1 & 0x03) << 4], '==');
break;
}
c2 = bytes[i++];
//结尾剩两个字节补1个=
if (i == len) {
res.push(Base64.encTable[((c1 & 0x03) << 4) | ((c2 >> 4) & 0x0F)]);
res.push(Base64.encTable[(c2 & 0x0F) << 2], '=');
break;
}
c3 = bytes[i++];
res.push(Base64.encTable[((c1 & 0x3) << 4) | ((c2 >> 4) & 0x0F)]);
res.push(Base64.encTable[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)]);
res.push(Base64.encTable[c3 & 0x3F]);
}
return res.join('');
}
};
const chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
const b64pad = "="; /* base-64 pad character. "=" for strict RFC compliance */
/*
* //使用hmac_sha1算法计算字符串的签名
* return base-64 encoded strings
*/
let b64_hmac_sha1 = function(key, data){
return binb2b64(core_hmac_sha1(key, data));
}
/*
* Calculate the HMAC-SHA1 of a key and some data
*/
let core_hmac_sha1 = function(key, data){
var bkey = str2binb(key);
if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
var ipad = Array(16), opad = Array(16);
for(var i = 0; i < 16; i++)
{
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
return core_sha1(opad.concat(hash), 512 + 160);
}
/*
* Convert an array of big-endian words to a base-64 string
*/
let binb2b64 = function(binarray){
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var str = "";
for(var i = 0; i < binarray.length * 4; i += 3)
{
var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16)
| (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
| ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
for(var j = 0; j < 4; j++)
{
if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
}
}
return str;
}
/*
* Convert an 8-bit or 16-bit string to an array of big-endian words
* In 8-bit function, characters >255 have their hi-byte silently ignored.
*/
let str2binb = function(str){
var bin = Array();
var mask = (1 << chrsz) - 1;
for(var i = 0; i < str.length * chrsz; i += chrsz)
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
return bin;
}
/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
*/
let core_sha1 = function(x, len){
/* append padding */
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for(var i = 0; i < x.length; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for(var j = 0; j < 80; j++)
{
if(j < 16) w[j] = x[i + j];
else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t;
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
let safe_add = function(x, y){
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
let rol = function(num, cnt){
return (num << cnt) | (num >>> (32 - cnt));
}
/*
* Perform the appropriate triplet combination function for the current
* iteration
*/
let sha1_ft = function(t, b, c, d){
if(t < 20) return (b & c) | ((~b) & d);
if(t < 40) return b ^ c ^ d;
if(t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
/*
* Determine the appropriate additive constant for the current iteration
*/
let sha1_kt = function(t){
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
}
var uuid = function () {
var S4 = function () {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
};
return S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4();
};
/**
* 产生headers
* CanonicalizedKssHeaders
*/
let generateHeaders =function(header) {
var str = '';
var arr = [];
if(header){
var prefix = 'x-kss';
let sortArr = [];
for (const key in header) {
if(key.indexOf(prefix) == 0){
sortArr.push({
key,
value: header[key]
});
}
};
// step2 : 根据属性名排序
sortArr.sort(function(a, b) {
return (a.key > b.key ? 1 : -1);
});
// step3 : 拼接起来
sortArr.forEach((element, index) => {
if(index === sortArr.length - 1){
str += element.key + ':' + element.value;
}else{
str += element.key + ':' + element.value + '\n';
}
});
}
return str;
}
/**
* 根据SK和请求生成Signature(用于Authorization头部)
* @param sk secrete key
* @param bucket bucket name
* @param resource ObjectKey[?subResource]
* @param httpVerb PUT/GET/POST/DELETE
* @param headers headers of request
* @param time_stamp expiration time
* @returns {*}
*/
let getAuth = async function (sk, bucket, key, resource, httpVerb, headers, time_stamp, params){
if(params.signature){
if(typeof params.signature !== 'function') {
return signatureResult;
}
const signatureResult = await params.signature({
bucket: bucket,
key: key,
resource: resource,
method: httpVerb,
headers: headers,
date: time_stamp,
config: this.config
});
return signatureResult;
}
var Resource = encodeKey(key) + resource;
var authHeaders = key2Lower(headers);
var canonicalizedKssHeaders = generateHeaders(authHeaders);
var canonicalizedResource = '/' + bucket + '/' + Resource;
var contentType = authHeaders['content-type'] || '';
var contentMD5 = authHeaders['content-md5'] || '';
if (canonicalizedKssHeaders !== '') {
var string2Sign = httpVerb.toUpperCase() + '\n' + contentMD5 + '\n' + contentType + '\n' + time_stamp + '\n' + canonicalizedKssHeaders + '\n' + canonicalizedResource;
} else {
var string2Sign = httpVerb.toUpperCase() + '\n' + contentMD5 + '\n' + contentType + '\n' + time_stamp + '\n' + canonicalizedResource;
}
console.log('string2Sign:' + string2Sign);
var signature = b64_hmac_sha1(sk, string2Sign);
console.log('signature:' + signature);
return signature;
}
function each(obj, fn) {
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
fn(obj[i], i);
}
}
}
//将header内的key都转成小写
function key2Lower(obj) {
var headers = {};
for (var key in obj) {
headers[key.toLowerCase()] = obj[key]
}
return headers;
}
// 获取文件分片
function fileSlice(file, start, end, callback) {
var blob;
if (file.slice) {
blob = file.slice(start, end);
} else if (file.mozSlice) {
blob = file.mozSlice(start, end);
} else if (file.webkitSlice) {
blob = file.webkitSlice(start, end);
}
var reader = new FileReader();
reader.onload = function(e) {
callback(e.target.result);
};
reader.readAsArrayBuffer(blob);
};
// 获取文件分片 新
var fileSliceForUpload = function (file, start, end, isUseToUpload, callback) {
var blob;
if (file.slice) { // W3C
blob = file.slice(start, end);
} else if (file.mozSlice) { // 火狐
blob = file.mozSlice(start, end);
} else if (file.webkitSlice) { // chrome
blob = file.webkitSlice(start, end);
}
if (isUseToUpload) {
var reader = new FileReader();
reader.onload = function (e) {
// 直接返回 ArrayBuffer,不需要重新包装成 Blob
callback(e.target.result);
// 清理资源
reader.onload = null;
reader.onerror = null;
};
reader.onerror = function() {
callback(null);
reader.onload = null;
reader.onerror = null;
};
reader.readAsArrayBuffer(blob);
} else {
callback(blob);
}
};
var readAsBinaryString = function (blob, callback) {
var readFun;
var fr = new FileReader();
if (FileReader.prototype.readAsBinaryString) {
readFun = FileReader.prototype.readAsBinaryString;
fr.onload = function () {
callback(this.result);
fr.onload = null;
fr.onerror = null;
};
} else if (FileReader.prototype.readAsArrayBuffer) {
// 在 ie11 添加 readAsBinaryString 兼容
readFun = function (fileData) {
var binary = '';
var reader = new FileReader();
reader.onload = function (e) {
var bytes = new Uint8Array(reader.result);
var length = bytes.byteLength;
for (var i = 0; i < length; i++) {
binary += String.fromCharCode(bytes[i]);
}
callback(binary);
reader.onload = null;
reader.onerror = null;
};
reader.readAsArrayBuffer(fileData);
};
fr.onload = null;
fr.onerror = null;
} else {
console.error('FileReader not support readAsBinaryString');
}
readFun.call(fr, blob);
};
// 获取文件 md5 值
var md5ChunkSize = 1024 * 1024;
var getFileMd5 = function (blob, callback, onProgress) {
var size = blob.size;
var loaded = 0;
var md5ctx = md5.getCtx();
var next = function (start) {
if (start >= size) {
var hash = md5ctx.digest('hex');
callback(null, hash);
return;
}
var end = Math.min(size, start + md5ChunkSize);
fileSliceForUpload(blob, start, end, false,function (chunk) {
readAsBinaryString(chunk, function (content) {
chunk = null;
md5ctx = md5ctx.update(content, true);
loaded += content.length;
content = null;
if (onProgress)
onProgress({ loaded: loaded, total: size, percent: Math.round((loaded / size) * 10000) / 10000 });
next(start + md5ChunkSize);
});
});
};
next(0);
};
/**
* 生成合并分块上传使用的xml
*/
function generateCompleteXML(partList) {
var length = partList.length;
var str = '';
if (length > 0) {
str = '<CompleteMultipartUpload>';
for (var i = 0; i < length; i++) {
str += '<Part><PartNumber>' + partList[i].partNumber + '</PartNumber><ETag>' + partList[i].etag + '</ETag></Part>'
}
str += '</CompleteMultipartUpload>';
}
return str;
}
// 函数节流 - 进度
var throttleOnProgress = function (total, onProgress) {
var self = this;
var size0 = 0;
var size1 = 0;
var time0 = Date.now();
var time1;
var timer;
function update() {
timer = 0;
if (onProgress && (typeof onProgress === 'function')) {
time1 = Date.now();
var speed = Math.max(0, Math.round((size1 - size0) / ((time1 - time0) / 1000) * 100) / 100) || 0;
var percent;
if (size1 === 0 && total === 0) {
percent = 1;
} else {
percent = Math.floor(size1 / total * 100) / 100 || 0;
}
time0 = time1;
size0 = size1;
try {
onProgress({loaded: size1, total: total, speed: speed, percent: percent});
} catch (e) {
}
}
}
return function (info, immediately) {
if (info) {
size1 = info.loaded;
total = info.total;
}
if (immediately) {
clearTimeout(timer);
update();
} else {
if (timer) return;
timer = setTimeout(update, self.config.progressInterval);
}
};
};
// 控制并发数量
/**
* arr Array 遍历集合
* limit number 每次异步操作时允许的并发执行的任务数量
* iteratee AsyncFunction 应用于遍历arr的异步函数,数组下标并不通过迭代器,如 果你需要用到index,使用eachOfLimit,调用 (item,callback)
* callback function<optional> 当所有迭代器结束或者出现一个错误调用(err)
*/
var syncLimit = function (arr, limit, iterator, callback) {
callback = callback || function () {};
if (!arr.length || limit <= 0) {
return callback();
}
var completed = 0;
var started = 0;
var running = 0;
(function replenish () {
if (completed >= arr.length) {
return callback();
}
while (running < limit && started < arr.length) {
started += 1;
running += 1;
iterator(arr[started - 1], function (err) {
if (err) {
callback(err);
callback = function () {};
} else {
completed += 1;
running -= 1;
if (completed >= arr.length) {
callback();
} else {
replenish();
}
}
});
}
})();
};
/**
* 获取post方式签名
* @param {*} sk
* @param {*} policy
* @returns
*/
var getPostSignature = function (sk, policy) {
var stringToSign = Base64.encode(JSON.stringify(policy));
var signature = b64_hmac_sha1(sk, stringToSign);
return signature;
}
/**
* 获取字符串的base64结果
* @param {*} policy
* @returns
*/
var getStrBase64 = function (policy) {
return Base64.encode(JSON.stringify(policy))
}
var getSourceParams = function (source) {
var m = source.match(/\/([^\s]+?)\/(.+)$/im);
if (!m) return null;
return { Bucket: m[1], Key: m[2] };
}
var generatePresignedUrl = function(params, sk, ak, url){
var StringToSign = '';
var expiresTime = parseInt(new Date().getTime() / 1000) + params.expiration;
var type = '';
var MD5 = '';
if(params.headers && params.headers['Content-Type']){
type = params.headers['Content-Type'];
}
if(params.headers && params.headers['Content-MD5']){
MD5 = params.headers['Content-MD5'];
}
var canonicalizedResource = '/' + params.bucket + '/' + params.key;
//生成url
var StringToSign = `${params.method}\n${MD5}\n${type}\n${expiresTime}\n${canonicalizedResource}`;
console.log(StringToSign)
var sign = b64_hmac_sha1(sk, StringToSign);
if(url){
return `${url}?KSSAccessKeyId=${ak}&Expires=${expiresTime}&Signature=${encodeURIComponent(sign)}`;
}
return sign;
}
var getFileSize = function (api, params, callback) {
var size;
if (typeof params.body === 'string') { // 如果是字符串,转化为 Blob 对象
params.body = new Blob([params.body], { type: 'text/plain' });
} else if (params.file instanceof ArrayBuffer) {
params.body = new Blob([params.body]);
}
// 保证 Body 存在,并且属于 Blob 对象或 File 对象
if (
params.body &&
(params.body instanceof Blob ||
params.body.toString() === '[object File]' ||
params.body.toString() === '[object Blob]')
) {
size = params.body.size;
} else {
callback(utils.error(new Error('params body format error, Only allow File|Blob|String.')));
return;
}
params.contentLength = size;
callback(null, size);
};
function isArray(arr) {
return arr instanceof Array;
}
function map(obj, fn) {
var o = isArray(obj) ? [] : {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
o[i] = fn(obj[i], i);
}
}
return o;
}
function clone(obj) {
return map(obj, function (v) {
return typeof v === 'object' && v !== null ? clone(v) : v;
});
}
function extend(target, source) {
each(source, function (val, key) {
target[key] = source[key];
});
return target;
}
var error = function (err, opt) {
var sourceErr = err;
err.message = err.message || null;
if (typeof opt === 'string') {
err.error = opt;
err.message = opt;
} else if (typeof opt === 'object' && opt !== null) {
extend(err, opt);
if (opt.code || opt.name) err.code = opt.code || opt.name;
if (opt.message) err.message = opt.message;
if (opt.stack) err.stack = opt.stack;
}
if (typeof Object.defineProperty === 'function') {
Object.defineProperty(err, 'name', { writable: true, enumerable: false });
Object.defineProperty(err, 'message', { enumerable: true });
}
err.name = (opt && opt.name) || err.name || err.code || 'Error';
if (!err.code) err.code = err.name;
if (!err.error) err.error = clone(sourceErr); // 兼容老的错误格式
return err;
};
function filter(obj, fn) {
var iaArr = isArray(obj);
var o = iaArr ? [] : {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
if (fn(obj[i], i)) {
if (iaArr) {
o.push(obj[i]);
} else {
o[i] = obj[i];
}
}
}
}
return o;
}
function isInArray(arr, item) {
var flag = false;
for (var i = 0; i < arr.length; i++) {
if (item === arr[i]) {
flag = true;
break;
}
}
return flag;
}
// 获取文件内容的 MD5
var getBodyMd5 = function (UploadCheckContentMd5, Body, callback) {
if (UploadCheckContentMd5) {
if (typeof Body === 'string') {
callback(utils.md5(Body, true));
} else if (Blob && Body instanceof Blob) {
utils.getFileMd5(
Body,
function (err, md5) {
callback(md5);
},
// onProgress
);
} else {
callback();
}
} else {
callback();
}
};
var getBodyMd5Promise = function (uploadCheckContentMd5, Body) {
return new Promise((resolve, reject) => {
if (!uploadCheckContentMd5) {
resolve();
return;
}
if (typeof Body === 'string') {
resolve(utils.md5(Body, true));
return;
}
if (Blob && Body instanceof Blob) {
utils.getFileMd5(
Body,
(err, md5) => {
if (err) {
reject(err);
} else {
resolve(md5);
}
},
// onProgress // 如果有进度回调,保持不变
);
} else {
resolve(); // 对于未知类型的 Body,直接 resolve()
}
});
};
var b64 = function (str) {
var i,
len,
char,
res = '';
for (i = 0, len = str.length / 2; i < len; i++) {
char = parseInt(str[i * 2] + str[i * 2 + 1], 16);
res += String.fromCharCode(char);
}
return btoa(res);
};
var utils = {
addURLParam,
b64_hmac_sha1,
getAuth,
getPostSignature,
getStrBase64,
each,
isInArray,
filter,
fileSlice,
fileSliceForUpload,
md5,
getFileMd5,
generateCompleteXML,
throttleOnProgress,
syncLimit,
getSourceParams,
encodeKey,
generatePresignedUrl,
ENDPOINT,
uuid,
b64,
getFileSize,
map,
error,
extend,
getBodyMd5,
getBodyMd5Promise
};
module.exports = utils;