Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: tencentyun/cos-nodejs-sdk-v5
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 5e2f48e91dcdb601992360a1b38836bf2965efa9
Choose a base ref
...
head repository: tencentyun/cos-nodejs-sdk-v5
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 94d51c3ef0dfc185ec48bf8836b873e417d18b50
Choose a head ref

Commits on Sep 6, 2018

  1. add tcb test ut

    carsonxu committed Sep 6, 2018
    Copy the full SHA
    b95d61a View commit details
  2. update tcb test ut

    carsonxu committed Sep 6, 2018
    Copy the full SHA
    0074a7b View commit details
  3. update test ut

    carsonxu committed Sep 6, 2018
    Copy the full SHA
    da5719d View commit details

Commits on Oct 12, 2018

  1. 修复上传10000个的报错

    修复并发 sliceUploadFile 错误
    carsonxu committed Oct 12, 2018
    Copy the full SHA
    510eeb4 View commit details
  2. Copy the full SHA
    96bddb6 View commit details

Commits on Oct 17, 2018

  1. Copy the full SHA
    cfd6a3b View commit details

Commits on Oct 18, 2018

  1. Rule -> Rules

    carsonxu committed Oct 18, 2018
    Copy the full SHA
    e148e66 View commit details

Commits on Nov 12, 2018

  1. Copy the full SHA
    60d34c0 View commit details
  2. 修改 demo

    carsonxu committed Nov 12, 2018
    Copy the full SHA
    33c8e05 View commit details
  3. Copy the full SHA
    c8ef701 View commit details
  4. 修改 demo 和用例

    carsonxu committed Nov 12, 2018
    Copy the full SHA
    fb82f20 View commit details
  5. 优化进度反馈

    carsonxu committed Nov 12, 2018
    Copy the full SHA
    d45d313 View commit details

Commits on Nov 13, 2018

  1. 优化进度反馈

    carsonxu committed Nov 13, 2018
    Copy the full SHA
    3067bd3 View commit details

Commits on Nov 14, 2018

  1. 调整上传调用顺序

    carsonxu committed Nov 14, 2018
    Copy the full SHA
    5211239 View commit details
  2. 修改测试用例

    carsonxu committed Nov 14, 2018
    Copy the full SHA
    23b5c27 View commit details
  3. 更新版本号

    carsonxu committed Nov 14, 2018
    Copy the full SHA
    1996a59 View commit details

Commits on Nov 15, 2018

  1. 修改最大分片大小

    carsonxu committed Nov 15, 2018
    Copy the full SHA
    8a32648 View commit details

Commits on Nov 22, 2018

  1. 优化代码

    carsonxu committed Nov 22, 2018
    Copy the full SHA
    fbaf025 View commit details
  2. update test

    carsonxu committed Nov 22, 2018
    Copy the full SHA
    87d1b71 View commit details
  3. 支持 Timeout 选项

    carsonxu committed Nov 22, 2018
    Copy the full SHA
    b77ee1f View commit details

Commits on Dec 6, 2018

  1. 支持 STS Scope

    carsonxu committed Dec 6, 2018
    Copy the full SHA
    b737f86 View commit details
  2. 支持 STS Scope

    carsonxu committed Dec 6, 2018
    Copy the full SHA
    94d51c3 View commit details
Showing with 3,234 additions and 1,090 deletions.
  1. +73 −0 demo/demo-sts-scope.js
  2. +62 −0 demo/demo-sts.js
  3. +42 −17 demo/demo.js
  4. +0 −109 demo/sts.js
  5. +7 −4 package.json
  6. +30 −28 sdk/advance.js
  7. +367 −101 sdk/base.js
  8. +11 −3 sdk/cos.js
  9. +27 −22 sdk/task.js
  10. +142 −111 sdk/util.js
  11. +1,302 −0 test/csp.js
  12. +1,171 −695 test/test.js
73 changes: 73 additions & 0 deletions demo/demo-sts-scope.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* 使用临时密钥例子
*/
var STS = require('qcloud-cos-sts');
var COS = require('../index');
var config = require('./config');

var allowPrefix = '';
// 简单上传和分片,需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/14048
var allowActions = [
'name/cos:PutObject',
'name/cos:InitiateMultipartUpload',
'name/cos:ListMultipartUploads',
'name/cos:ListParts',
'name/cos:UploadPart',
'name/cos:CompleteMultipartUpload'
];


