UNPKG

19.4 kBJavaScriptView Raw
1/*! *****************************************************************************
2Copyright (c) Microsoft Corporation. All rights reserved.
3Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4this file except in compliance with the License. You may obtain a copy of the
5License at http://www.apache.org/licenses/LICENSE-2.0
6
7THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
9WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
10MERCHANTABLITY OR NON-INFRINGEMENT.
11
12See the Apache Version 2.0 License for specific language governing permissions
13and limitations under the License.
14***************************************************************************** */
15var __assign = function () {
16 __assign = Object.assign || function __assign(t) {
17 for (var s, i = 1, n = arguments.length; i < n; i++) {
18 s = arguments[i];
19
20 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
21 }
22
23 return t;
24 };
25
26 return __assign.apply(this, arguments);
27};
28
29/**
30 * remove ^\/+
31 * @param name
32 */
33function objectName(name) {
34 return name.replace(/^\/+/, '');
35}
36function escapeName(name) {
37 return encodeURIComponent(name).replace(/%2F/g, '/');
38}
39function isHttpsProtocol() {
40 return location && location.protocol === 'https:';
41}
42
43// unescape(encodeURIComponent(str))
44function utf8Encode(str) {
45 return unescape(encodeURIComponent(str));
46}
47/*
48export function utf8Decode(str) {
49 let i, ac, c1, c2, c3, arr = [],
50 l;
51 i = ac = c1 = c2 = c3 = 0;
52
53 if (str && str.length) {
54 l = str.length;
55 str += '';
56
57 while (i < l) {
58 c1 = str.charCodeAt(i);
59 ac += 1;
60 if (c1 < 128) {
61 arr[ac] = String.fromCharCode(c1);
62 i += 1;
63 } else if (c1 > 191 && c1 < 224) {
64 c2 = str.charCodeAt(i + 1);
65 arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
66 i += 2;
67 } else {
68 c2 = str.charCodeAt(i + 1);
69 c3 = str.charCodeAt(i + 2);
70 arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
71 i += 3;
72 }
73 }
74 }
75 return arr.join('');
76}
77*/
78/**
79 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
80 * to work around bugs in some JS interpreters.
81 */
82function safe_add(x, y) {
83 var lsw = (x & 0xFFFF) + (y & 0xFFFF), msw = (x >> 16) + (y >> 16) + (lsw >> 16);
84 return (msw << 16) | (lsw & 0xFFFF);
85}
86/**
87 * Bitwise rotate a 32-bit number to the left.
88 */
89function bit_rol(num, cnt) {
90 return (num << cnt) | (num >>> (32 - cnt));
91}
92/**
93 * Convert a raw string to a hex string
94 */
95function rstr2hex(input, hexCase) {
96 var hex_tab = hexCase ? '0123456789ABCDEF' : '0123456789abcdef', output = '', x, i = 0, l = input.length;
97 for (; i < l; i += 1) {
98 x = input.charCodeAt(i);
99 output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
100 }
101 return output;
102}
103/**
104 * Convert an array of big-endian words to a string
105 */
106function binb2rstr(input) {
107 var i, l = input.length * 32, output = '';
108 for (i = 0; i < l; i += 8) {
109 output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
110 }
111 return output;
112}
113/**
114 * Convert a raw string to an array of big-endian words
115 * Characters >255 have their high-byte silently ignored.
116 */
117function rstr2binb(input) {
118 var i, l = input.length * 8, output = Array(input.length >> 2), lo = output.length;
119 for (i = 0; i < lo; i += 1) {
120 output[i] = 0;
121 }
122 for (i = 0; i < l; i += 8) {
123 output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
124 }
125 return output;
126}
127/**
128 * Convert a raw string to an arbitrary string encoding
129 */
130function rstr2any(input, encoding) {
131 var divisor = encoding.length, remainders = Array(), i, q, x, ld, quotient, dividend, output, full_length;
132 /* Convert to an array of 16-bit big-endian values, forming the dividend */
133 dividend = Array(Math.ceil(input.length / 2));
134 ld = dividend.length;
135 for (i = 0; i < ld; i += 1) {
136 dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
137 }
138 /**
139 * Repeatedly perform a long division. The binary array forms the dividend,
140 * the length of the encoding is the divisor. Once computed, the quotient
141 * forms the dividend for the next step. We stop when the dividend is zerHashes.
142 * All remainders are stored for later use.
143 */
144 while (dividend.length > 0) {
145 quotient = Array();
146 x = 0;
147 for (i = 0; i < dividend.length; i += 1) {
148 x = (x << 16) + dividend[i];
149 q = Math.floor(x / divisor);
150 x -= q * divisor;
151 if (quotient.length > 0 || q > 0) {
152 quotient[quotient.length] = q;
153 }
154 }
155 remainders[remainders.length] = x;
156 dividend = quotient;
157 }
158 /* Convert the remainders to the output string */
159 output = '';
160 for (i = remainders.length - 1; i >= 0; i--) {
161 output += encoding.charAt(remainders[i]);
162 }
163 /* Append leading zero equivalents */
164 full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
165 for (i = output.length; i < full_length; i += 1) {
166 output = encoding[0] + output;
167 }
168 return output;
169}
170/**
171 * Convert a raw string to a base-64 string
172 */
173function rstr2b64(input, b64pad) {
174 if (b64pad === void 0) { b64pad = '='; }
175 var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
176 var output = '', len = input.length, i, j, triplet;
177 for (i = 0; i < len; i += 3) {
178 triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
179 for (j = 0; j < 4; j += 1) {
180 if (i * 8 + j * 6 > input.length * 8) {
181 output += b64pad;
182 }
183 else {
184 output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
185 }
186 }
187 }
188 return output;
189}
190
191/**
192 * This file is copied from https://github.com/react-component/upload/blob/master/src/request.js
193 * Thanks the authors.
194 */
195function getError(url, option, xhr) {
196 var codePart = xhr.response.match(/<Code>(.+)<\/Code>/);
197 var messagePart = xhr.response.match(/<Message>(.+)<\/Message>/);
198 var method = option.method || 'GET';
199 // let msg = `[${xhr.status}] ${method} ${url}`;
200 var msg = '';
201 if (codePart && codePart[1])
202 msg += codePart[1] + ": ";
203 if (messagePart && messagePart[1])
204 msg += messagePart[1];
205 var err = new Error(msg);
206 err.status = xhr.status;
207 err.method = method;
208 err.code = codePart && codePart[1] || '';
209 err.url = url;
210 return err;
211}
212function getBody(xhr) {
213 var text = xhr.responseText || xhr.response;
214 if (!text) {
215 return text;
216 }
217 try {
218 return JSON.parse(text);
219 }
220 catch (e) {
221 return text;
222 }
223}
224function request(url, options) {
225 var xhr = new XMLHttpRequest();
226 xhr.timeout = options.timeout || 60000;
227 if (options.onProgress && xhr.upload) {
228 xhr.upload.onprogress = function progress(e) {
229 e.percent = e.loaded / e.total * 100;
230 options.onProgress(e);
231 };
232 }
233 /*
234 const formData = new FormData();
235 if (options.data){
236 Object.keys(options.data).forEach(key => {
237 formData.append(key, options.data[key]);
238 })
239 }
240 formData.append(options.filename, options.file);
241 */
242 xhr.onerror = function (e) {
243 options.onError(e);
244 };
245 xhr.onload = function onload() {
246 if (xhr.status < 200 || xhr.status >= 300) {
247 return options.onError(getError(url, options, xhr), getBody(xhr));
248 }
249 var result = {
250 status: xhr.status,
251 statusText: xhr.statusText,
252 xhr: xhr,
253 data: getBody(xhr),
254 };
255 options.onSuccess(result, xhr);
256 };
257 xhr.ontimeout = function timeout(ev) {
258 var err = new Error("Request timeout, limit " + xhr.timeout + " ms.");
259 options.onError(err);
260 };
261 if (options.onAbort)
262 xhr.onabort = options.onAbort;
263 xhr.open(options.method || 'get', url, true);
264 if (options.withCredentials && 'withCredentials' in xhr) {
265 xhr.withCredentials = true;
266 }
267 var headers = options.headers || {};
268 if (headers['X-Requested-With'] !== null) {
269 xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
270 }
271 for (var h in headers) {
272 if (headers.hasOwnProperty(h) && headers[h] !== null) {
273 xhr.setRequestHeader(h, headers[h]);
274 }
275 }
276 // xhr.send(formData);
277 xhr.send(options.data || null);
278 return {
279 abort: function () {
280 xhr.abort();
281 },
282 };
283}
284
285/**
286 * Copy from https://github.com/h2non/jshashes/blob/master/hashes.js
287 */
288var SHA1 = function SHA1(options) {
289 /**
290 * Private config properties. You may need to tweak these to be compatible with
291 * the server-side, but the defaults work in most cases.
292 * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
293 */
294 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
295 b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
296 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
297 // public methods
298 this.hex = function (s) {
299 return rstr2hex(rstr(s, utf8), hexcase);
300 };
301 this.b64 = function (s) {
302 return rstr2b64(rstr(s, utf8), b64pad);
303 };
304 this.any = function (s, e) {
305 return rstr2any(rstr(s, utf8), e);
306 };
307 this.raw = function (s) {
308 return rstr(s, utf8);
309 };
310 this.hex_hmac = function (k, d) {
311 return rstr2hex(rstr_hmac(k, d));
312 };
313 this.b64_hmac = function (k, d) {
314 return rstr2b64(rstr_hmac(k, d), b64pad);
315 };
316 this.any_hmac = function (k, d, e) {
317 return rstr2any(rstr_hmac(k, d), e);
318 };
319 /**
320 * Perform a simple self-test to see if the VM is working
321 * @return {String} Hexadecimal hash sample
322 * @public
323 */
324 /*this.vm_test = function () {
325 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
326 };*/
327 /**
328 * @description Enable/disable uppercase hexadecimal returned string
329 * @param {boolean} a
330 * @return {Object} this
331 * @public
332 */
333 this.setUpperCase = function (a) {
334 if (typeof a === 'boolean') {
335 hexcase = a;
336 }
337 return this;
338 };
339 /**
340 * @description Defines a base64 pad string
341 * @param {string} Pad
342 * @return {Object} this
343 * @public
344 */
345 this.setPad = function (Pad) {
346 b64pad = Pad || b64pad;
347 return this;
348 };
349 /**
350 * @description Defines a base64 pad string
351 * @param {boolean} a
352 * @return {Object} this
353 * @public
354 */
355 this.setUTF8 = function (a) {
356 if (typeof a === 'boolean') {
357 utf8 = a;
358 }
359 return this;
360 };
361 // private methods
362 /**
363 * Calculate the SHA-1 of an array of big-endian words, and a bit length
364 */
365 function binb(x, len) {
366 var i, j, t, olda, oldb, oldc, oldd, olde, w = Array(80), a = 1732584193, b = -271733879, c = -1732584194, d = 271733878, e = -1009589776;
367 /* append padding */
368 x[len >> 5] |= 0x80 << (24 - len % 32);
369 x[((len + 64 >> 9) << 4) + 15] = len;
370 for (i = 0; i < x.length; i += 16) {
371 olda = a;
372 oldb = b;
373 oldc = c;
374 oldd = d;
375 olde = e;
376 for (j = 0; j < 80; j += 1) {
377 if (j < 16) {
378 w[j] = x[i + j];
379 }
380 else {
381 w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
382 }
383 t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));
384 e = d;
385 d = c;
386 c = bit_rol(b, 30);
387 b = a;
388 a = t;
389 }
390 a = safe_add(a, olda);
391 b = safe_add(b, oldb);
392 c = safe_add(c, oldc);
393 d = safe_add(d, oldd);
394 e = safe_add(e, olde);
395 }
396 return Array(a, b, c, d, e);
397 }
398 /**
399 * Calculate the SHA-512 of a raw string
400 */
401 function rstr(s, utf8) {
402 s = (utf8) ? utf8Encode(s) : s;
403 return binb2rstr(binb(rstr2binb(s), s.length * 8));
404 }
405 /**
406 * Calculate the HMAC-SHA1 of a key and some data (raw strings)
407 */
408 function rstr_hmac(key, data) {
409 var bkey, ipad, opad, i, hash;
410 key = (utf8) ? utf8Encode(key) : key;
411 data = (utf8) ? utf8Encode(data) : data;
412 bkey = rstr2binb(key);
413 if (bkey.length > 16) {
414 bkey = binb(bkey, key.length * 8);
415 }
416 ipad = Array(16), opad = Array(16);
417 for (i = 0; i < 16; i += 1) {
418 ipad[i] = bkey[i] ^ 0x36363636;
419 opad[i] = bkey[i] ^ 0x5C5C5C5C;
420 }
421 hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
422 return binb2rstr(binb(opad.concat(hash), 512 + 160));
423 }
424 /**
425 * Perform the appropriate triplet combination function for the current
426 * iteration
427 */
428 function sha1_ft(t, b, c, d) {
429 if (t < 20) {
430 return (b & c) | ((~b) & d);
431 }
432 if (t < 40) {
433 return b ^ c ^ d;
434 }
435 if (t < 60) {
436 return (b & c) | (b & d) | (c & d);
437 }
438 return b ^ c ^ d;
439 }
440 /**
441 * Determine the appropriate additive constant for the current iteration
442 */
443 function sha1_kt(t) {
444 return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
445 (t < 60) ? -1894007588 : -899497514;
446 }
447};
448
449function computeSignature(accessKeySecret, canonicalString) {
450 return new SHA1().b64_hmac(accessKeySecret, canonicalString);
451}
452
453function getOssParams(params, extendKeys) {
454 if (extendKeys === void 0) { extendKeys = []; }
455 var out = {};
456 Object.keys(params).forEach(function (key) {
457 var lowerKey = key.toLowerCase();
458 if (/^x-oss-/.test(lowerKey) || extendKeys.indexOf(key) > -1) {
459 out[lowerKey] = params[key];
460 }
461 });
462 return out;
463}
464var Client = /** @class */ (function () {
465 function Client(options) {
466 if (!(this instanceof Client)) {
467 return new Client(options);
468 }
469 var opts = __assign(__assign({ endpoint: null, region: 'oss-cn-hangzhou', timeout: 300000, internal: false,
470 // cname: false,
471 secure: undefined }, options), { host: '' });
472 if (opts.endpoint) ;
473 else if (opts.region && opts.bucket) {
474 opts.endpoint = opts.bucket;
475 if (opts.internal)
476 opts.region += '-internal';
477 opts.endpoint += "." + opts.region + ".aliyuncs.com";
478 }
479 else {
480 throw new Error('require endpoint or region/bucket in options');
481 }
482 // 一般情况下不需要设置 `secure` 参数,唯一需要用到的场景可能就是在 http 页面中使用 https 连接了
483 opts.host += "http" + (opts.secure === true || isHttpsProtocol() ? 's' : '') + "://" + opts.endpoint;
484 this.opts = opts;
485 }
486 /*
487 public putObject(name, file: File|BlobPart, options){
488
489 }
490 */
491 /**
492 * post object as form/multi-part
493 * @param name
494 * @param file
495 * @param options
496 */
497 Client.prototype.postObject = function (name, file, options) {
498 if (options === void 0) { options = {}; }
499 var policyBase64;
500 var data = new FormData();
501 Object.keys(options.headers || {}).forEach(function (key) {
502 data.append(key, options.headers[key].toString());
503 });
504 var objectKey = objectName((options.dir || '').replace(/^(.+?)\/*$/, '$1/') + objectName(name));
505 data.append('key', objectKey);
506 if (this.opts.accessKeyId && this.opts.accessKeySecret) {
507 if (typeof options.policy === 'string') {
508 policyBase64 = options.policy;
509 }
510 else {
511 var policy = __assign({ "expiration": new Date(+new Date() + 24 * 3600 * 1000).toISOString(), "conditions": [
512 { "bucket": this.opts.bucket },
513 { "key": objectKey },
514 ["content-length-range", 0, 1024 * 1024 * 1024],
515 ] }, options.policy);
516 policyBase64 = rstr2b64(utf8Encode(JSON.stringify(policy)));
517 }
518 var signature = options.signature || computeSignature(this.opts.accessKeySecret, policyBase64);
519 data.append('OSSAccessKeyId', this.opts.accessKeyId);
520 data.append('policy', policyBase64);
521 data.append('Signature', signature);
522 if (this.opts.stsToken) {
523 data.append('x-oss-security-token', this.opts.stsToken);
524 }
525 }
526 var ossParam = getOssParams(options, ['success_action_status', 'success_action_redirect']);
527 Object.keys(ossParam).forEach(function (k) { return data.append(k, ossParam[k]); });
528 data.append('file', file);
529 var emptyFunc = function () { };
530 var successCallback = options.onSuccess || emptyFunc;
531 var reqOptions = {
532 method: 'POST',
533 data: data,
534 timeout: options.timeout || this.opts.timeout,
535 onSuccess: function (result, xhr) { return successCallback(result, xhr); },
536 onError: options.onError || function (e) {
537 console.error(e);
538 },
539 onAbort: options.onAbort || emptyFunc,
540 };
541 if (options.onProgress)
542 reqOptions.onProgress = options.onProgress;
543 return request(this.opts.host, reqOptions);
544 };
545 /**
546 * Get the Object url.
547 * If provide baseUrl, will use baseUrl instead the default bucket and endpoint .
548 * @param name
549 * @param baseUrl
550 */
551 Client.prototype.generateObjectUrl = function (name, baseUrl) {
552 if (!baseUrl) {
553 baseUrl = this.opts.host + '/';
554 }
555 else if (baseUrl[baseUrl.length - 1] !== '/') {
556 baseUrl += '/';
557 }
558 return baseUrl + escapeName(objectName(name));
559 };
560 return Client;
561}());
562
563export default Client;