ali-oss
Version:
aliyun oss(object storage service) node client
1,653 lines (1,343 loc) • 867 kB
JavaScript
// Aliyun OSS SDK for JavaScript v6.9.0
// Copyright Aliyun.com, Inc. or its affiliates. All Rights Reserved.
// License at https://github.com/ali-sdk/ali-oss/blob/master/LICENSE
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.OSS = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
'use strict';
var OSS = require('./browser/client');
OSS.Buffer = require('buffer').Buffer;
OSS.urllib = require('../shims/xhr');
OSS.version = require('./browser/version').version;
module.exports = OSS;
},{"../shims/xhr":291,"./browser/client":2,"./browser/version":5,"buffer":73}],2:[function(require,module,exports){
(function (Buffer,process){
'use strict';
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var debug = require('debug')('ali-oss');
var copy = require('copy-to');
var xml = require('xml2js');
var AgentKeepalive = require('agentkeepalive');
var merge = require('merge-descriptors');
var urlutil = require('url');
var is = require('is-type-of');
var platform = require('platform');
var utility = require('utility');
var urllib = require('urllib');
var pkg = require('./version');
var bowser = require('bowser');
var signUtils = require('../common/signUtils');
var _isIP = require('../common/utils/isIP');
var _initOptions = require('../common/client/initOptions');
var createRequest = require('../common/utils/createRequest');
var globalHttpAgent = new AgentKeepalive();
function _unSupportBrowserTip() {
var name = platform.name,
version = platform.version;
if (name && name.toLowerCase && name.toLowerCase() === 'ie' && version.split('.')[0] < 10) {
// eslint-disable-next-line no-console
console.warn('ali-oss does not support the current browser');
}
}
// check local web protocol,if https secure default set true , if http secure default set false
function isHttpsWebProtocol() {
// for web worker not use window.location.
// eslint-disable-next-line no-restricted-globals
return location && location.protocol === 'https:';
}
function Client(options, ctx) {
_unSupportBrowserTip();
if (!(this instanceof Client)) {
return new Client(options, ctx);
}
if (options && options.inited) {
this.options = options;
} else {
this.options = Client.initOptions(options);
}
this.options.cancelFlag = false; // cancel flag: if true need to be cancelled, default false
// support custom agent and urllib client
if (this.options.urllib) {
this.urllib = this.options.urllib;
} else {
this.urllib = urllib;
this.agent = this.options.agent || globalHttpAgent;
}
this.ctx = ctx;
this.userAgent = this._getUserAgent();
// record the time difference between client and server
this.options.amendTimeSkewed = 0;
}
/**
* Expose `Client`
*/
module.exports = Client;
Client.initOptions = function initOptions(options) {
if (!options.stsToken) {
console.warn('Please use STS Token for safety, see more details at https://help.aliyun.com/document_detail/32077.html');
}
var opts = (0, _assign2.default)({
secure: isHttpsWebProtocol(),
// for browser compatibility disable fetch.
useFetch: false
}, options);
return _initOptions(opts);
};
/**
* prototype
*/
var proto = Client.prototype;
// mount debug on proto
proto.debug = debug;
/**
* Object operations
*/
merge(proto, require('./object'));
/**
* Bucket operations
*/
merge(proto, require('../common/bucket/getBucketWebsite'));
merge(proto, require('../common/bucket/putBucketWebsite'));
merge(proto, require('../common/bucket/deleteBucketWebsite'));
// lifecycle
merge(proto, require('../common/bucket/getBucketLifecycle'));
merge(proto, require('../common/bucket/putBucketLifecycle'));
merge(proto, require('../common/bucket/deleteBucketLifecycle'));
// multiversion
merge(proto, require('../common/bucket/putBucketVersioning'));
merge(proto, require('../common/bucket/getBucketVersioning'));
// multipart upload
merge(proto, require('./managed-upload'));
/**
* Multipart operations
*/
merge(proto, require('../common/multipart'));
/**
* Common module parallel
*/
merge(proto, require('../common/parallel'));
/**
* get OSS signature
* @param {String} stringToSign
* @return {String} the signature
*/
proto.signature = function signature(stringToSign) {
this.debug('authorization stringToSign: %s', stringToSign, 'info');
return signUtils.computeSignature(this.options.accessKeySecret, stringToSign);
};
/**
* get author header
*
* "Authorization: OSS " + Access Key Id + ":" + Signature
*
* Signature = base64(hmac-sha1(Access Key Secret + "\n"
* + VERB + "\n"
* + CONTENT-MD5 + "\n"
* + CONTENT-TYPE + "\n"
* + DATE + "\n"
* + CanonicalizedOSSHeaders
* + CanonicalizedResource))
*
* @param {String} method
* @param {String} resource
* @param {Object} header
* @return {String}
*
* @api private
*/
proto.authorization = function authorization(method, resource, subres, headers) {
var stringToSign = signUtils.buildCanonicalString(method.toUpperCase(), resource, {
headers: headers,
parameters: subres
});
return signUtils.authorization(this.options.accessKeyId, this.options.accessKeySecret, stringToSign);
};
/**
* request oss server
* @param {Object} params
* - {String} object
* - {String} bucket
* - {Object} [headers]
* - {Object} [query]
* - {Buffer} [content]
* - {Stream} [stream]
* - {Stream} [writeStream]
* - {String} [mime]
* - {Boolean} [xmlResponse]
* - {Boolean} [customResponse]
* - {Number} [timeout]
* - {Object} [ctx] request context, default is `this.ctx`
*
* @api private
*/
proto.request = function request(params) {
var reqParams, result, reqErr, useStream, err, parseData;
return _regenerator2.default.async(function request$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
reqParams = createRequest.call(this, params);
if (!this.options.useFetch) {
reqParams.params.mode = 'disable-fetch';
}
result = void 0;
reqErr = void 0;
useStream = !!params.stream;
_context.prev = 5;
_context.next = 8;
return _regenerator2.default.awrap(this.urllib.request(reqParams.url, reqParams.params));
case 8:
result = _context.sent;
this.debug('response %s %s, got %s, headers: %j', params.method, reqParams.url, result.status, result.headers, 'info');
_context.next = 15;
break;
case 12:
_context.prev = 12;
_context.t0 = _context['catch'](5);
reqErr = _context.t0;
case 15:
err = void 0;
if (!(result && params.successStatuses && params.successStatuses.indexOf(result.status) === -1)) {
_context.next = 28;
break;
}
_context.next = 19;
return _regenerator2.default.awrap(this.requestError(result));
case 19:
err = _context.sent;
if (!(err.code === 'RequestTimeTooSkewed' && !useStream)) {
_context.next = 25;
break;
}
this.options.amendTimeSkewed = +new Date(err.serverTime) - new Date();
_context.next = 24;
return _regenerator2.default.awrap(this.request(params));
case 24:
return _context.abrupt('return', _context.sent);
case 25:
err.params = params;
_context.next = 32;
break;
case 28:
if (!reqErr) {
_context.next = 32;
break;
}
_context.next = 31;
return _regenerator2.default.awrap(this.requestError(reqErr));
case 31:
err = _context.sent;
case 32:
if (!err) {
_context.next = 34;
break;
}
throw err;
case 34:
if (!params.xmlResponse) {
_context.next = 39;
break;
}
_context.next = 37;
return _regenerator2.default.awrap(this.parseXML(result.data));
case 37:
parseData = _context.sent;
result.data = parseData;
case 39:
return _context.abrupt('return', result);
case 40:
case 'end':
return _context.stop();
}
}
}, null, this, [[5, 12]]);
};
proto._getResource = function _getResource(params) {
var resource = '/';
if (params.bucket) resource += params.bucket + '/';
if (params.object) resource += params.object;
return resource;
};
proto._isIP = _isIP;
proto._escape = function _escape(name) {
return utility.encodeURIComponent(name).replace(/%2F/g, '/');
};
proto._getReqUrl = function _getReqUrl(params) {
var ep = {};
copy(this.options.endpoint).to(ep);
var isIP = this._isIP(ep.hostname);
var isCname = this.options.cname;
if (params.bucket && !isCname && !isIP) {
ep.host = params.bucket + '.' + ep.host;
}
var reourcePath = '/';
if (params.bucket && isIP) {
reourcePath += params.bucket + '/';
}
if (params.object) {
// Preserve '/' in result url
reourcePath += this._escape(params.object).replace(/\+/g, '%2B');
}
ep.pathname = reourcePath;
var query = {};
if (params.query) {
merge(query, params.query);
}
if (params.subres) {
var subresAsQuery = {};
if (is.string(params.subres)) {
subresAsQuery[params.subres] = '';
} else if (is.array(params.subres)) {
params.subres.forEach(function (k) {
subresAsQuery[k] = '';
});
} else {
subresAsQuery = params.subres;
}
merge(query, subresAsQuery);
}
ep.query = query;
return urlutil.format(ep);
};
/*
* Get User-Agent for browser & node.js
* @example
* aliyun-sdk-nodejs/4.1.2 Node.js 5.3.0 on Darwin 64-bit
* aliyun-sdk-js/4.1.2 Safari 9.0 on Apple iPhone(iOS 9.2.1)
* aliyun-sdk-js/4.1.2 Chrome 43.0.2357.134 32-bit on Windows Server 2008 R2 / 7 64-bit
*/
proto._getUserAgent = function _getUserAgent() {
var agent = process && process.browser ? 'js' : 'nodejs';
var sdk = 'aliyun-sdk-' + agent + '/' + pkg.version;
var plat = platform.description;
if (!plat && process) {
plat = 'Node.js ' + process.version.slice(1) + ' on ' + process.platform + ' ' + process.arch;
}
return this._checkUserAgent(sdk + ' ' + plat);
};
proto._checkUserAgent = function _checkUserAgent(ua) {
var userAgent = ua.replace(/\u03b1/, 'alpha').replace(/\u03b2/, 'beta');
return userAgent;
};
/*
* Check Browser And Version
* @param {String} [name] browser name: like IE, Chrome, Firefox
* @param {String} [version] browser major version: like 10(IE 10.x), 55(Chrome 55.x), 50(Firefox 50.x)
* @return {Bool} true or false
* @api private
*/
proto.checkBrowserAndVersion = function checkBrowserAndVersion(name, version) {
return bowser.name === name && bowser.version.split('.')[0] === version;
};
/**
* thunkify xml.parseString
* @param {String|Buffer} str
*
* @api private
*/
proto.parseXML = function parseXMLThunk(str) {
return new _promise2.default(function (resolve, reject) {
if (Buffer.isBuffer(str)) {
str = str.toString();
}
xml.parseString(str, {
explicitRoot: false,
explicitArray: false
}, function (err, result) {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
};
/**
* generater a request error with request response
* @param {Object} result
*
* @api private
*/
proto.requestError = function requestError(result) {
var err, message, info, msg;
return _regenerator2.default.async(function requestError$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
err = null;
if (!(!result.data || !result.data.length)) {
_context2.next = 5;
break;
}
if (result.status === -1 || result.status === -2) {
// -1 is net error , -2 is timeout
err = new Error(result.message);
err.name = result.name;
err.status = result.status;
err.code = result.name;
} else {
// HEAD not exists resource
if (result.status === 404) {
err = new Error('Object not exists');
err.name = 'NoSuchKeyError';
err.status = 404;
err.code = 'NoSuchKey';
} else if (result.status === 412) {
err = new Error('Pre condition failed');
err.name = 'PreconditionFailedError';
err.status = 412;
err.code = 'PreconditionFailed';
} else {
err = new Error('Unknow error, status: ' + result.status);
err.name = 'UnknowError';
err.status = result.status;
}
err.requestId = result.headers['x-oss-request-id'];
err.host = '';
}
_context2.next = 33;
break;
case 5:
message = String(result.data);
this.debug('request response error data: %s', message, 'error');
info = void 0;
_context2.prev = 8;
_context2.next = 11;
return _regenerator2.default.awrap(this.parseXML(message));
case 11:
_context2.t0 = _context2.sent;
if (_context2.t0) {
_context2.next = 14;
break;
}
_context2.t0 = {};
case 14:
info = _context2.t0;
_context2.next = 24;
break;
case 17:
_context2.prev = 17;
_context2.t1 = _context2['catch'](8);
this.debug(message, 'error');
_context2.t1.message += '\nraw xml: ' + message;
_context2.t1.status = result.status;
_context2.t1.requestId = result.headers['x-oss-request-id'];
return _context2.abrupt('return', _context2.t1);
case 24:
msg = info.Message || 'unknow request error, status: ' + result.status;
if (info.Condition) {
msg += ' (condition: ' + info.Condition + ')';
}
err = new Error(msg);
err.name = info.Code ? info.Code + 'Error' : 'UnknowError';
err.status = result.status;
err.code = info.Code;
err.requestId = info.RequestId;
err.hostId = info.HostId;
err.serverTime = info.ServerTime;
case 33:
this.debug('generate error %j', err, 'error');
return _context2.abrupt('return', err);
case 35:
case 'end':
return _context2.stop();
}
}
}, null, this, [[8, 17]]);
};
}).call(this,{"isBuffer":require("../../node_modules/is-buffer/index.js")},require('_process'))
},{"../../node_modules/is-buffer/index.js":197,"../common/bucket/deleteBucketLifecycle":6,"../common/bucket/deleteBucketWebsite":7,"../common/bucket/getBucketLifecycle":8,"../common/bucket/getBucketVersioning":9,"../common/bucket/getBucketWebsite":10,"../common/bucket/putBucketLifecycle":11,"../common/bucket/putBucketVersioning":12,"../common/bucket/putBucketWebsite":13,"../common/client/initOptions":15,"../common/multipart":18,"../common/parallel":33,"../common/signUtils":34,"../common/utils/createRequest":38,"../common/utils/isIP":45,"./managed-upload":3,"./object":4,"./version":5,"_process":208,"agentkeepalive":48,"babel-runtime/core-js/object/assign":54,"babel-runtime/core-js/promise":61,"babel-runtime/regenerator":68,"bowser":70,"copy-to":76,"debug":288,"is-type-of":289,"merge-descriptors":200,"platform":206,"url":238,"urllib":291,"utility":290,"xml2js":249}],3:[function(require,module,exports){
(function (Buffer){
'use strict';
var _from = require('babel-runtime/core-js/array/from');
var _from2 = _interopRequireDefault(_from);
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// var debug = require('debug')('ali-oss:multipart');
var is = require('is-type-of');
var util = require('util');
var path = require('path');
var mime = require('mime');
var copy = require('copy-to');
var isBlob = require('../common/utils/isBlob');
var isFile = require('../common/utils/isFile');
var proto = exports;
/**
* Multipart operations
*/
/**
* Upload a file to OSS using multipart uploads
* @param {String} name
* @param {String|File} file
* @param {Object} options
* {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64
* {String} options.callback.url the OSS sends a callback request to this URL
* {String} options.callback.host The host header value for initiating callback requests
* {String} options.callback.body The value of the request body when a callback is initiated
* {String} options.callback.contentType The Content-Type of the callback requests initiatiated
* {Object} options.callback.customValue Custom parameters are a map of key-values, e.g:
* customValue = {
* key1: 'value1',
* key2: 'value2'
* }
*/
proto.multipartUpload = function multipartUpload(name, file, options) {
var minPartSize, fileSize, stream, result, ret, initResult, uploadId, partSize, checkpoint;
return _regenerator2.default.async(function multipartUpload$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
this.resetCancelFlag();
options = options || {};
if (!(options.checkpoint && options.checkpoint.uploadId)) {
_context.next = 6;
break;
}
_context.next = 5;
return _regenerator2.default.awrap(this._resumeMultipart(options.checkpoint, options));
case 5:
return _context.abrupt('return', _context.sent);
case 6:
minPartSize = 100 * 1024;
if (!options.mime) {
if (isFile(file)) {
options.mime = mime.getType(path.extname(file.name));
} else if (isBlob(file)) {
options.mime = file.type;
} else {
options.mime = mime.getType(path.extname(file));
}
}
options.headers = options.headers || {};
this._convertMetaToHeaders(options.meta, options.headers);
_context.next = 12;
return _regenerator2.default.awrap(this._getFileSize(file));
case 12:
fileSize = _context.sent;
if (!(fileSize < minPartSize)) {
_context.next = 25;
break;
}
stream = this._createStream(file, 0, fileSize);
options.contentLength = fileSize;
_context.next = 18;
return _regenerator2.default.awrap(this.putStream(name, stream, options));
case 18:
result = _context.sent;
if (!(options && options.progress)) {
_context.next = 22;
break;
}
_context.next = 22;
return _regenerator2.default.awrap(options.progress(1));
case 22:
ret = {
res: result.res,
bucket: this.options.bucket,
name: name,
etag: result.res.headers.etag
};
if (options.headers && options.headers['x-oss-callback'] || options.callback) {
ret.data = result.data;
}
return _context.abrupt('return', ret);
case 25:
if (!(options.partSize && !(parseInt(options.partSize, 10) === options.partSize))) {
_context.next = 27;
break;
}
throw new Error('partSize must be int number');
case 27:
if (!(options.partSize && options.partSize < minPartSize)) {
_context.next = 29;
break;
}
throw new Error('partSize must not be smaller than ' + minPartSize);
case 29:
_context.next = 31;
return _regenerator2.default.awrap(this.initMultipartUpload(name, options));
case 31:
initResult = _context.sent;
uploadId = initResult.uploadId;
partSize = this._getPartSize(fileSize, options.partSize);
checkpoint = {
file: file,
name: name,
fileSize: fileSize,
partSize: partSize,
uploadId: uploadId,
doneParts: []
};
if (!(options && options.progress)) {
_context.next = 38;
break;
}
_context.next = 38;
return _regenerator2.default.awrap(options.progress(0, checkpoint, initResult.res));
case 38:
_context.next = 40;
return _regenerator2.default.awrap(this._resumeMultipart(checkpoint, options));
case 40:
return _context.abrupt('return', _context.sent);
case 41:
case 'end':
return _context.stop();
}
}
}, null, this);
};
/*
* Resume multipart upload from checkpoint. The checkpoint will be
* updated after each successful part upload.
* @param {Object} checkpoint the checkpoint
* @param {Object} options
*/
proto._resumeMultipart = function _resumeMultipart(checkpoint, options) {
var that, file, fileSize, partSize, uploadId, doneParts, name, internalDoneParts, partOffs, numParts, multipartFinish, uploadPartJob, all, done, todo, defaultParallel, parallel, jobErr;
return _regenerator2.default.async(function _resumeMultipart$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
that = this;
if (!this.isCancel()) {
_context3.next = 3;
break;
}
throw this._makeCancelEvent();
case 3:
file = checkpoint.file, fileSize = checkpoint.fileSize, partSize = checkpoint.partSize, uploadId = checkpoint.uploadId, doneParts = checkpoint.doneParts, name = checkpoint.name;
internalDoneParts = [];
if (doneParts.length > 0) {
copy(doneParts).to(internalDoneParts);
}
partOffs = this._divideParts(fileSize, partSize);
numParts = partOffs.length;
multipartFinish = false;
uploadPartJob = function uploadPartJob(self, partNo) {
var _this = this;
return new _promise2.default(function _callee(resolve, reject) {
var pi, data, result, tempErr;
return _regenerator2.default.async(function _callee$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.prev = 0;
if (self.isCancel()) {
_context2.next = 18;
break;
}
pi = partOffs[partNo - 1];
data = {
stream: self._createStream(file, pi.start, pi.end),
size: pi.end - pi.start
};
_context2.next = 6;
return _regenerator2.default.awrap(self._uploadPart(name, uploadId, partNo, data));
case 6:
result = _context2.sent;
if (!(!self.isCancel() && !multipartFinish)) {
_context2.next = 15;
break;
}
checkpoint.doneParts.push({
number: partNo,
etag: result.res.headers.etag
});
if (!options.progress) {
_context2.next = 12;
break;
}
_context2.next = 12;
return _regenerator2.default.awrap(options.progress(doneParts.length / numParts, checkpoint, result.res));
case 12:
resolve({
number: partNo,
etag: result.res.headers.etag
});
_context2.next = 16;
break;
case 15:
resolve();
case 16:
_context2.next = 19;
break;
case 18:
resolve();
case 19:
_context2.next = 30;
break;
case 21:
_context2.prev = 21;
_context2.t0 = _context2['catch'](0);
tempErr = new Error();
tempErr.name = _context2.t0.name;
tempErr.message = _context2.t0.message;
tempErr.stack = _context2.t0.stack;
tempErr.partNum = partNo;
copy(_context2.t0).to(tempErr);
reject(tempErr);
case 30:
case 'end':
return _context2.stop();
}
}
}, null, _this, [[0, 21]]);
});
};
all = (0, _from2.default)(new Array(numParts), function (x, i) {
return i + 1;
});
done = internalDoneParts.map(function (p) {
return p.number;
});
todo = all.filter(function (p) {
return done.indexOf(p) < 0;
});
defaultParallel = 5;
parallel = options.parallel || defaultParallel;
// upload in parallel
_context3.next = 17;
return _regenerator2.default.awrap(this._parallel(todo, parallel, function (value) {
return new _promise2.default(function (resolve, reject) {
uploadPartJob(that, value).then(function (result) {
if (result) {
internalDoneParts.push(result);
}
resolve();
}).catch(function (err) {
reject(err);
});
});
}));
case 17:
jobErr = _context3.sent;
multipartFinish = true;
if (!this.isCancel()) {
_context3.next = 22;
break;
}
uploadPartJob = null;
throw this._makeCancelEvent();
case 22:
if (!(jobErr && jobErr.length > 0)) {
_context3.next = 25;
break;
}
jobErr[0].message = 'Failed to upload some parts with error: ' + jobErr[0].toString() + ' part_num: ' + jobErr[0].partNum;
throw jobErr[0];
case 25:
_context3.next = 27;
return _regenerator2.default.awrap(this.completeMultipartUpload(name, uploadId, internalDoneParts, options));
case 27:
return _context3.abrupt('return', _context3.sent);
case 28:
case 'end':
return _context3.stop();
}
}
}, null, this);
};
/**
* Get file size
*/
proto._getFileSize = function _getFileSize(file) {
return _regenerator2.default.async(function _getFileSize$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
if (!is.buffer(file)) {
_context4.next = 4;
break;
}
return _context4.abrupt('return', file.length);
case 4:
if (!(isBlob(file) || isFile(file))) {
_context4.next = 6;
break;
}
return _context4.abrupt('return', file.size);
case 6:
throw new Error('_getFileSize requires Buffer/File/Blob.');
case 7:
case 'end':
return _context4.stop();
}
}
}, null, this);
};
/*
* Readable stream for Web File
*/
var _require = require('stream'),
Readable = _require.Readable;
function WebFileReadStream(file, options) {
if (!(this instanceof WebFileReadStream)) {
return new WebFileReadStream(file, options);
}
Readable.call(this, options);
this.file = file;
this.reader = new FileReader();
this.start = 0;
this.finish = false;
this.fileBuffer = null;
}
util.inherits(WebFileReadStream, Readable);
WebFileReadStream.prototype.readFileAndPush = function readFileAndPush(size) {
if (this.fileBuffer) {
var pushRet = true;
while (pushRet && this.fileBuffer && this.start < this.fileBuffer.length) {
var start = this.start;
var end = start + size;
end = end > this.fileBuffer.length ? this.fileBuffer.length : end;
this.start = end;
pushRet = this.push(this.fileBuffer.slice(start, end));
}
}
};
WebFileReadStream.prototype._read = function _read(size) {
if (this.file && this.start >= this.file.size || this.fileBuffer && this.start >= this.fileBuffer.length || this.finish || this.start === 0 && !this.file) {
if (!this.finish) {
this.fileBuffer = null;
this.finish = true;
}
this.push(null);
return;
}
var defaultReadSize = 16 * 1024;
size = size || defaultReadSize;
var that = this;
this.reader.onload = function onload(e) {
that.fileBuffer = Buffer.from(new Uint8Array(e.target.result));
that.file = null;
that.readFileAndPush(size);
};
if (this.start === 0) {
this.reader.readAsArrayBuffer(this.file);
} else {
this.readFileAndPush(size);
}
};
proto._createStream = function _createStream(file, start, end) {
if (isBlob(file) || isFile(file)) {
return new WebFileReadStream(file.slice(start, end));
}
throw new Error('_createStream requires File/Blob.');
};
proto._getPartSize = function _getPartSize(fileSize, partSize) {
var maxNumParts = 10 * 1000;
var defaultPartSize = 1024 * 1024;
if (!partSize) {
return defaultPartSize;
}
return Math.max(Math.ceil(fileSize / maxNumParts), partSize);
};
proto._divideParts = function _divideParts(fileSize, partSize) {
var numParts = Math.ceil(fileSize / partSize);
var partOffs = [];
for (var i = 0; i < numParts; i++) {
var start = partSize * i;
var end = Math.min(start + partSize, fileSize);
partOffs.push({
start: start,
end: end
});
}
return partOffs;
};
}).call(this,require("buffer").Buffer)
},{"../common/utils/isBlob":43,"../common/utils/isFile":44,"babel-runtime/core-js/array/from":52,"babel-runtime/core-js/promise":61,"babel-runtime/regenerator":68,"buffer":73,"copy-to":76,"is-type-of":289,"mime":202,"path":205,"stream":230,"util":243}],4:[function(require,module,exports){
'use strict';
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// const debug = require('debug')('ali-oss:object');
var utility = require('utility');
var fs = require('fs');
var is = require('is-type-of');
var urlutil = require('url');
var copy = require('copy-to');
var path = require('path');
var mime = require('mime');
var callback = require('../common/callback');
var signHelper = require('../common/signUtils');
var merge = require('merge-descriptors');
var isBlob = require('../common/utils/isBlob');
var isFile = require('../common/utils/isFile');
// var assert = require('assert');
var proto = exports;
/**
* Object operations
*/
/**
* append an object from String(file path)/Buffer/ReadableStream
* @param {String} name the object key
* @param {Mixed} file String(file path)/Buffer/ReadableStream
* @param {Object} options
* @return {Object}
*/
proto.append = function append(name, file, options) {
var result;
return _regenerator2.default.async(function append$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
options = options || {};
if (options.position === undefined) options.position = '0';
options.subres = {
append: '',
position: options.position
};
options.method = 'POST';
_context.next = 6;
return _regenerator2.default.awrap(this.put(name, file, options));
case 6:
result = _context.sent;
result.nextAppendPosition = result.res.headers['x-oss-next-append-position'];
return _context.abrupt('return', result);
case 9:
case 'end':
return _context.stop();
}
}
}, null, this);
};
/**
* put an object from String(file path)/Buffer/ReadableStream
* @param {String} name the object key
* @param {Mixed} file String(file path)/Buffer/ReadableStream
* @param {Object} options
* {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64
* {String} options.callback.url the OSS sends a callback request to this URL
* {String} options.callback.host The host header value for initiating callback requests
* {String} options.callback.body The value of the request body when a callback is initiated
* {String} options.callback.contentType The Content-Type of the callback requests initiatiated
* {Object} options.callback.customValue Custom parameters are a map of key-values, e.g:
* customValue = {
* key1: 'value1',
* key2: 'value2'
* }
* @return {Object}
*/
proto.put = function put(name, file, options) {
var content, stream, _result, method, params, result, ret;
return _regenerator2.default.async(function put$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
content = void 0;
options = options || {};
name = this._objectName(name);
if (!is.buffer(file)) {
_context2.next = 7;
break;
}
content = file;
_context2.next = 30;
break;
case 7:
if (!(isBlob(file) || isFile(file))) {
_context2.next = 29;
break;
}
if (!options.mime) {
if (isFile(file)) {
options.mime = mime.getType(path.extname(file.name));
} else {
options.mime = file.type;
}
}
stream = this._createStream(file, 0, file.size);
_context2.next = 12;
return _regenerator2.default.awrap(this._getFileSize(file));
case 12:
options.contentLength = _context2.sent;
_context2.prev = 13;
_context2.next = 16;
return _regenerator2.default.awrap(this.putStream(name, stream, options));
case 16:
_result = _context2.sent;
return _context2.abrupt('return', _result);
case 20:
_context2.prev = 20;
_context2.t0 = _context2['catch'](13);
if (!(_context2.t0.code === 'RequestTimeTooSkewed')) {
_context2.next = 27;
break;
}
this.options.amendTimeSkewed = +new Date(_context2.t0.serverTime) - new Date();
_context2.next = 26;
return _regenerator2.default.awrap(this.put(name, file, options));
case 26:
return _context2.abrupt('return', _context2.sent);
case 27:
_context2.next = 30;
break;
case 29:
throw new TypeError('Must provide Buffer/Blob/File for put.');
case 30:
options.headers = options.headers || {};
this._convertMetaToHeaders(options.meta, options.headers);
method = options.method || 'PUT';
params = this._objectRequestParams(method, name, options);
callback.encodeCallback(params, options);
params.mime = options.mime;
params.content = content;
params.successStatuses = [200];
_context2.next = 40;
return _regenerator2.default.awrap(this.request(params));
case 40:
result = _context2.sent;
ret = {
name: name,
url: this._objectUrl(name),
res: result.res
};
if (params.headers && params.headers['x-oss-callback']) {
ret.data = JSON.parse(result.data.toString());
}
return _context2.abrupt('return', ret);
case 44:
case 'end':
return _context2.stop();
}
}
}, null, this, [[13, 20]]);
};
/**
* put an object from ReadableStream. If `options.contentLength` is
* not provided, chunked encoding is used.
* @param {String} name the object key
* @param {Readable} stream the ReadableStream
* @param {Object} options
* @return {Object}
*/
proto.putStream = function putStream(name, stream, options) {
var method, params, result, ret;
return _regenerator2.default.async(function putStream$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
options = options || {};
options.headers = options.headers || {};
name = this._objectName(name);
if (options.contentLength) {
options.headers['Content-Length'] = options.contentLength;
} else {
options.headers['Transfer-Encoding'] = 'chunked';
}
this._convertMetaToHeaders(options.meta, options.headers);
method = options.method || 'PUT';
params = this._objectRequestParams(method, name, options);
callback.encodeCallback(params, options);
params.mime = options.mime;
params.stream = stream;
params.successStatuses = [200];
_context3.next = 13;
return _regenerator2.default.awrap(this.request(params));
case 13:
result = _context3.sent;
ret = {
name: name,
url: this._objectUrl(name),
res: result.res
};
if (params.headers && params.headers['x-oss-callback']) {
ret.data = JSON.parse(result.data.toString());
}
return _context3.abrupt('return', ret);
case 17:
case 'end':
return _context3.stop();
}
}
}, null, this);
};
merge(proto, require('../common/object/copyObject'));
merge(proto, require('../common/object/getObjectTagging'));
merge(proto, require('../common/object/putObjectTagging'));
merge(proto, require('../common/object/deleteObjectTagging'));
merge(proto, require('../common/image'));
merge(proto, require('../common/object/getBucketVersions'));
merge(proto, require('../common/object/getACL'));
merge(proto, require('../common/object/putACL'));
merge(proto, require('../common/object/head'));
merge(proto, require('../common/object/delete'));
merge(proto, require('../common/object/get'));
merge(proto, require('../common/object/putSymlink'));
merge(proto, require('../common/object/getSymlink'));
merge(proto, require('../common/object/deleteMulti'));
merge(proto, require('../common/object/getObjectMeta'));
proto.putMeta = function putMeta(name, meta, options) {
var copyResult;
return _regenerator2.default.async(function putMeta$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return _regenerator2.default.awrap(this.copy(name, name, {
meta: meta || {},
timeout: options && options.timeout,
ctx: options && options.ctx
}));
case 2:
copyResult = _context4.sent;
return _context4.abrupt('return', copyResult);
case 4:
case 'end':
return _context4.stop();
}
}
}, null, this);
};
proto.list = function list(query, options) {
var params, result, objects, that, prefixes;
return _regenerator2.default.async(function list$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
// prefix, marker, max-keys, delimiter
params = this._objectRequestParams('GET', '', options);
params.query = query;
params.xmlResponse = true;
params.successStatuses = [200];
_context5.next = 6;
return _regenerator2.default.awrap(this.request(params));
case 6:
result = _context5.sent;
objects = result.data.Contents;
that = this;
if (objects) {
if (!Array.isArray(objects)) {
objects = [objects];
}
objects = objects.map(function (obj) {
return {
name: obj.Key,
url: that._objectUrl(obj.Key),
lastModified: obj.LastModified,
etag: obj.ETag,
type: obj.Type,
size: Number(obj.Size),
storageClass: obj.StorageClass,
owner: {
id: obj.Owner.ID,
displayName: obj.Owner.DisplayName
}
};
});
}
prefixes = result.data.CommonPrefixes || null;
if (prefixes) {
if (!Array.isArray(prefixes)) {
prefixes = [prefixes];
}
prefixes = prefixes.map(function (item) {
return item.Prefix;
});
}
return _context5.abrupt('return', {
res: result.res,
objects: objects,
prefixes: prefixes,
nextMarker: result.data.NextMarker || null,
isTruncated: result.data.IsTruncated === 'true'
});
case 13:
case 'end':
return _context5.stop();
}
}
}, null, this);
};
/**
* Restore Object
* @param {String} name the object key
* @param {Object} options
* @returns {{res}}
*/
proto.restore = function restore(name, options) {
var params, result;
return _regenerator2.default.async(function restore$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
options = options || {};
options.subres = (0, _assign2.default)({ restore: '' }, options.subres);
if (options.versionId) {
options.subres.versionId = options.versionId;
}
params = this._objectRequestParams('POST', name, options);
params.successStatuses = [202];
_context6.next = 7;
return _regenerator2.default.awrap(this.request(params));
case 7:
result = _context6.sent;
return _context6.abrupt('return', {
res: result.res
});
case 9:
case 'end':
return _context6.stop();
}
}
}, null, this);
};
proto.signatureUrl = function signatureUrl(name, options) {
options = options || {};
name = this._objectName(name);
options.method = options.method || 'GET';
var expires = utility.timestamp() + (options.expires || 1800);
var params = {
bucket: this.options.bucket,
object: name
};
var resource = this._getResource(params);
if (this.options.stsToken) {
options['security-token'] = this.options.stsToken;
}
var signRes = signHelper._signatureForURL(this.options.accessKeySecret, options, resource, expires);
var url = urlutil.parse(this._getReqUrl(params));
url.query = {
OSSAccessKeyId: this.options.accessKeyId,
Expires: expires,
Signature: signRes.Signature
};
copy(signRes.subResource).to(url.query);
return url.format();
};
/**
* Get Object url by name
* @param {String} name - object name
* @param {String} [baseUrl] - If provide `baseUrl`,
* will use `baseUrl` instead the default `endpoint`.
* @return {String} object url
*/
proto.getObjectUrl = function getObjectUrl(name, baseUrl) {
if (!baseUrl) {
baseUrl = this.options.endpoint.format();
} else if (baseUrl[baseUrl.length - 1] !== '/') {
baseUrl += '/';
}
return baseUrl + this._escape(this._objectName(name));
};
proto._objectUrl = function _objectUrl(name) {
return this._getReqUrl({ bucket: this.options.bucket, object: name });
};
/**
* Get Object url by name
* @param {String} name - object name
* @param {String} [baseUrl] - If provide `baseUrl`, will use `baseUrl` instead the default `endpoint and bucket`.
* @return {String} object url include bucket
*/
proto.generateObjectUrl = function (name, baseUrl) {
if (!baseUrl) {
baseUrl = this.options.endpoint.format();
var copyUrl = urlutil.parse(baseUrl);
var bucket = this.options.bucket;
copyUrl.hostname = bucket + '.' + copyUrl.hostname;
copyUrl.host = bucket + '.' + copyUrl.host;
baseUrl = copyUrl.format();
} else if (baseUrl[baseUrl.length - 1] !== '/') {
baseUrl += '/';
}
return baseUrl + this._escape(this._objectName(name));
};
/**
* generator request params
* @return {Object} params
*
* @api private
*/
proto._objectRequestParams = function _objectRequestParams(method, name, options) {
if (!this.options.bucket) {
throw new Error('Please create a bucket first');
}
options = options || {};
name = this._objectName(name);
var params = {
object: name,
bucket: this.options.bucket,
method: method,
subres: options && options.subres,
timeout: options && options.timeout,
ctx: options && options.ctx
};
if (options.headers) {
params.headers = {};
copy(options.headers).to(params.headers);
}
return params;
};
proto._objectName = function _objectName(name) {
return name.replace(/^\/+/, '');
};
proto._convertMetaToHeaders = function _convertMetaToHeaders(meta, headers) {
if (!meta) {
return;
}
(0, _keys2.default)(meta).forEach(function (k) {
headers['x-oss-meta-' + k] = meta[k];
});
};
proto._deleteFileSafe = function _deleteFileSafe(filepath) {
var _this = this;
return new _promise2.default(function (resolve) {
fs.exists(filepath, function (exists) {
if (!exists) {
resolve();
} else {
fs.unlink(filepath, function (err) {
if (err) {
_this.debug('unlink %j error: %s', filepath, err, 'error');
}
resolve();
});
}
});
});
};
},{"../common/callback":14,"../common/image":16,"../common/object/copyObject":19,"../common/object/delete":20,"../common/object/deleteMulti":21,"../common/object/deleteObjectTagging":22,"../common/object/get":23,"../common/object/getACL":24,"../common/object/getBucketVersions":25,"../common/object/getObjectMeta":26,"../common/object/getObjectTagging":27,"../common/object/getSymlink":28,"../common/object/head":29,"../common/object/putACL":30,"../common/object/putObjectTagging":31,"../common/object/putSymlink":32,"../common/signUtils":34,"../common/utils/isBlob":43,"../common/utils/isFile":44,"babel-runtime/core-js/object/assign":54,"babel-runtime/core-js/object/keys":60,"babel-runtime/core-js/promise":61,"babel-runtime/regenerator":68,"copy-to":76,"fs":71,"is-type-of":289,"merge-descriptors":200,"mime":202,"path":205,"url":238,"utility":290}],5:[function(require,module,exports){
"use strict";
exports.version = "6.9.0";
},{}],6:[function(require,module,exports){
'use strict';
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _checkBucketName = require('../utils/checkBucketName');
var proto = exports;
proto.deleteBucketLifecycle = function deleteBucketLifecycle(name, options) {
var params, result;
return _regenerator2.default.async(function deleteBucketLifecycle$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_checkBucketName(name);
params = this._bucketRequestParams('DELETE', name, 'lifecycle', options);
params.successStatuses = [204];
_context.next = 5;
return _regenerator2.default.awrap(this.request(params));
case 5:
result = _context.sent;
return _context.abrupt('return', {
res: result.res
});
case 7:
case 'end':
return _context.stop();
}
}
}, nul