// 判断是否允许获取密钥
var allowScope = function (scope) {
var allow = (scope || []).every(function (item) {
return allowActions.includes(item.action) &&
item.bucket === config.bucket &&
item.region === config.region &&
(item.prefix || '').startsWith(allowPrefix);
});
return allow;
};

var cos = new COS({
getAuthorization: function (options, callback) {

if (!allowScope()) {
console.log('deny Scope');
return;
}

// 获取临时密钥
var policy = STS.getPolicy(options.Scope);
STS.getCredential({
secretId: config.SecretId,
secretKey: config.SecretKey,
policy: policy,
// durationSeconds: 1800,
proxy: '',
}, function (err, data) {
if (err) {
console.error(err);
} else {
console.log(data);
var credentials = data.credentials;
callback({
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
XCosSecurityToken: credentials.sessionToken,
ExpiredTime: data.expiredTime,
ScopeLimit: true, // 设为 true 可限制密钥只在相同请求可重用,默认不限制一直可重用,细粒度控制权限需要设为 true
});
}
});

},
});

cos.putObject({
Bucket: config.Bucket,
Region: config.Region,
Key: 'dir/1.txt',
Body: 'hello!',
}, function (err, data) {
console.log(err || data);
});
62 changes: 62 additions & 0 deletions demo/demo-sts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* 使用临时密钥例子
*/
var STS = require('qcloud-cos-sts');
var COS = require('../index');
var config = require('./config');


var LongBucketName = config.Bucket;
var ShortBucketName = LongBucketName.substr(0, LongBucketName.indexOf('-'));
var AppId = LongBucketName.substr(LongBucketName.indexOf('-') + 1);
var policy = {
'version': '2.0',
'statement': [{
'action': [
'name/cos:PutObject',
'name/cos:InitiateMultipartUpload',
'name/cos:ListMultipartUploads',
'name/cos:ListParts',
'name/cos:UploadPart',
'name/cos:CompleteMultipartUpload'
],
'effect': 'allow',
'principal': {'qcs': ['*']},
'resource': [
'qcs::cos:ap-guangzhou:uid/' + AppId + ':prefix//' + AppId + '/' + ShortBucketName + '/dir/*'
]
}]
};

var cos = new COS({
getAuthorization: function (options, callback) {
STS.getCredential({
secretId: config.SecretId,
secretKey: config.SecretKey,
policy: policy,
durationSeconds: 7200,
proxy: '',
}, function (err, data) {
if (err) {
console.error(err);
} else {
var credentials = data.credentials;
callback({
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
XCosSecurityToken: credentials.sessionToken,
ExpiredTime: data.expiredTime,
});
}
});
},
});

cos.putObject({
Bucket: config.Bucket,
Region: config.Region,
Key: 'dir/1.txt',
Body: 'hello!',
}, function (err, data) {
console.log(err || data);
});
59 changes: 42 additions & 17 deletions demo/demo.js
Original file line number Diff line number Diff line change
@@ -13,7 +13,8 @@ var cos = new COS({
// 可选参数
FileParallelLimit: 3, // 控制文件上传并发数
ChunkParallelLimit: 8, // 控制单个文件下分片上传并发数,在同园区上传可以设置较大的并发数
ChunkSize: 1024 * 1024, // 控制分片大小,单位 B,在同园区上传可以设置较大的分片大小
ChunkSize: 1024 * 1024 * 8, // 控制分片大小,单位 B,在同园区上传可以设置较大的分片大小
Proxy: '',
});
var TaskId;

@@ -300,17 +301,39 @@ function putBucketLifecycle() {
Bucket: config.Bucket, // Bucket 格式:test-1250000000
Region: config.Region,
LifecycleConfiguration: {
"Rules": [{
'ID': 1,
'Filter': {
'Prefix': 'cas',
Rules: [{
"ID": "1",
"Status": "Enabled",
"Filter": {},
"Transition": {
"Days": "30",
"StorageClass": "STANDARD_IA"
}
}, {
"ID": "2",
"Status": "Enabled",
"Filter": {
"Prefix": "dir/"
},
'Status': 'Enabled',
'Transition': {
'Days': 0,
'StorageClass': 'ARCHIVE'
"Transition": {
"Days": "90",
"StorageClass": "ARCHIVE"
}
}]
}, {
"ID": "3",
"Status": "Enabled",
"Filter": {},
"Expiration": {
"Days": "180"
}
}, {
"ID": "4",
"Status": "Enabled",
"Filter": {},
"AbortIncompleteMultipartUpload": {
"DaysAfterInitiation": "30"
}
}],
}
}, function (err, data) {
console.log(err || data);
@@ -361,7 +384,8 @@ function listObjectVersions() {
cos.listObjectVersions({
Bucket: config.Bucket, // Bucket 格式:test-1250000000
Region: config.Region,
Prefix: "1mb.zip"
// Prefix: "",
// Delimiter: '/'
}, function (err, data) {
console.log(err || JSON.stringify(data, null, ' '));
});
@@ -373,14 +397,15 @@ function putBucketReplication() {
Bucket: config.Bucket, // Bucket 格式:test-1250000000
Region: config.Region,
ReplicationConfiguration: {
Role: "qcs::cam::uin/459000000:uin/459000000",
Role: "qcs::cam::uin/10001:uin/10001",
Rules: [{
ID: "1",
Status: "Enabled",
Prefix: "img/",
Prefix: "sync/",
Destination: {
Bucket: "qcs::cos:ap-guangzhou::test-" + AppId
},
Bucket: "qcs:id/0:cos:ap-chengdu:appid/" + AppId + ":backup",
// StorageClass: "Standard",
}
}]
}
}, function (err, data) {
@@ -414,7 +439,7 @@ function deleteBucket() {
console.log(err || data);
});
}

return putObject();
function putObject() {
// 创建测试文件
var filename = '1mb.zip';
@@ -556,7 +581,7 @@ function deleteMultipleObject() {
Region: config.Region,
Objects: [
{Key: '中文/中文.txt'},
{Key: '中文/中文.zip'},
{Key: '中文/中文.zip',VersionId: 'MTg0NDY3NDI1MzM4NzM0ODA2MTI'},
]
}, function (err, data) {
console.log(err || data);
109 changes: 0 additions & 109 deletions demo/sts.js

This file was deleted.

11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
{
"name": "cos-nodejs-sdk-v5",
"version": "2.4.10",
"version": "2.5.0",
"description": "cos nodejs sdk v5",
"main": "index.js",
"scripts": {
"demo": "node demo/demo.js",
"test": "mocha"
"demo-sts": "node demo/demo-sts.js",
"demo-sts-scope": "node demo/demo-sts-scope.js",
"test": "mocha test/test.js",
"csp": "mocha test/csp.js"
},
"repository": {
"type": "git",
@@ -26,11 +29,11 @@
"homepage": "https://github.com/tencentyun/cos-nodejs-sdk-v5#readme",
"dependencies": {
"configstore": "^3.1.2",
"qcloudapi-sdk": "^0.2.0",
"request": "^2.81.0",
"xml2js": "^0.4.19"
},
"devDependencies": {
"mocha": "^4.0.1"
"mocha": "^4.0.1",
"qcloud-cos-sts": "^2.0.5"
}
}
58 changes: 30 additions & 28 deletions sdk/advance.js
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ var util = require('./util');

// 文件分块上传全过程,暴露的分块上传接口
function sliceUploadFile(params, callback) {
var self = this;
var ep = new EventProxy();
var TaskId = params.TaskId;
var Bucket = params.Bucket;
@@ -16,7 +17,6 @@ function sliceUploadFile(params, callback) {
var StorageClass = params.StorageClass || 'Standard';
var ServerSideEncryption = params.ServerSideEncryption;
var FileSize;
var self = this;

var onProgress;
var onHashProgress = params.onHashProgress;
@@ -135,21 +135,20 @@ function sliceUploadFile(params, callback) {
var AutoChunkSize = 1024 * 1024;
for (var i = 0; i < SIZE.length; i++) {
AutoChunkSize = SIZE[i] * 1024 * 1024;
if (FileSize / AutoChunkSize < 10000) break;
if (FileSize / AutoChunkSize <= self.options.MaxPartNumber) break;
}
params.ChunkSize = params.SliceSize = ChunkSize = Math.max(ChunkSize, AutoChunkSize);
})();
onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);

// 开始上传
if (FileSize === 0) {
params.Body = '';
params.ContentLength = 0;
params._OnlyUploadNotAddTask = true;
self.putObject(params, function (err, data) {
if (err) {
onProgress(null, true);
return callback(err);
}
onProgress({loaded: FileSize, total: FileSize}, true);
callback(null, data);
});
} else {
@@ -957,7 +956,7 @@ function sliceCopyFile(params, callback) {
var Region = params.Region;
var Key = params.Key;
var CopySource = params.CopySource;
var m = CopySource.match(/^([^.]+-\d+)\.cos\.([^.]+)\.myqcloud\.com\/(.+)$/);
var m = CopySource.match(/^([^.]+-\d+)\.cos\.([^.]+)\.[^/]+\/(.+)$/);
if (!m) {
callback({error: 'CopySource format error'});
return;
@@ -1016,7 +1015,7 @@ function sliceCopyFile(params, callback) {
}
},function (err,data) {
if (err) {
return callback(err);
return asyncCallback(err);
}
onProgress({loaded: FinishSize, total: FileSize});

@@ -1030,7 +1029,7 @@ function sliceCopyFile(params, callback) {
return callback(err);
}

ep.emit('copy_slice_complete',UploadData);
ep.emit('copy_slice_complete', UploadData);
});
});

@@ -1041,7 +1040,7 @@ function sliceCopyFile(params, callback) {
var AutoChunkSize = 1024 * 1024;
for (var i = 0; i < SIZE.length; i++) {
AutoChunkSize = SIZE[i] * 1024 * 1024;
if (FileSize / AutoChunkSize < 10000) break;
if (FileSize / AutoChunkSize <= self.options.MaxPartNumber) break;
}
params.ChunkSize = ChunkSize = Math.max(ChunkSize, AutoChunkSize);

@@ -1082,35 +1081,35 @@ function sliceCopyFile(params, callback) {
Key: SourceKey,
},function(err, data) {
if (err) {
if (err.statusCode && err.statusCode === 404) {
return callback({ ErrorStatus: SourceKey + ' Not Exist' });
} else {
callback(err);
}
return;
if (err.statusCode && err.statusCode === 404) {
callback({ErrorStatus: SourceKey + ' Not Exist'});
} else {
callback(err);
}
return;
}

FileSize = params.FileSize = data.headers['content-length'];
onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);

// 开始上传
if (FileSize <= CopySliceSize) {
self.putObjectCopy(params, function (err, data) {
if (err) {
onProgress(null, true);
return callback(err);
}
onProgress({loaded: FileSize, total: FileSize}, true);
callback(err, data);
});
self.putObjectCopy(params, function (err, data) {
if (err) {
onProgress(null, true);
return callback(err);
}
onProgress({loaded: FileSize, total: FileSize}, true);
callback(err, data);
});
} else {
ep.emit('get_file_size_finish');
ep.emit('get_file_size_finish');
}
});
}

// 复制指定分片
function copySliceItem(params,callback) {
function copySliceItem(params, callback) {
var TaskId = params.TaskId;
var Bucket = params.Bucket;
var Region = params.Region;
@@ -1150,6 +1149,9 @@ var API_MAP = {
sliceCopyFile: sliceCopyFile,
};

util.each(API_MAP, function (fn, apiName) {
exports[apiName] = util.apiWrapper(apiName, fn);
});
module.exports.init = function (COS, task) {
task.transferToTaskMethod(API_MAP, 'sliceUploadFile');
util.each(API_MAP, function (fn, apiName) {
COS.prototype[apiName] = util.apiWrapper(apiName, fn);
});
};
468 changes: 367 additions & 101 deletions sdk/base.js

Large diffs are not rendered by default.

14 changes: 11 additions & 3 deletions sdk/cos.js
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ var defaultOptions = {
AppId: '', // AppId 已废弃,请拼接到 Bucket 后传入,例如:test-1250000000
SecretId: '',
SecretKey: '',
XCosSecurityToken: '',
FileParallelLimit: 3,
ChunkParallelLimit: 3,
ChunkRetryTimes: 3,
@@ -19,12 +20,17 @@ var defaultOptions = {
CopyChunkParallelLimit: 20,
CopyChunkSize: 1024 * 1024 * 10,
CopySliceSize: 1024 * 1024 * 10,
MaxPartNumber: 10000,
ProgressInterval: 1000,
UploadQueueSize: 10000,
Domain: '',
ServiceDomain: '',
Protocol: '',
IgnoreRegionFormat: false,
CompatibilityMode: false,
ForcePathStyle: false,
UseRawKey: false,
Timeout: 0, // 单位毫秒,0 代表不设置超时时间
UploadCheckContentMd5: false,
UploadIdCacheLimit: 500,
Proxy: '',
UserAgent: '',
@@ -40,15 +46,17 @@ var COS = function (options) {
this.options.CopyChunkParallelLimit = Math.max(1, this.options.CopyChunkParallelLimit);
this.options.CopyChunkSize = Math.max(1024 * 1024, this.options.CopyChunkSize);
this.options.CopySliceSize = Math.max(0, this.options.CopySliceSize);
this.options.MaxPartNumber = Math.max(1024, Math.min(10000, this.options.MaxPartNumber));
this.options.Timeout = Math.max(0, this.options.Timeout);
if (this.options.AppId) {
console.warn('warning: AppId has been deprecated, Please put it at the end of parameter Bucket(E.g: "test-1250000000").');
}
event.init(this);
task.init(this);
};

util.extend(COS.prototype, base);
util.extend(COS.prototype, advance);
base.init(COS, task);
advance.init(COS, task);

COS.getAuthorization = util.getAuth;
COS.version = pkg.version;
49 changes: 27 additions & 22 deletions sdk/task.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
var util = require('./util');

var originApiMap = {};
var transferToTaskMethod = function (apiMap, apiName) {
originApiMap[apiName] = apiMap[apiName];
apiMap[apiName] = function (params, callback) {
if (params._OnlyUploadNotAddTask) {
originApiMap[apiName].call(this, params, callback);
} else {
this._addTask(apiName, params, callback);
}
};
};

var initTask = function (cos) {

var queue = [];
var tasks = {};
var uploadingFileCount = 0;
var nextUploadIndex = 0;

var originApiMap = {};

// 把上传方法替换成添加任务的方法
util.each([
'putObject',
'sliceUploadFile',
], function (api) {
originApiMap[api] = cos[api];
cos[api] = function (params, callback) {
cos._addTask(api, params, callback);
};
});

// 接口返回简略的任务信息
var formatTask = function (task) {
var t = {
@@ -53,7 +52,8 @@ var initTask = function (cos) {
uploadingFileCount++;
task.state = 'checking';
!task.params.UploadData && (task.params.UploadData = {});
originApiMap[task.api].call(cos, task.params, function (err, data) {
var apiParams = util.formatParams(task.api, task.params);
originApiMap[task.api].call(cos, apiParams, function (err, data) {
if (!cos._isRunningTask(task.id)) return;
if (task.state === 'checking' || task.state === 'uploading') {
task.state = err ? 'error' : 'success';
@@ -111,7 +111,7 @@ var initTask = function (cos) {
cos._addTask = function (api, params, callback, ignoreAddEvent) {

// 复制参数对象
params = util.extend({}, params);
params = util.formatParams(api, params);

// 生成 id
var id = util.uuid();
@@ -155,18 +155,22 @@ var initTask = function (cos) {
onProgress && onProgress(info);
emitListUpdate();
};
queue.push(task);
if (queue.length > cos.options.UploadQueueSize) {
queue.splice(0, queue.length - cos.options.UploadQueueSize);
}
tasks[id] = task;

// 异步获取 filesize
util.getFileSize(api, params, function (err, size) {
if (err) {
// 开始处理上传
if (err) { // 如果获取大小出错,不加入队列
callback(err);
return;
}
// 获取完文件大小再把任务加入队列
tasks[id] = task;
queue.push(task);
if (queue.length > cos.options.UploadQueueSize) {
var delta = queue.length - cos.options.UploadQueueSize;
queue.splice(0, delta);
nextUploadIndex -= delta;
}
task.size = size;
!ignoreAddEvent && emitListUpdate();
startNextTask(cos);
@@ -198,4 +202,5 @@ var initTask = function (cos) {

};

module.exports.init = initTask;
module.exports.transferToTaskMethod = transferToTaskMethod;
module.exports.init = initTask;
253 changes: 142 additions & 111 deletions sdk/util.js

Large diffs are not rendered by default.

1,302 changes: 1,302 additions & 0 deletions test/csp.js

Large diffs are not rendered by default.

1,866 changes: 1,171 additions & 695 deletions test/test.js

Large diffs are not rendered by default.