Comparing version 1.0.2 to 1.1.0
@@ -18,24 +18,12 @@ var KS3 = require('..'); | ||
function put () { | ||
client.bucket.put({Bucket: 'test'}, cb) | ||
client.bucket.put({Bucket: 'test-abc'}, cb) | ||
} | ||
function listMultipartUploads () { | ||
client.bucket.listMultipartUploads({ | ||
Bucket: bucketName, | ||
'max-uploads': 3 | ||
}, function (err, data, cb) { | ||
console.log('=====> err:', err) | ||
console.log('========> data:', data) | ||
const d = xml2json.parser(data) | ||
console.log('========> 转后的json:', JSON.stringify(d)) | ||
}) | ||
} | ||
function query () { | ||
client.bucket.get({ | ||
Bucket: 'ks3-sdk-test' || bucketName, | ||
// delimiter: "/", | ||
// marker: "", | ||
// 'max-keys': 10, | ||
// prefix: "" | ||
Bucket: bucketName, | ||
Delimiter: "/", | ||
Marker: "", | ||
MaxKeys: 10, | ||
Prefix: "" | ||
}, cb) | ||
@@ -56,3 +44,3 @@ } | ||
function getBucketLocation () { | ||
client.bucket.getBucketLocation(cb) | ||
client.bucket.getLocation(cb) | ||
} | ||
@@ -74,3 +62,2 @@ | ||
} | ||
client.bucket.putBucketCors() | ||
client.bucket.putBucketCors(params, cb) | ||
@@ -178,3 +165,3 @@ } | ||
put() | ||
// put() | ||
@@ -208,5 +195,5 @@ // head() | ||
// putBucketLifecycle() | ||
// getBucketLifecycle() | ||
// deleteBucketLifecycle() | ||
// putBucketLifecycle() | ||
@@ -213,0 +200,0 @@ // getLogging() |
var KS3 = require('..'); | ||
var xml2json = require("../lib/util").xml2json; | ||
const { ak, sk, bucketName, region } = require('./const'); | ||
const { ak, sk, bucketName, endpoint } = require('./const'); | ||
@@ -9,6 +9,8 @@ const client = new KS3({ | ||
bucket: bucketName, | ||
endpoint: 'ks3-cn-shanghai.ksyuncs.com', | ||
endpoint: endpoint, | ||
timeout: 6000, | ||
secure: true | ||
// secure: true | ||
}); | ||
module.exports = { | ||
@@ -15,0 +17,0 @@ xml2json, |
@@ -5,6 +5,5 @@ require('dotenv').config() | ||
// var region = 'BEIJING' || '<your region>'; // replace your region | ||
var bucketName = process.env.bucketName || '<BUCKE_TNAME>'; // input your bucketname | ||
var bucketName = process.env.bucketName || 'test-bucket' || '<BUCKE_TNAME>'; // input your bucketname | ||
var region = process.env.regionName || 'BEIJING'; // replace your region | ||
var endpoint = process.env.endpoint || 'ks3-cn-beijing.ksyuncs.com'; // replace your region | ||
@@ -16,4 +15,4 @@ var krn = process.env.KRN || '' // replace your rolekrn | ||
bucketName, | ||
region, | ||
endpoint, | ||
krn | ||
} |
@@ -22,3 +22,3 @@ | ||
console.log('==========> err:', err) | ||
console.log('==========> data:', data) | ||
console.log('==========> data:', JSON.stringify(data)) | ||
console.log('==========> statusCode:', res.statusCode) | ||
@@ -50,6 +50,9 @@ console.log('==========> body:', body) | ||
function upload () { | ||
const initParams = { Key: key, Bucket: bucketName } | ||
const headers = { | ||
'x-kss-server-side-encryption': 'AES256' | ||
} | ||
const initParams = { Key: key, Bucket: bucketName, headers } | ||
client.object.multitpart_upload_init( initParams, function(err, data, res) { | ||
data = util.xml2json.parser(data) | ||
// data = util.xml2json.parser(data) | ||
@@ -82,5 +85,9 @@ uploadId = data.InitiateMultipartUploadResult.UploadId | ||
body: buffer, | ||
type: contentType | ||
type: contentType, | ||
headers | ||
} | ||
console.log('分块上传参数:', params) | ||
client.config({ | ||
isDebug: true | ||
}) | ||
client.object.upload_part(params, function(err, data, res) { | ||
@@ -110,3 +117,4 @@ if (err) { | ||
UploadId: uploadId, | ||
body: util.generateCompleteXML(etags) | ||
body: util.generateCompleteXML(etags), | ||
headers | ||
} | ||
@@ -154,5 +162,5 @@ console.log('合并参数:', params) | ||
destinationBucket: bucketName, | ||
destinationObject: 'dat-copy', | ||
destinationObject: 'copy-sse-s3-a.mp4', | ||
sourceBucket: bucketName, | ||
sourceKey: 'dat' | ||
sourceKey: 'new-sse-s3-a.mp4' | ||
}, cb) | ||
@@ -174,4 +182,4 @@ } | ||
// Bucket: bucketName, | ||
Key: 'word.txt', | ||
newKey: 'word-rename.txt' | ||
Key: 'sse-s3-a.mp4', | ||
newKey: 'new-sse-s3-a.mp4' | ||
}, cb) | ||
@@ -183,13 +191,22 @@ } | ||
Bucket: bucketName, | ||
Key: '12-rename.jpg', | ||
storageClass: 'STANDARD_IA' | ||
}, ) | ||
Key: 'sse-s3-a.mp4', | ||
storageClass: 'STANDARD' | ||
}, cb) | ||
} | ||
var key = "stream.mp4" | ||
function getACLType () { | ||
client.object.getACLType({ | ||
Bucket: bucketName, | ||
Key: key, | ||
}, cb) | ||
} | ||
function generateUrl () { | ||
client.object.generatePresignedUrl({ | ||
Bucket: bucketName, | ||
Key: '111()~!\'.jpg', | ||
expiration: 5 * 60 | ||
Key: key, | ||
Expiration: 5 * 60 | ||
}, function (res, data) { | ||
@@ -200,25 +217,26 @@ console.log('url: ', data) | ||
function headObject () { | ||
client.object.head({ | ||
// 生成上传外链 | ||
function generateUploadUrl () { | ||
client.config({ | ||
isDebug: true | ||
}) | ||
client.object.generatePresignedUrl({ | ||
Bucket: bucketName, | ||
Key: '0831-1//14869.dat' | ||
}, function (err, data, res) { | ||
console.log('-------> err:', err) | ||
console.log('-------> data:', data) | ||
Key: key, | ||
Expiration: 5 * 60, | ||
Method: 'PUT' | ||
}, function (err, data) { | ||
console.log(data) | ||
}) | ||
} | ||
function getAcl () { | ||
client.object.getAcl({ | ||
Bucket: bucketName, | ||
Key: '0831-1/moon.jpg' | ||
}, function (err, data, res) { | ||
console.log('-------> err:', err) | ||
console.log('-------> data:', data) | ||
}) | ||
Key: key | ||
}, cb) | ||
} | ||
key = '#####.png' | ||
// key = '#####.png' | ||
function head () { | ||
@@ -284,10 +302,35 @@ client.object.head({ | ||
function putStream () { | ||
const fout = fs.createReadStream(filePath) | ||
const stat = fs.statSync(filePath) | ||
client.object.put({ | ||
Key: 'stream.mp4', | ||
Body: fout | ||
Body: fout, | ||
headers: { | ||
'Content-Length': stat.size, | ||
'x-kss-server-side-encryption': 'AES256' | ||
} | ||
}, cb) | ||
} | ||
function putString () { | ||
var buf = new Buffer('<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><title>测试</title></head><body>testing page for gulp-ks3</body></html>'); | ||
client.object.put({ | ||
Key: 'put-string.html', | ||
Body: buf, | ||
headers: { | ||
'Content-Type':'text/html' | ||
} | ||
}, cb) | ||
} | ||
function putBuffer () { | ||
client.object.put({ | ||
Key: 'put-buffer', | ||
Body: new Buffer('this is a buffer content') | ||
}, cb) | ||
} | ||
// set callback | ||
@@ -338,5 +381,2 @@ function putCallBack () { | ||
var buf = new Buffer('<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><title>测试</title></head><body>testing page for gulp-ks3</body></html>'); | ||
client.config({ | ||
isDebug: true | ||
}) | ||
var key = 'test_buffer'; | ||
@@ -370,2 +410,3 @@ client.object.put({ | ||
}, function (err, data, res) { | ||
console.log(res.caseless.get('content-length')) | ||
console.log(data) | ||
@@ -375,22 +416,30 @@ }) | ||
// copy(); | ||
function encryptionSSES3 () { | ||
client.object.put({ | ||
FilePath: filePath, | ||
Key: 'sse-s3-a.mp4', | ||
ServerSideEncryption: 'AES256' | ||
}, cb) | ||
} | ||
// upload() | ||
copy(); | ||
// restore(); | ||
// rename(); | ||
// modifyStorageClass(); | ||
// getACLType(); | ||
// generateUrl(); | ||
// generateUploadUrl() | ||
// getAcl() | ||
// head() | ||
// putObjectTagging() | ||
// getObjectTagging() | ||
// deleteObjectTagging() | ||
// putObjectTagging() | ||
head() | ||
// putStream() | ||
// putString() | ||
// putBuffer() | ||
// putCallBack() | ||
// uploadByUrl() | ||
// getContentType() | ||
// getRangeData () | ||
// getRangeData () | ||
// encryptionSSES3() |
var { client, xml2json } = require('./client') | ||
function listBuckets () { | ||
client.config({ | ||
isDebug: true | ||
}) | ||
client.service.get(function (err, data, cb) { | ||
@@ -5,0 +8,0 @@ console.log('=====> err:', err) |
@@ -0,5 +1,12 @@ | ||
1.1.0/2022-07-25 | ||
================ | ||
- 统一参数大小写 | ||
0.5.1 / 2021-09-02 | ||
================== | ||
* 域名变更 ksyun.com -> ksyuncs.com | ||
* 域名变更 ksyun.com -> ksyuncs.com | ||
@@ -9,4 +16,4 @@ 0.4.0 / 2016-08-05 | ||
* 导出签名(auth)接口(使用方法参见test/auth.js的AUTH generateToken测试) | ||
* 增加测试覆盖率统计(coverage.html) | ||
* 导出签名(auth)接口(使用方法参见test/auth.js的AUTH generateToken测试) | ||
* 增加测试覆盖率统计(coverage.html) | ||
@@ -16,17 +23,15 @@ 0.3.8 / 2016-06-02 | ||
* 修复上传文件夹设置acl无效问题 | ||
* 更新sdk默认region为北京 | ||
* 修复上传文件夹设置acl无效问题 | ||
* 更新sdk默认region为北京 | ||
0.3.7 / 2016-06-01 | ||
================== | ||
* 上传模块优化(根据文件大小自动选择put上传或分块上传) | ||
* 命令行工具文档更新 | ||
* 上传模块优化(根据文件大小自动选择put上传或分块上传) | ||
* 命令行工具文档更新 | ||
0.3.6 / 2016-03-22 | ||
================== | ||
* 命令行工具支持设置region | ||
* 命令行工具支持设置region | ||
@@ -36,4 +41,4 @@ 0.3.5 / 2016-03-04 | ||
* 文档更新 | ||
* 问题修复 | ||
* 文档更新 | ||
* 问题修复 | ||
@@ -43,4 +48,4 @@ 0.3.0 / 2016-03-03 | ||
* 支持美国和上海region | ||
* 更新travis配置 | ||
* 支持美国和上海region | ||
* 更新travis配置 | ||
@@ -50,4 +55,4 @@ 0.2.0 / 2016-02-17 | ||
* 支持设置不同region(通过KS3构造函数的region参数) | ||
* 增加上传测试用例 | ||
* 支持设置不同region(通过KS3构造函数的region参数) | ||
* 增加上传测试用例 | ||
@@ -57,3 +62,3 @@ 0.1.0 / 2016-01-27 | ||
* 增加若干测试用例 | ||
* 增加若干测试用例 | ||
@@ -63,3 +68,3 @@ 0.0.6 / 2015-11-30 | ||
* fix bugs | ||
* fix bugs | ||
@@ -69,2 +74,2 @@ 0.0.1 / 2014-11-06 | ||
* init | ||
* init |
@@ -6,10 +6,9 @@ var auth = require('./../auth'); | ||
* 创建单个Bucket | ||
* @param {object} params | ||
* { | ||
* Bucket: '' | ||
* ACL: '', // bucket权限设置 ['private' || 'public-read' || 'public-read-write' || 'authenticated-read'] | ||
* Type: '', // bucket存储类型 ['NORMAL' || 'ARCHIVE'] | ||
* Region: '', // bucket存储region ['BEIJING' || 'SHANGHAI' || 'HONGKONG' || 'GUANGZHOU' || 'RUSSIA' || 'SINGAPORE'] | ||
* ProjectId: '' // 项目组id | ||
* } | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket | ||
* @param {String} params.ACL bucket权限设置 ['private' || 'public-read' || 'public-read-write' || 'authenticated-read'] | ||
* @param {String} params.Type bucket存储类型 ['NORMAL' || 'ARCHIVE'] | ||
* @param {String} params.Region bucket存储region ['BEIJING' || 'SHANGHAI' || 'HONGKONG' || 'GUANGZHOU' || 'RUSSIA' || 'SINGAPORE'] | ||
* @param {String} params.ProjectId 项目组id 非必填 | ||
*/ | ||
@@ -23,22 +22,4 @@ function put(params, cb) { | ||
var bucketName = params && params.Bucket ? params.Bucket : this.bucketName; | ||
var baseUrl = params && params.Region ? config.ENDPOINT[params.Region] : config.baseUrl; | ||
var req = _getBucketRequestParams.call(this, '', 'PUT', params) | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} else if(!util.verifyBucket(bucketName)) { | ||
throw new Error('the illegal bucketName'); | ||
} | ||
var date = (new Date()).toUTCString(); | ||
var resource = '/'; | ||
var req = { | ||
method: 'PUT', | ||
date: date, | ||
uri: config.protocol + '://' + bucketName + '.' + baseUrl + resource + (params.ProjectId ? '?projectId=' + params.ProjectId : ''), // projectId不计入签名 | ||
resource: '/' + bucketName + resource, | ||
type: '', | ||
headers: {} | ||
} | ||
if(params && params.ACL) { | ||
@@ -85,11 +66,9 @@ var acl = params.ACL; | ||
* 获取bucket下的objects | ||
* params | ||
* { | ||
* Bucket: '', // 非必传 | ||
* delimiter: '', | ||
* 'encoding-type': '', | ||
* maker: '', | ||
* 'max-keys': 0, // 默认为1000 | ||
* prefix: '', | ||
* } | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket // 非必传 | ||
* @param {String} params.Delimiter | ||
* @param {String} params.Marker | ||
* @param {String} params.MaxKeys // 默认为1000 | ||
* @param {String} params.Prefix | ||
* | ||
@@ -103,2 +82,11 @@ */ | ||
} else { | ||
var opts = {} | ||
opts['prefix'] = params['Prefix'] || params.prefix || ''; | ||
opts['delimiter'] = params['Delimiter'] || params.delimiter || ''; | ||
opts['marker'] = params['Marker'] || params.marker || ''; | ||
opts['max-keys'] = params['MaxKeys'] || params['max-keys'] || 1000; | ||
opts['encoding-type'] = params['EncodingType'] || params['encoding-type'] || ''; | ||
params = opts | ||
Object.keys(params).forEach(function(key) { | ||
@@ -110,3 +98,3 @@ if(key !== 'Bucket') { | ||
*/ | ||
if(!(key == 'delimiter' && params[key] =='')){ | ||
if(!(key == 'delimiter' && params[key] == '')){ | ||
queryString.push(key + '=' + encodeURIComponent(params[key])); | ||
@@ -117,19 +105,7 @@ } | ||
} | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var date = (new Date()).toUTCString(); | ||
var resource = '/'; | ||
var req = _getBucketRequestParams.call(this, '', 'GET', params) | ||
var req = { | ||
method: 'GET', | ||
date: date, | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '' | ||
} | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
var body = null; | ||
// 如果传入的params除了Bucket,还有其他的则,重新设置uri | ||
@@ -140,10 +116,10 @@ if(queryString.length > 0) { | ||
} | ||
this.request(req, body, curAuth, cb); | ||
this.request(req, null, curAuth, cb); | ||
} | ||
/** | ||
* 获取bucket权限 | ||
* params | ||
* { | ||
* Bucket: '' // 非必传 | ||
* } | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket | ||
* | ||
*/ | ||
@@ -155,18 +131,5 @@ function getACL(params, cb) { | ||
} | ||
var date = (new Date()).toUTCString(); | ||
var resource = '/?acl'; | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var req = { | ||
method: 'GET', | ||
date: date, | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '', | ||
dataType: 'json' | ||
} | ||
var req = _getBucketRequestParams.call(this, 'acl', 'GET', params) | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
@@ -178,2 +141,8 @@ var body = null; | ||
/** | ||
* 获取acl的类型 | ||
* | ||
* @param {*} params | ||
* @param {*} cb | ||
*/ | ||
function getACLType(params, cb){ | ||
@@ -184,5 +153,7 @@ if (typeof params === 'function') { | ||
} | ||
params.dataType = 'json' | ||
this.bucket.getACL(params, function(err, body, res){ | ||
if (err) { | ||
cb(err, body, res) | ||
cb(err, body, res, null) | ||
return | ||
@@ -205,3 +176,3 @@ } | ||
} | ||
cb(err, type, res) | ||
cb(err, type, res, null) | ||
}) | ||
@@ -212,11 +183,10 @@ } | ||
* 修改bucket权限 | ||
* params | ||
* { | ||
* Bucket: '' // 非必须 | ||
* ACL: 'private || public-read || public-read-write || authenticated-read || bucket-owner-read || bucket-owner-full-control' // 必须 | ||
* } | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {String} params.ACL 'private || public-read || public-read-write || authenticated-read || bucket-owner-read || bucket-owner-full-control' // 必须 | ||
* @param {function} cb | ||
*/ | ||
function putACL(params, cb) { | ||
var date = (new Date()).toUTCString(); | ||
var acl = params.ACL; | ||
@@ -230,16 +200,6 @@ if (!acl) { | ||
} | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var resource = '/?acl'; | ||
var req = _getBucketRequestParams.call(this, 'acl', 'PUT', params) | ||
var attr_Acl = 'x-'+config.prefix+'-acl'; | ||
var req = { | ||
method: 'PUT', | ||
date: date, | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '', | ||
headers:{} | ||
} | ||
req.headers[attr_Acl] = acl; | ||
@@ -252,6 +212,6 @@ var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
* 获取location | ||
* params | ||
* { | ||
* Bucket: '' // 非必须 | ||
* } | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {function} cb | ||
*/ | ||
@@ -263,17 +223,5 @@ function getLocation(params, cb) { | ||
} | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var date = (new Date()).toUTCString(); | ||
var resource = '/?location' | ||
var req = { | ||
method: 'GET', | ||
date: date, | ||
uri: config.protocol + '://'+bucketName+'.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '' | ||
} | ||
var req = _getBucketRequestParams.call(this, 'location', 'GET', params) | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
@@ -286,6 +234,6 @@ var body = null; | ||
* 获取日志信息 | ||
* params | ||
* { | ||
* Bucket: '' // 非必须 | ||
* } | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {function} cb | ||
*/ | ||
@@ -297,17 +245,5 @@ function getLogging(params, cb) { | ||
} | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var date = (new Date()).toUTCString(); | ||
var resource = '/?logging' | ||
var req = _getBucketRequestParams.call(this, 'logging', 'GET', params) | ||
var req = { | ||
method: 'GET', | ||
date: date, | ||
uri: config.protocol + '://'+bucketName+'.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '' | ||
} | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
@@ -320,4 +256,7 @@ var body = null; | ||
* 日志信息设置 | ||
* @param {object} params - { Bucket , Logging } | ||
* | ||
* @param {object} params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {String} params.Logging { targetBucket, targetPrefix } // 可为空,若为空则为禁用日志 | ||
* @param {function} cb | ||
* @description | ||
@@ -331,7 +270,8 @@ * Logging: { targetBucket, targetPrefix } // 可为空,若为空则为禁用日志 | ||
} | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
params.type = 'text/xml' | ||
var req = _getBucketRequestParams.call(this, 'logging', 'PUT', params) | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
var Logging = params.Logging || null; | ||
@@ -351,15 +291,4 @@ // 默认关闭 | ||
var date = (new Date()).toUTCString(); | ||
var resource = '/?logging' | ||
var body = p | ||
var req = { | ||
method: 'PUT', | ||
date: date, | ||
uri: config.protocol + '://'+bucketName+'.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: 'text/xml' | ||
} | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
this.request(req, body, curAuth, cb); | ||
@@ -369,6 +298,7 @@ } | ||
* 删除Bucket(单个) | ||
* params | ||
* { | ||
* Bucket: '' // 非必传 | ||
* } | ||
* | ||
* @param {object} params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {function} cb | ||
* | ||
*/ | ||
@@ -380,15 +310,5 @@ function del(params, cb) { | ||
} | ||
var date = (new Date()).toUTCString(); | ||
var resource = '/' | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var req = { | ||
method: 'DELETE', | ||
date: date, | ||
uri: config.protocol + '://'+bucketName+'.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '' | ||
} | ||
var req = _getBucketRequestParams.call(this, '', 'DELETE', params) | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
@@ -401,6 +321,7 @@ var body = null; | ||
* 查看是否有权限操作bucket | ||
* params | ||
* { | ||
* Bucket: '' // 非必传 | ||
* } | ||
* | ||
* @param {object} params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {function} cb | ||
* | ||
*/ | ||
@@ -412,16 +333,5 @@ function headBucket(params, cb) { | ||
} | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var date = (new Date()).toUTCString(); | ||
var resource = '/'; | ||
var req = { | ||
method: 'HEAD', | ||
date: date, | ||
uri: config.protocol + '://'+bucketName+'.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '' | ||
} | ||
var req = _getBucketRequestParams.call(this, '', 'HEAD', params) | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
@@ -434,5 +344,14 @@ var body = null; | ||
* 获取当前bucket下的所有碎片 | ||
* @param {*} params { Bucket、delimiter、max-uploads、encoding-type ... } | ||
* @param {*} cb | ||
* | ||
* @param {object} params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {String} params.Delimiter | ||
* @param {String} params.MaxUploads | ||
* @param {String} params.EncodingType | ||
* @param {String} params.UploadIdMarker | ||
* @param {String} params.KeyMarker | ||
* @param {String} params.Prefix | ||
* @param {function} cb | ||
* @description 具体详见: https://docs.ksyun.com/documents/927 | ||
* | ||
*/ | ||
@@ -444,27 +363,18 @@ function listMultipartUploads (params, cb) { | ||
} | ||
var date = (new Date()).toUTCString(); | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
var req = _getBucketRequestParams.call(this, 'uploads', 'GET', params) | ||
delete params.Bucket | ||
var opts = {} | ||
opts['delimiter'] = params.Delimiter || params.delimiter || '' | ||
opts['encoding-type'] = params.EncodingType || params['encoding-type'] || '' | ||
opts['max-uploads'] = params.MaxUploads || params['max-uploads'] || '' | ||
opts['upload-id-marker'] = params.UploadIdMarker || params['upload-id-marker'] || '' | ||
opts['key-marker'] = params.KeyMarker || params['key-marker'] || '' | ||
opts['prefix'] = params.Prefix || params.prefix || '' | ||
const p = util.paramsEncode(params) | ||
const queryStr = '&' + util.paramsEncode(opts) | ||
var resource = '/?uploads'; | ||
var queryStr = resource | ||
if (p) { | ||
queryStr += '&' + p | ||
} | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var req = { | ||
method: 'GET', | ||
date: date, | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + queryStr, | ||
resource: '/' + bucketName + resource, | ||
type: '' | ||
} | ||
req.uri += queryStr | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
@@ -478,13 +388,11 @@ var body = null; | ||
* put bucket cors | ||
* @param {*} params { Rules, Bucket } | ||
* @param {*} cb | ||
* @description rule: { allowedMethod: '', allowedOrigin: [], allowedHeader: [], maxAgeSeconds: '', exposeHeader: '' } | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket | ||
* @param {String | Array } params.Rules | ||
* @param {function} cb | ||
* @description Rules: { allowedMethod: '', allowedOrigin: [], allowedHeader: [], maxAgeSeconds: '', exposeHeader: '' } | ||
*/ | ||
function putBucketCors (params, cb) { | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var rules = params.Rules | ||
@@ -509,16 +417,6 @@ if (!rules) { | ||
var resource = '/?cors'; | ||
var req = _getBucketRequestParams.call(this, 'cors', 'PUT', params) | ||
var body = util.convertToCORSXML(rules); | ||
var date = (new Date()).toUTCString(); | ||
var req = { | ||
method: 'PUT', | ||
date: date, | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '', | ||
headers: {} | ||
} | ||
if(body){ | ||
@@ -535,4 +433,6 @@ req.type = 'text/xml'; | ||
* get bucket cors | ||
* @param {*} params - { Bucket } | ||
* @param {*} cb | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket | ||
* @param {function} cb | ||
*/ | ||
@@ -545,22 +445,6 @@ function getBucketCors (params, cb) { | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
var req = _getBucketRequestParams.call(this, 'cors', 'GET', params) | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var resource = '/?cors'; | ||
var date = (new Date()).toUTCString(); | ||
var body = params; | ||
var req = { | ||
method: 'GET', | ||
date: date, | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '' | ||
} | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
this.request(req, body, curAuth, cb); | ||
this.request(req, '', curAuth, cb); | ||
} | ||
@@ -574,51 +458,16 @@ | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
var req = _getBucketRequestParams.call(this, 'cors', 'DELETE', params) | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var resource = '/?cors'; | ||
var date = (new Date()).toUTCString(); | ||
var body = params; | ||
var req = { | ||
method: 'DELETE', | ||
date: date, | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '' | ||
} | ||
var curAuth = auth.generateAuth(this.ak, this.sk, req); | ||
this.request(req, body, curAuth, cb); | ||
this.request(req, '', curAuth, cb); | ||
} | ||
function getReq (type, method, params) { | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var resource = `/?${type}`; | ||
var date = (new Date()).toUTCString(); | ||
var req = { | ||
method: method, | ||
date: date, | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '', | ||
headers: {} | ||
} | ||
return req; | ||
} | ||
/** | ||
* 配置复制规则 | ||
* @param {*} params { Rule, Bucket } | ||
* @param {*} cb | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket | ||
* @param {String} params.Rule | ||
* @param {function} cb | ||
* @description Rule: { prefix: '', deleteMarkerStatus: '', targetBucket: '' } | ||
@@ -645,6 +494,6 @@ */ | ||
if (!Rule.targetBucket) { | ||
throw new Error('targetBucket require the targetBucket') | ||
throw new Error('require the targetBucket') | ||
} | ||
const req = getReq.call(this, 'crr', 'PUT', params) | ||
const req = _getBucketRequestParams.call(this, 'crr', 'PUT', params) | ||
@@ -664,4 +513,5 @@ var body = util.convertToReplicationXML(params.Rule) | ||
* 获取复制规则 | ||
* @param {*} params | ||
* @param {*} cb | ||
* | ||
* @param {Object} params | ||
* @param {function} cb | ||
*/ | ||
@@ -674,3 +524,3 @@ function getBucketReplicationConfiguration (params, cb) { | ||
const req = getReq.call(this, 'crr', 'GET', params) | ||
const req = _getBucketRequestParams.call(this, 'crr', 'GET', params) | ||
@@ -685,4 +535,5 @@ var body = params; | ||
* 删除复制规则 | ||
* @param {*} params | ||
* @param {*} cb | ||
* | ||
* @param {Object} params | ||
* @param {function} cb | ||
*/ | ||
@@ -695,3 +546,3 @@ function deleteBucketReplicationConfiguration (params, cb) { | ||
const req = getReq.call(this, 'crr', 'DELETE', params) | ||
const req = _getBucketRequestParams.call(this, 'crr', 'DELETE', params) | ||
@@ -707,4 +558,7 @@ var body = params; | ||
* 创建或者更新镜像回源规则 | ||
* @param {*} params {Bucket, Mirror} | ||
* @param {*} cb | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket | ||
* @param {String} params.Mirror | ||
* @param {function} cb | ||
*/ | ||
@@ -720,3 +574,3 @@ function putBucketMirror (params, cb) { | ||
const req = getReq.call(this, 'mirror', 'PUT', params) | ||
const req = _getBucketRequestParams.call(this, 'mirror', 'PUT', params) | ||
@@ -735,4 +589,4 @@ var body = JSON.stringify(mirror); | ||
* 获取镜像回源规则 | ||
* @param {*} params | ||
* @param {*} cb | ||
* @param {Object} params | ||
* @param {function} cb | ||
*/ | ||
@@ -745,3 +599,3 @@ function getBucketMirror (params, cb) { | ||
const req = getReq.call(this, 'mirror', 'GET', params) | ||
const req = _getBucketRequestParams.call(this, 'mirror', 'GET', params) | ||
@@ -756,4 +610,4 @@ var body = params; | ||
* 删除镜像回源规则 | ||
* @param {*} params | ||
* @param {*} cb | ||
* @param {Object} params | ||
* @param {function} cb | ||
*/ | ||
@@ -766,3 +620,3 @@ function deleteBucketMirror (params, cb) { | ||
const req = getReq.call(this, 'mirror', 'DELETE', params) | ||
const req = _getBucketRequestParams.call(this, 'mirror', 'DELETE', params) | ||
@@ -778,4 +632,8 @@ var body = params; | ||
* 创建或者更新bucket policy | ||
* @param {*} params {Bucket, Policy } | ||
* @param {*} cb | ||
* | ||
* @param {*} params | ||
* @param {Object} params | ||
* @param {Object} params.Bucket | ||
* @param {Object} params.Policy | ||
* @param {function} cb | ||
*/ | ||
@@ -790,3 +648,3 @@ function putBucketPolicy (params, cb) { | ||
const req = getReq.call(this, 'policy', 'PUT', params) | ||
const req = _getBucketRequestParams.call(this, 'policy', 'PUT', params) | ||
@@ -805,4 +663,5 @@ var body = JSON.stringify(params.Policy); | ||
* 获取BucketPolicy配置 | ||
* @param {*} params | ||
* @param {*} cb | ||
* | ||
* @param {Object} params | ||
* @param {function} cb | ||
*/ | ||
@@ -815,3 +674,3 @@ function getBucketPolicy (params, cb) { | ||
const req = getReq.call(this, 'policy', 'GET', params) | ||
const req = _getBucketRequestParams.call(this, 'policy', 'GET', params) | ||
@@ -826,4 +685,5 @@ var body = params; | ||
* 删除空间的BucketPolicy配置 | ||
* @param {*} params | ||
* @param {*} cb | ||
* | ||
* @param {Object} params | ||
* @param {function} cb | ||
*/ | ||
@@ -836,3 +696,3 @@ function deleteBucketPolicy (params, cb) { | ||
const req = getReq.call(this, 'policy', 'DELETE', params) | ||
const req = _getBucketRequestParams.call(this, 'policy', 'DELETE', params) | ||
@@ -847,4 +707,7 @@ var body = params; | ||
* 设置bucket生命周期策略 | ||
* @param {*} params { Bucket, Rules } | ||
* @param {*} cb | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket | ||
* @param {String} params.Rules | ||
* @param {function} cb | ||
* @description | ||
@@ -885,5 +748,4 @@ * - Rules:规定的xml格式对等的json Array | ||
const req = _getBucketRequestParams.call(this, 'lifecycle', 'PUT', params) | ||
const req = getReq.call(this, 'lifecycle', 'PUT', params) | ||
var body = util.objToXml(fullParams); | ||
@@ -900,2 +762,8 @@ // console.log('json to xml : ', body) | ||
/** | ||
* 获取bucket的生命周期 | ||
* | ||
* @param {Object} params | ||
* @param {function} cb | ||
*/ | ||
function getBucketLifecycle (params, cb) { | ||
@@ -907,3 +775,3 @@ if (typeof params === 'function') { | ||
const req = getReq.call(this, 'lifecycle', 'GET', params) | ||
const req = _getBucketRequestParams.call(this, 'lifecycle', 'GET', params) | ||
@@ -918,4 +786,5 @@ var body = params; | ||
* 删除生命周期配置 | ||
* @param {*} params - { Bucket } | ||
* @param {*} cb | ||
* | ||
* @param {Object} params | ||
* @param {function} cb | ||
*/ | ||
@@ -928,3 +797,3 @@ function deleteBucketLifecycle (params, cb) { | ||
const req = getReq.call(this, 'lifecycle', 'DELETE', params) | ||
const req = _getBucketRequestParams.call(this, 'lifecycle', 'DELETE', params) | ||
@@ -937,2 +806,45 @@ var body = params; | ||
function _getBucketRequestParams (subres, method, params) { | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} else if(!util.verifyBucket(bucketName)) { | ||
throw new Error('the illegal bucketName'); | ||
} | ||
var queryStr = params.ProjectId ? '?projectId=' + params.ProjectId : '' | ||
var resource = '/' + (subres ? `?${subres}` : ''); | ||
var date = (new Date()).toUTCString(); | ||
var uri = config.protocol + '://' + bucketName + '.' + config.baseUrl + resource + queryStr | ||
// 是否是自定义域名 | ||
if (this.domainMode) { | ||
uri = config.protocol + '://' + config.baseUrl + resource + queryStr | ||
} | ||
const type = params.Type || params.type | ||
const dataType = params.DataType || params.dataType | ||
var req = { | ||
method: method, | ||
date: date, | ||
uri, | ||
resource: '/' + bucketName + resource, | ||
type: type || '', | ||
headers: {}, | ||
dataType: dataType || '' | ||
} | ||
if (this.timeout) { | ||
req.timeout = this.timeout | ||
} | ||
if (this.securityToken) req.headers['x-kss-security-token'] = this.securityToken | ||
return req; | ||
} | ||
module.exports = { | ||
@@ -950,2 +862,3 @@ put: put, | ||
listMultipartUploads, | ||
getBucketCors, | ||
@@ -952,0 +865,0 @@ putBucketCors, |
/*** | ||
* 命令行下载核心方法 | ||
* | ||
* @Decrepated 从v1.1.0开始废弃,将在v1.1.5中删除 | ||
* | ||
* 如果有命令行下载的需求,可自行实现。 | ||
* | ||
* @description 命令行工具-下载实现 | ||
@@ -32,2 +38,3 @@ */ | ||
function download(params, cb) { | ||
console.error('calling a decrepated methods!') | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
@@ -34,0 +41,0 @@ // 这个地方不能进行encode |
@@ -8,2 +8,4 @@ const requestPromise = require('request-promise') | ||
* 获取项目列表 | ||
* | ||
* @param {*} opts | ||
* @param opt - { protocol, domain, region, ak, sk } | ||
@@ -10,0 +12,0 @@ */ |
@@ -9,34 +9,22 @@ var auth = require('./../auth'); | ||
* 删除单个Object | ||
* params: { | ||
* | ||
* @param {object} params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {String} params.Key 必填 | ||
* @param {String} params.VersionId 非必填 | ||
* @param {function} cb - callback | ||
* @description | ||
* - params: { | ||
* Bucket: '', // 非必传 | ||
* Key: '' // Object Key 必须传 | ||
* VersionId: '' | ||
* VersionId: '' // 非必填 | ||
* } | ||
*/ | ||
function del(params, cb) { | ||
if (params.Key === null || params.Key === undefined) { | ||
throw new Error('require the Key'); | ||
} | ||
var key = util.encodeKey(params.Key); | ||
var resource = params.VersionId ? '/' + key + '?versionId=' + params.VersionId: '/' + key; | ||
// 转码 主要是为了处理没有名称的文件夹 | ||
resource = resource.replace('//', '/%2F') | ||
var req = _getObjectRequestParams.call(this, '', 'DELETE', params) | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucket name'); | ||
} | ||
var req = { | ||
method: 'DELETE', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '' | ||
} | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
var body = null; | ||
this.request(req, body, authStr, cb); | ||
this.request(req, null, authStr, cb); | ||
} | ||
@@ -46,72 +34,83 @@ | ||
* 获取object | ||
* params: { | ||
* | ||
* @param {object} params - params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {String} params.Key 必填 | ||
* @param {String} params.VersionId 非必填 | ||
* @param {String} params.headers 非必填 | ||
* @param {function} cb - callback | ||
* @description | ||
* - params: { | ||
* Bucket: '', //非必传 | ||
* Key: '', // Object Key 必须传 | ||
* headers: { Range: ''} | ||
* VersionId: '' // 非必填 | ||
* headers: { Range: ''} 非必填 | ||
* } | ||
*/ | ||
function get(params, cb) { | ||
if (params.Key === null || params.Key === undefined) { | ||
throw new Error('require the Key'); | ||
} | ||
var resource = '/' + util.encodeKey(params.Key); | ||
// 转码 主要是为了处理没有名称的文件夹 | ||
resource = resource.replace('//', '/%2F') | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucket name'); | ||
} | ||
var req = { | ||
method: 'GET', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: {}, | ||
isOnprogress: params.isOnprogress, | ||
dataType: 'application/octet-stream' // 下载文件时 为了防止数据源被解析特意设置 | ||
}; | ||
var req = _getObjectRequestParams.call(this, '', 'GET', params) | ||
req.dataType = 'application/octet-stream' // 下载文件时 为了防止数据源被解析特意设置 | ||
var reRange = /^bytes=(\d+)-(\d+)$/i; | ||
var range = params.headers && params.headers.Range | ||
if(range!==''&& reRange.test(range)){ | ||
if(range!==''&& reRange.test(range)) { | ||
req.headers['Range'] = range; | ||
} | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
var body = null; | ||
return this.request(req, body, authStr, cb); | ||
const outputStream = this.request(req, null, authStr, cb); | ||
if (params.ReturnStream) return outputStream; | ||
} | ||
/** | ||
* download stream | ||
* | ||
* @param {*} params | ||
* @param {function} cb | ||
* @returns | ||
*/ | ||
function getObjectStream (params, cb) { | ||
params.ReturnStream = true | ||
return get.call(this, params, cb) | ||
} | ||
/** | ||
* 获取Object ACL | ||
* | ||
* @param {object} params - params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {String} params.Key 必填 | ||
* @param {String} params.VersionId 非必填 | ||
* @param {function} cb | ||
* params: { | ||
* Key: '' // Object Key 必须传 | ||
* Key: '', // Object Key 必须传 | ||
* VersionId: '' // 非必填 | ||
* } | ||
*/ | ||
function getAcl(params, cb) { | ||
if (params.Key === null || params.Key === undefined) { | ||
throw new Error('require the Key'); | ||
} | ||
var key = util.encodeKey(params.Key); | ||
var resource = params.VersionId ? '/' + key + '?ACL&versionId=' + params.VersionId: '/' + key + '?acl'; | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucket name'); | ||
} | ||
var req = { | ||
method: 'GET', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '', | ||
dataType: 'json' | ||
} | ||
var req = _getObjectRequestParams.call(this, 'acl', 'GET', params) | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
var body = null; | ||
this.request(req, body, authStr, cb); | ||
this.request(req, null, authStr, cb); | ||
} | ||
/** | ||
* 获取Object ACL type | ||
* | ||
* @param {object} params - params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {String} params.Key 必填 | ||
* @param {String} params.VersionId 非必填 | ||
* @param {function} cb | ||
* params: { | ||
* Key: '', // Object Key 必须传 | ||
* VersionId: '' // 非必填 | ||
* } | ||
*/ | ||
function getACLType(params, cb){ | ||
@@ -140,3 +139,12 @@ this.object.getAcl(params, function(err, body, res){ | ||
* 设置 Object ACL | ||
* params { | ||
* | ||
* @param {object} params - params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {String} params.Key 必填 | ||
* @param {String} params.VersionId 非必填 | ||
* @param {String} params.ACL 非必填 | ||
* @param {function} cb | ||
* | ||
* @description | ||
* - params { | ||
* Key: '', // Object Key 必须传 | ||
@@ -149,5 +157,2 @@ * VersionId: '', | ||
var ACL = params.ACL; | ||
if (params.Key === null || params.Key === undefined) { | ||
throw new Error('require the Key'); | ||
} | ||
if (!ACL) { | ||
@@ -159,27 +164,21 @@ throw new Error('require the permission'); | ||
} | ||
var key = util.encodeKey(params.Key); | ||
var resource = params.VersionId ? '/' + key + '?ACL&versionId=' + params.VersionId: '/' + key + '?acl'; | ||
var req = _getObjectRequestParams.call(this, 'acl', 'PUT', params) | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucket name'); | ||
} | ||
var req = { | ||
method: 'PUT', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: {} | ||
} | ||
var attr_Acl = 'x-' + config.prefix + '-acl'; | ||
req.headers[attr_Acl] = ACL; | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
var body = null; | ||
this.request(req, body, authStr, cb); | ||
this.request(req, null, authStr, cb); | ||
} | ||
/** | ||
* 获取指定object的元数据 | ||
* | ||
* @param {object} params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {String} params.Key 必填 | ||
* @param {String} params.VersionId 非必填 | ||
* @param {String} params.IfModifiedSince 非必填 | ||
* @param {function} cb | ||
* params { | ||
* Key: '' // 必须 | ||
* VersionId: '', | ||
* VersionId: '', // 非必填 | ||
* IfModifiedSince: ''// 指定时间后被修改,格式:格林尼治时间,如:'Wed, 13 Apr 2022 08:26:32 GMT' | ||
@@ -189,20 +188,4 @@ * } | ||
function headObject(params, cb) { | ||
if (params.Key === null || params.Key === undefined) { | ||
throw new Error('require the Key'); | ||
} | ||
var key = util.encodeKey(params.Key); | ||
var resource = params.VersionId ? '/' + key + '?versionId=' + params.VersionId: '/' + key; | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucket name'); | ||
} | ||
var req = { | ||
method: 'HEAD', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
type: '', | ||
headers: {} | ||
} | ||
var req = _getObjectRequestParams.call(this, '', 'HEAD', params) | ||
@@ -214,4 +197,4 @@ if (params.IfModifiedSince) { | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
var body = null; | ||
this.request(req, body, authStr, cb); | ||
this.request(req, null, authStr, cb); | ||
} | ||
@@ -221,10 +204,22 @@ | ||
* @function put方式上传Object | ||
* @param {*} params Bucket/Key/filePath/storageClass/Region/ACL,以及headers | ||
* @param {*} cb 结果回调 | ||
* | ||
* @param {*} params Bucket/Key/FilePath/StorageClass/ACL/VersionId/Body,以及headers | ||
* @param {object} params | ||
* @param {String} params.Bucket 非必填 | ||
* @param {String} params.Key 必填 | ||
* @param {String} params.FilePath | ||
* @param {String} params.StorageClass 非必填 | ||
* @param {String} params.ACL 非必填 | ||
* @param {Buffer|ReadStream|String} params.Body | ||
* @param {String} params.VersionId 非必填 | ||
* @param {String} params.headers 非必填 | ||
* @param {function} cb结果回调 | ||
* @returns | ||
* @description | ||
* 1、如需保证传输过程中没有损坏,需要设置Content-MD5,会影响性能,不推荐使用 | ||
* 2、如需在对象级别上加密,需要设置x-kss-server-side-encryption | ||
* 3、如需自定义加密, 需要设置x-kss-server-side-encryption-customer-key | ||
* 2、如需在服务端加密,需要设置ServerSideEncryption | ||
* 3、如需客户端加密, 需要设置SSECustomerAlgorithm、SSECustomerKey、SSECustomerKeyMD5 | ||
* 4、如果需要设置回调,回调详见文档:https://docs.ksyun.com/documents/956 | ||
* 5、为保持统一,将storageClass修改为StorageClass,大小写不影响 | ||
* 6、Body如果是stream,则content-length必须得传 | ||
* | ||
@@ -235,21 +230,13 @@ * 具体详见文档https://docs.ksyun.com/documents/960 | ||
function put(params, cb) { | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
var Key = util.encodeKey(params.Key) || null; | ||
var filePath = params.filePath || null; | ||
var filePath = params.filePath || params.FilePath || null; | ||
var headers = params.headers || {} | ||
if (!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
if (!Key) { | ||
throw new Error('require the object Key'); | ||
} | ||
var ak = this.ak; | ||
var sk = this.sk; | ||
var body = ''; | ||
var size = 0 | ||
// 传递的是 STRING 或者BUFFER | ||
// 传递的是 STRING 或者BUFFER {Buffer || ReadStream || String} | ||
if (!filePath) { | ||
body = params.Body || ''; | ||
if (util.isStream(body) && !headers['Content-Length']) { | ||
throw new Error("upload stream require headers['Content-Length'] ") | ||
} | ||
} else { // 传递的是文件路径 | ||
@@ -269,21 +256,9 @@ if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) { | ||
var subResource = params.subResource; | ||
var resource = '/' + Key + (subResource ? '?' + subResource : ''); | ||
// 转码 主要是为了处理没有名称的文件夹 | ||
resource = resource.replace('//', '/%2F') | ||
var req = _getObjectRequestParams.call(this, '', 'PUT', params) | ||
var req = { | ||
method: 'PUT', | ||
// 在上传文件的时候默认一个content-type | ||
type: params.isNoContent ? '': mime.lookup(Key), | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: headers, | ||
isOnprogress: params.isOnprogress | ||
} | ||
req.headers = Object.assign(req.headers, headers) | ||
// 如果手动设置content-type 则以设置为主 | ||
if (headers['Content-Type']) req.type = headers['Content-Type'] | ||
// 在上传文件的时候默认一个content-type | ||
if (!req.type) req.type = params.isNoContent ? '' : mime.lookup(params.Key) | ||
req.isOnprogress = params.isOnprogress | ||
@@ -296,3 +271,3 @@ var acl = params.ACL; | ||
var storageClass = params.storageClass | ||
var storageClass = params.storageClass || params.StorageClass | ||
if (storageClass && util.verifyStorageClass(storageClass)) { | ||
@@ -302,16 +277,4 @@ req.headers['x-kss-storage-class'] = params.storageClass | ||
const encrypt = params.headers && params.headers['x-kss-server-side-encryption'] | ||
if (encrypt) { | ||
if(encrypt != 'AES256') throw new Error('check your encrypt type, we now only support "AES256".') | ||
req.headers['x-kss-server-side-encryption'] = encrypt | ||
} | ||
const customerKey = params.headers && params.headers['x-kss-server-side-encryption-customer-key'] | ||
if (customerKey) { | ||
req.headers['x-kss-server-side-encryption'] = 'AES256' | ||
req.headers['x-kss-server-side-encryption-customer-key-MD5'] = util.getStringMd5(customerKey) | ||
} | ||
var authStr = auth.generateAuth(ak, sk, req, body); | ||
var authStr = auth.generateAuth(this.ak, this.sk, req, body); | ||
//console.log('req=========== :' + JSON.stringify(req)); | ||
return this.request(req, body, authStr, cb); | ||
@@ -326,29 +289,13 @@ | ||
/** | ||
* 初始化 | ||
* 初始化分块上传 | ||
* | ||
* @param {Object} params | ||
* @param {String} params.StorageClass | ||
* @param {String} params.ACL | ||
* @param {function} cb | ||
*/ | ||
var multitpart_upload_init = function(params, cb) { | ||
var ak = this.ak || ''; | ||
var sk = this.sk || ''; | ||
var bucketName = params.Bucket || this.bucketName || '';; | ||
var Key = util.encodeKey(params.Key) || null; | ||
if (!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var req = _getObjectRequestParams.call(this, 'uploads', 'POST', params) | ||
if (!Key) { | ||
throw new Error('require the object Key'); | ||
} | ||
var body = null; | ||
var resource = '/' + Key + '?uploads'; | ||
var req = { | ||
method: 'POST', | ||
// TODO: type:require('mime').lookup(key), | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: params.headers || {} | ||
} | ||
var acl = params.ACL; | ||
@@ -360,27 +307,26 @@ if (acl && util.verifyAcl(acl)) { | ||
var storageClass = params.storageClass | ||
var storageClass = params.storageClass || params.StorageClass | ||
if (storageClass && util.verifyStorageClass(storageClass)) { | ||
req.headers['x-kss-storage-class'] = params.storageClass | ||
req.headers['x-kss-storage-class'] = storageClass | ||
} | ||
var body = null | ||
// TODO: x-kss-meta | ||
var authStr = auth.generateAuth(ak, sk, req, body); | ||
var authStr = auth.generateAuth(this.ak, this.sk, req, body); | ||
this.request(req, body, authStr, cb); | ||
} | ||
/** | ||
* 上传分块 | ||
* | ||
* @param {Object} params | ||
* @param {String} params.PartNumber | ||
* @param {String} params.UploadId | ||
* @param {function} cb | ||
* @returns | ||
*/ | ||
function upload_part(params, cb){ | ||
var ak = this.ak || ''; | ||
var sk = this.sk || ''; | ||
var bucketName = params.Bucket || this.bucketName || '';; | ||
var key = util.encodeKey(params.Key)|| null; | ||
var contentType = params.type || ''; | ||
var partNumber = (typeof params.PartNumber!=='undefined') ?params.PartNumber: ''; | ||
var partNumber = (typeof params.PartNumber !== 'undefined') ? params.PartNumber: ''; | ||
var uploadId = params.UploadId || ''; | ||
if (!bucketName || !key) { | ||
throw new Error('require the bucketName and object key'); | ||
} | ||
if (partNumber==='' || !uploadId) { | ||
@@ -390,34 +336,23 @@ throw new Error('require the partNumber and uploadId'); | ||
params.resource = `?partNumber=${partNumber}&uploadId=${uploadId}` | ||
var req = _getObjectRequestParams.call(this, '', 'PUT', params) | ||
var body = params.body || ''; | ||
var resource = '/' + key + '?partNumber='+partNumber+'&uploadId='+uploadId; | ||
var req = { | ||
method: 'PUT', | ||
type:contentType, | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: {} | ||
} | ||
/** | ||
* TODO: encryption | ||
/**/ | ||
var authStr = auth.generateAuth(this.ak, this.sk, req, body); | ||
var authStr = auth.generateAuth(ak, sk, req, body); | ||
return this.request(req, body, authStr, cb); | ||
} | ||
/** | ||
* 合并分块 | ||
* | ||
* @param {Object} params | ||
* @param {String} params.UploadId | ||
* @param {String} params.ACL | ||
* @param {function} cb | ||
*/ | ||
function upload_complete(params,cb){ | ||
var ak = this.ak || ''; | ||
var sk = this.sk || ''; | ||
var bucketName = params.Bucket || this.bucketName || '';; | ||
var key = util.encodeKey(params.Key)|| null; | ||
var uploadId = params.UploadId || ''; | ||
if (!bucketName || !key) { | ||
throw new Error('require the bucketName and object key'); | ||
} | ||
if (!uploadId) { | ||
@@ -436,12 +371,6 @@ throw new Error('require the uploadId'); | ||
*/ | ||
var body = params.body || ''; | ||
var resource = '/' + key + '?uploadId='+uploadId; | ||
var req = { | ||
method: 'POST', | ||
date: util.getDate(), | ||
type:'text/plain', | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: {} | ||
}; | ||
params.type = 'text/plain' | ||
params.resource = `?uploadId=${uploadId}` | ||
var req = _getObjectRequestParams.call(this, '', 'POST', params) | ||
@@ -453,18 +382,19 @@ var acl = params.ACL; | ||
} | ||
var authStr = auth.generateAuth(ak, sk, req, body); | ||
var body = params.body || ''; | ||
var authStr = auth.generateAuth(this.ak, this.sk, req, body); | ||
this.request(req, body, authStr, cb); | ||
} | ||
/** | ||
* 废弃分块 | ||
* | ||
* @param {Object} params | ||
* @param {String} params.UploadId | ||
* @param {function} cb | ||
*/ | ||
function upload_abort(params,cb) { | ||
var ak = this.ak || ''; | ||
var sk = this.sk || ''; | ||
var bucketName = params.Bucket || this.bucketName || '';; | ||
var key = util.encodeKey(params.Key)|| null; | ||
var uploadId = params.UploadId || ''; | ||
if (!bucketName || !key) { | ||
throw new Error('require the bucketName and object key'); | ||
} | ||
if (!uploadId) { | ||
@@ -474,28 +404,23 @@ throw new Error('require the uploadId'); | ||
params.resource = `?uploadId=${uploadId}` | ||
var req = _getObjectRequestParams.call(this, '', 'DELETE', params) | ||
var body = params.body || ''; | ||
var resource = '/' + key + '?uploadId='+uploadId; | ||
var req = { | ||
method: 'DELETE', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: {} | ||
}; | ||
var authStr = auth.generateAuth(ak, sk, req, body); | ||
var authStr = auth.generateAuth(this.ak, this.sk, req, body); | ||
this.request(req, body, authStr, cb); | ||
} | ||
/** | ||
* 列举分块 | ||
* | ||
* @param {Object} params | ||
* @param {String} params.UploadId | ||
* @param {function} cb | ||
*/ | ||
function upload_list_part(params,cb){ | ||
var ak = this.ak || ''; | ||
var sk = this.sk || ''; | ||
var bucketName = params.Bucket || this.bucketName || '';; | ||
var key = util.encodeKey(params.Key)|| null; | ||
var uploadId = params.UploadId || ''; | ||
if (!bucketName || !key) { | ||
throw new Error('require the bucketName and object key'); | ||
} | ||
if (!uploadId) { | ||
@@ -505,14 +430,11 @@ throw new Error('require the uploadId'); | ||
params.dataType = 'xml' | ||
params.resource = `?uploadId=${uploadId}` | ||
var req = _getObjectRequestParams.call(this, null, 'GET', params) | ||
var body = params.body || ''; | ||
var resource = '/' + key + '?uploadId='+uploadId; | ||
var req = { | ||
method: 'GET', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: {}, | ||
dataType: 'xml' | ||
}; | ||
var authStr = auth.generateAuth(ak, sk, req, body); | ||
var authStr = auth.generateAuth(this.ak, this.sk, req, body); | ||
this.request(req, body, authStr, cb); | ||
@@ -523,23 +445,51 @@ } | ||
* 将sourceBucket这个存储空间下的sourceKey这个object复制到destinationBucket这个存储空间下,并命名为destinationObject | ||
* @param {*} params {"destinationBucket","destinationObject","sourceBucket","sourceKey", headers} | ||
* @param {*} cb | ||
* | ||
* @remark 当前接口不支持跨region复制 | ||
* @param {Object} params {"destinationBucket","destinationObject","sourceBucket","sourceKey", headers} | ||
* @param {Object} params.DestinationBucket | ||
* @param {Object} params.DestinationObject | ||
* @param {Object} params.SourceBucket | ||
* @param {Object} params.SourceKey | ||
* @param {Object} params.headers | ||
* @param {function} cb | ||
* | ||
*/ | ||
function copy (params, cb) { | ||
var sourceBucket = params.sourceBucket | ||
var sourceKey = params.sourceKey | ||
var headers = params.headers || {} | ||
headers = Object.assign({ | ||
'x-kss-copy-source': '/' + sourceBucket + '/' + util.encodeKey(sourceKey) | ||
}, headers) | ||
var sourceBucket = params.SourceBucket || params.sourceBucket | ||
var sourceKey = params.SourceKey || params.sourceKey | ||
var destinationBucket = params.DestinationBucket || params.destinationBucket | ||
var destinationObject = params.DestinationObject || params.destinationObject | ||
const { destinationBucket, destinationObject } = params | ||
if (!destinationBucket) throw new Error('require the destinationBucket') | ||
if (!destinationObject) throw new Error('require the destinationObject') | ||
var p = { | ||
Bucket: params.destinationBucket, | ||
Key: params.destinationObject, | ||
headers | ||
} | ||
put.apply(this, [p, cb]) | ||
const self = this | ||
// 先head一下source是否存在 如果存在则需要取其加密信息 否则会复制失败 如果不存在则直接返回error | ||
headObject.call(self, { | ||
Bucket: sourceBucket, | ||
Key: sourceKey | ||
}, function (err, data, res) { | ||
if(err) { | ||
cb(err, data, res) | ||
return | ||
} | ||
var headers = params.headers || {} | ||
headers = Object.assign({ | ||
'x-kss-copy-source': '/' + sourceBucket + '/' + util.encodeKey(sourceKey), | ||
'x-kss-storage-class': res.caseless.get('x-kss-storage-class') || 'STANDARD' | ||
}, headers) | ||
const { ServerSideEncryption, SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5 } = _getEncryptInfo(res) | ||
var p = { | ||
Bucket: destinationBucket, | ||
Key: destinationObject, | ||
headers, | ||
isNoContent: true, | ||
ServerSideEncryption, SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5 | ||
} | ||
put.apply(self, [p, cb]) | ||
}) | ||
} | ||
@@ -549,4 +499,5 @@ | ||
* 解冻归档文件 | ||
* | ||
* @param {*} params { Bucket, Key } | ||
* @param {*} cb | ||
* @param {function} cb | ||
* @description 此接口只针对归档类型的Object的解冻操作。如果一个Object是标准或者低频访问类型,不要调用该接口。 | ||
@@ -556,18 +507,3 @@ * 具体说明详见:https://docs.ksyun.com/documents/5961 | ||
function restore (params, cb) { | ||
if (params.Key === null || params.Key === undefined) { | ||
throw new Error('require the Key'); | ||
} | ||
var resource = '/' + util.encodeKey(params.Key) + '?restore'; | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucket name'); | ||
} | ||
var req = { | ||
method: 'POST', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: {} | ||
}; | ||
var req = _getObjectRequestParams.call(this, 'restore', 'POST', params) | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
@@ -580,28 +516,37 @@ var body = null; | ||
* 文件重命名 | ||
* @param {*} params {Bucket, Key, newKey} | ||
* @param {*} cb | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket | ||
* @param {String} params.Key | ||
* @param {String} params.NewKey | ||
* @param {function} cb | ||
* @description 具体详情见:https://docs.ksyun.com/documents/908#2 | ||
*/ | ||
function rename (params, cb) { | ||
const { Bucket = this.bucketName, Key, newKey } = params | ||
var p = { | ||
destinationBucket: Bucket, | ||
destinationObject: newKey, | ||
sourceBucket: Bucket, | ||
sourceKey: Key | ||
} | ||
const { Bucket = this.bucketName, Key } = params | ||
const self = this | ||
// 先复制 改名字 | ||
copy.apply(self, [p, function (err, data, res) { | ||
if (!err) { | ||
// 删原始文件 | ||
del.apply(self, [{ | ||
Bucket, Key | ||
}, cb]) | ||
} else { | ||
cb(err, data, res) | ||
headObject.call(this, { Bucket, Key }, function (err, data, res) { | ||
if (err) { | ||
return cb(err, data, res) | ||
} | ||
var newKey = params.NewKey || params.newKey | ||
var p = { | ||
destinationBucket: Bucket, | ||
destinationObject: newKey, | ||
sourceBucket: Bucket, | ||
sourceKey: Key, | ||
} | ||
// 先复制 改名字 | ||
copy.apply(self, [p, function (err, data, res) { | ||
if (!err) { | ||
// 删原始文件 | ||
del.apply(self, [{ | ||
Bucket, Key | ||
}, cb]) | ||
} else { | ||
cb(err, data, res) | ||
} | ||
}]) | ||
}) | ||
}]) | ||
} | ||
@@ -611,11 +556,15 @@ | ||
* 修改文件存储类型 | ||
* @param {*} params { Bucket, Key, storageClass } | ||
* | ||
* storageClass: "STANDARD"、"STANDARD_IA"、"ARCHIVE"。 | ||
* "STANDARD"表示标准存储,"STANDARD_IA"表示低频存储,如果不指定,默认为标准存储。 | ||
* @param {*} cb | ||
* @param {Object} params | ||
* @param {String} params.Bucket | ||
* @param {String} params.Key | ||
* @param {String} params.StorageClass StorageClass: "STANDARD"、"STANDARD_IA"、"ARCHIVE"。 | ||
* "STANDARD"表示标准存储,"STANDARD_IA"表示低频存储,如果不指定,默认为标准存储。 | ||
* @param {function} cb | ||
* @description 具体详见:https://docs.ksyun.com/documents/908#16 | ||
* | ||
*/ | ||
function modifyStorageClass (params, cb) { | ||
const { Bucket = this.bucketName , Key, storageClass = 'STANDARD' } = params; | ||
const { Bucket = this.bucketName , Key } = params; | ||
var storageClass = params.StorageClass || params.storageClass || 'STANDARD' | ||
// 修改之前需要先判断是否存在该object | ||
@@ -625,3 +574,8 @@ const self = this; | ||
if (!err) { | ||
put.apply(self, [{ | ||
const { | ||
ServerSideEncryption, | ||
SSECustomerAlgorithm, | ||
SSECustomerKey, | ||
SSECustomerKeyMD5 } = _getEncryptInfo(res) | ||
const p = { | ||
Bucket, Key, | ||
@@ -632,4 +586,10 @@ headers: { | ||
'x-kss-storage-class': storageClass | ||
} | ||
}, cb]) | ||
}, | ||
ServerSideEncryption, | ||
SSECustomerAlgorithm, | ||
SSECustomerKey, | ||
SSECustomerKeyMD5 | ||
} | ||
put.apply(self, [p, cb]) | ||
} else { | ||
@@ -644,9 +604,23 @@ cb(err, data, res) | ||
* 生成外链 可用于分享或者上传 | ||
* @param {*} params { Bucket, Key, expiration, headers, method } | ||
* | ||
* @param {Object} params { Bucket, Key, Expiration, headers, Method, Sign } | ||
* @param {String} params.Bucket | ||
* @param {String} params.Key | ||
* @param {String} params.Expiration | ||
* @param {String} params.headers | ||
* @param {String} params.Method | ||
* @param {String} params.Sign | ||
* @param cb 回调函数 | ||
* @description expiration: 单位s,不指定的话则默认为15分钟后过期 | ||
* @description Expiration: 单位s,不指定的话则默认为15分钟后过期 | ||
* - 如果是外链上传,需要注意的是headers参数需要和前端传参保持一致 | ||
* - 如果是公开的文件 则Sign为false 可以不需要签名直接生成外链 | ||
*/ | ||
function generatePresignedUrl (params, cb) { | ||
const { Bucket, Key, expiration = 15 * 60, isPublic = false } = params | ||
var { Bucket, Key, Sign = true } = params | ||
// 兼容老版本 之前使用的是isPublic | ||
if (params.hasOwnProperty('isPublic')) { | ||
Sign = !params.isPublic | ||
} | ||
if (Key === null || Key === undefined) { | ||
@@ -666,3 +640,3 @@ throw new Error('require the Key'); | ||
if (isPublic) { | ||
if (!Sign) { | ||
cb(null, uri, null); | ||
@@ -672,20 +646,12 @@ return | ||
var expiration = params.expiration || params.Expiration || 15 * 60 | ||
const expiresTime = util.getExpiresTime(expiration); | ||
let type = '' | ||
if (params.headers) { | ||
type = headers['Content-Type'] || '' | ||
} | ||
params.date = expiresTime | ||
var req = { | ||
method: params.method || 'GET', | ||
date: expiresTime, | ||
uri: uri, | ||
resource: '/' + bucketName + resource, | ||
type: type, | ||
headers: params.headers || {} | ||
} | ||
const method = params.Method || params.method | ||
var req = _getObjectRequestParams.call(this, '', method, params) | ||
const sign = auth.generateToken(this.sk, req, null) | ||
const url = req.uri + '?KSSAccessKeyId=' + this.ak + '&Expires=' + expiresTime + '&Signature=' + encodeURIComponent(sign); | ||
const url = req.uri + '?KSSAccessKeyId=' + encodeURIComponent(this.ak) + '&Expires=' + expiresTime + '&Signature=' + encodeURIComponent(sign); | ||
cb(null, url, null, null); | ||
@@ -695,28 +661,21 @@ } | ||
* 可同时更新acl与stroage class | ||
* @param {*} params { Bucket, Key, ACL, storageClass } | ||
* @param {*} cb | ||
* | ||
* @deprecated 该方法存在缺陷,同时设置时只有acl生效,故从v1.2.0弃用 | ||
* | ||
* @param {object} params - params to func, { Bucket, Key, ACL, StorageClass } | ||
* @param {function} cb - callback function | ||
* @description | ||
* ACL: "private"、"public-read" | ||
* | ||
* storageClass: "STANDARD"、"STANDARD_IA"、"ARCHIVE"。 | ||
* StorageClass: "STANDARD"、"STANDARD_IA"、"ARCHIVE"。 | ||
*/ | ||
function updateAclAndStorageClass ( params, cb) { | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
console.warn('calling a deprecated method!') | ||
if (!bucketName) { | ||
throw new Error('require the bucketName'); | ||
} | ||
var req = _getObjectRequestParams.call(this, 'acl', 'PUT', params) | ||
if (params.Key === null || params.Key === undefined) { | ||
throw new Error('require the Key'); | ||
} | ||
var headers = params.headers || {} | ||
var key = util.encodeKey(params.Key); | ||
var headers = req.headers | ||
var subResource = params.subResource; | ||
var resource = '/' + key + (subResource ? '?' + subResource : ''); | ||
var ACL = params.ACL; | ||
@@ -727,6 +686,4 @@ if (ACL && util.verifyAcl(ACL) !== null) { | ||
headers[attr_Acl] = ACL; | ||
resource = params.VersionId ? '/' + key + '?ACL&versionId=' + params.VersionId: '/' + key + '?acl'; | ||
} | ||
// 如果是修改存储类型 | ||
@@ -736,15 +693,5 @@ if (params.storageClass) { | ||
headers['x-kss-metadata-directive'] = 'REPLACE' | ||
headers['x-kss-storage-class'] = params.storageClass | ||
headers['x-kss-storage-class'] = params.storageClass || params.StorageClass | ||
} | ||
var req = { | ||
method: 'PUT', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: headers, | ||
} | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
@@ -757,16 +704,12 @@ var body = null; | ||
* 设置或更新指定Key的tagging | ||
* @param {*} params - { Bucket, Key, Taggings } | ||
* @param {*} cb | ||
* @param {Object} options | ||
* | ||
* @param {Object} params | ||
* @param {String} params.Bucket | ||
* @param {String} params.Key | ||
* @param {String} params.Taggings | ||
* @param {*} cb | ||
* | ||
* @description Taggings: [{key, value}] | ||
*/ | ||
function putObjectTagging (params, cb) { | ||
if (params.Key === null || params.Key === undefined) { | ||
throw new Error('require the Key'); | ||
} | ||
var resource = '/' + util.encodeKey(params.Key) + '?tagging'; | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucket name'); | ||
} | ||
@@ -799,24 +742,15 @@ const Taggings = params.Taggings | ||
var req = { | ||
method: 'PUT', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: {}, | ||
type: 'text/plain' | ||
}; | ||
params.type = 'text/plain' | ||
var req = _getObjectRequestParams.call(this, 'tagging', 'PUT', params) | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
this.request(req, body, authStr, cb); | ||
} | ||
/** | ||
* 获取指定key的tagging | ||
* | ||
* @param {*} params { Bucket, Key } | ||
* @param {*} cb | ||
* @param {function} cb | ||
*/ | ||
function getObjectTagging (params, cb) { | ||
if (params.Key === null || params.Key === undefined) { | ||
throw new Error('require the Key'); | ||
} | ||
var resource = '/' + util.encodeKey(params.Key) + '?tagging'; | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
@@ -826,10 +760,3 @@ if(!bucketName) { | ||
} | ||
var req = { | ||
method: 'GET', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
resource: '/' + bucketName + resource, | ||
headers: {} | ||
}; | ||
var req = _getObjectRequestParams.call(this, 'tagging', 'GET', params) | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
@@ -842,31 +769,133 @@ var body = null; | ||
* 删除指定Key的tagging | ||
* | ||
* @param {*} params { Bucket, Key } | ||
* @param {*} cb | ||
* @param {function} cb | ||
*/ | ||
function deleteObjectTagging (params, cb) { | ||
if (params.Key === null || params.Key === undefined) { | ||
var req = _getObjectRequestParams.call(this, 'tagging', 'delete', params) | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
var body = null; | ||
this.request(req, body, authStr, cb); | ||
} | ||
// check key wheath is null | ||
function _checkObjectKey (options) { | ||
if (options.Key === null || options.Key === undefined) { | ||
throw new Error('require the Key'); | ||
} | ||
var resource = '/' + util.encodeKey(params.Key) + '?tagging'; | ||
var bucketName = params.Bucket || this.bucketName || ''; | ||
} | ||
function _getObjectRequestParams (subres, method, options) { | ||
_checkObjectKey(options) | ||
var bucketName = options.Bucket || this.bucketName || ''; | ||
if(!bucketName) { | ||
throw new Error('require the bucket name'); | ||
} | ||
var key = util.encodeKey(options.Key) | ||
// 生成外链的计算 需要对key进行二次处理 | ||
if (options.date) { | ||
key = util.encodePresignedUrlKey(options.Key) | ||
} | ||
// according to different business generate resource to calc auth | ||
// eg: ?acl&versionId= ?versionId= | ||
var queryStr = '' | ||
// 连接符 | ||
var sign = '?' | ||
if (subres) { | ||
queryStr = `${sign}${subres}` | ||
sign = '&' | ||
} | ||
if (options.VersionId) { | ||
queryStr += options.VersionId ? `${sign}versionId=${options.VersionId}` : ''; | ||
} | ||
var resource = '/' + key + (options.resource ? options.resource : `${queryStr}`) | ||
// 转码 主要是为了处理没有名称的文件夹 | ||
resource = resource.replace('//', '/%2F') | ||
var uri = config.protocol + '://' + bucketName + '.' + config.baseUrl + resource | ||
// 是否为自定义域名 | ||
if (this.domainMode) { | ||
uri = config.protocol + '://' + config.baseUrl + resource | ||
} | ||
const headers = options.headers || {} | ||
const type = options.Type || options.type | ||
const dataType = options.DataType || options.dataType | ||
var req = { | ||
method: 'DELETE', | ||
date: util.getDate(), | ||
uri: config.protocol + '://' + bucketName + '.' + config.baseUrl + resource, | ||
method: method || 'GET', | ||
date: options.date || util.getDate(), | ||
uri, | ||
resource: '/' + bucketName + resource, | ||
headers: {} | ||
headers: options.headers || {}, | ||
type: type || headers['Content-Type'] || '',// 以设置的类型为主 | ||
dataType: dataType || 'json' // this response data format 'xml' or 'json' | ||
}; | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
var body = null; | ||
this.request(req, body, authStr, cb); | ||
// SSE-KS3 | ||
var encryption = options.ServerSideEncryption | ||
if (encryption) { | ||
if(!util.verifyServerEncryption(encryption)) throw new Error('check your encrypt type, we now only support "AES256".') | ||
req.headers['x-kss-server-side-encryption'] = encryption | ||
} | ||
// SSE-C | ||
const { SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5 } = options | ||
if (SSECustomerAlgorithm && SSECustomerKey && SSECustomerKeyMD5 ) { | ||
if(!util.verifyServerEncryption(SSECustomerAlgorithm)) throw new Error('check your encrypt type, we now only support "AES256".') | ||
req.headers['x-kss-server-side-encryption-customer-algorithm'] = SSECustomerAlgorithm | ||
req.headers['x-kss-server-side-encryption-customer-key'] = SSECustomerKey | ||
req.headers['x-kss-server-side-encryption-customer-key-MD5'] = SSECustomerKeyMD5 | ||
} | ||
// 被拷贝对象为客户端提供密钥加密方式 需要同时提供下面三个属性 | ||
const { SourceSSECustomerAlgorithm, SourceSSECustomerKey, SourceSSECustomerKeyMD5 } = options | ||
if (SourceSSECustomerAlgorithm && SourceSSECustomerKey && SourceSSECustomerKeyMD5) { | ||
req.headers['x-kss-copy-source-server-side-encryption-customer-algorithm'] = SSECustomerAlgorithm | ||
req.headers['x-kss-copy-source-server-side-encryption-customer-key'] = SSECustomerKey | ||
req.headers['x-kss-copy-source-server-side-encryption-customer-key-MD5'] = SSECustomerKeyMD5 | ||
} | ||
if (this.timeout) req.timeout = this.timeout | ||
if (this.securityToken) req.headers['x-kss-security-token'] = this.securityToken | ||
return req; | ||
} | ||
/** | ||
* 从response中提取加密信息 | ||
* | ||
* @param {*} response | ||
* @returns | ||
*/ | ||
function _getEncryptInfo (response) { | ||
const ServerSideEncryption = response.caseless.get('x-kss-server-side-encryption') || '' | ||
const SSECustomerAlgorithm = response.caseless.get('x-kss-server-side-encryption-customer-algorithm') || '' | ||
const SSECustomerKey = response.caseless.get('x-kss-server-side-encryption-customer-key') || '' | ||
const SSECustomerKeyMD5 = response.caseless.get('x-kss-server-side-encryption-customer-key-MD5') || '' | ||
return { | ||
ServerSideEncryption, | ||
SSECustomerAlgorithm, | ||
SSECustomerKey, | ||
SSECustomerKeyMD5 | ||
} | ||
} | ||
module.exports = { | ||
del: del, | ||
get: get, | ||
getObjectStream, | ||
put: put, | ||
@@ -876,2 +905,3 @@ getAcl: getAcl, | ||
putAcl: putAcl, | ||
headObject, | ||
head: headObject, | ||
@@ -878,0 +908,0 @@ copy: copy, |
@@ -11,16 +11,32 @@ var auth = require('./../auth'); | ||
} | ||
var req = _getServiceRequestParams.call(this, '', 'GET', params) | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
var body = null; | ||
this.request(req, body, authStr, cb); | ||
} | ||
function _getServiceRequestParams (type, method, params) { | ||
var date = (new Date()).toUTCString(); | ||
var projectsUrl = params&¶ms.projectIds ? '?projectIds=' + params.projectIds : '' | ||
var projectIds = params && (params.ProjectIds || params.projectIds) | ||
var resource = projectIds ? '?projectIds=' + projectIds : '' | ||
var uri = config.protocol + '://' + config.baseUrl + resource | ||
var req = { | ||
method: 'GET', | ||
method, | ||
date: date, | ||
uri: config.protocol + '://' + config.baseUrl + projectsUrl, | ||
resource: '/' | ||
uri: uri, | ||
resource: '/' | ||
} | ||
var authStr = auth.generateAuth(this.ak, this.sk, req); | ||
var body = null; | ||
if (this.timeout) req.timeout = this.timeout | ||
this.request(req, body, authStr, cb); | ||
if (this.securityToken) req.headers['x-kss-security-token'] = this.securityToken | ||
return req | ||
} | ||
module.exports = { | ||
@@ -27,0 +43,0 @@ get: get, |
/** | ||
* | ||
* 命令行上传核心代码 | ||
* | ||
* @Decrepated 从v1.1.0开始废弃,将在v1.1.5中删除 | ||
* | ||
* 如果有命令行上传的需求,可自行实现。 | ||
* | ||
* @description 命令行工具-上传实现 | ||
@@ -117,2 +123,3 @@ * | ||
function upload(params, cb) { | ||
console.error('Calling a decrepated method !') | ||
var bucketName = params.Bucket || this.bucketName || '';; | ||
@@ -119,0 +126,0 @@ var key = util.encodeKey(params.Key) || null; |
@@ -31,3 +31,36 @@ const ms = require('humanize-ms'); | ||
/** | ||
* 将字符串首字母转小写,比如 Bucket --> bucket | ||
* @param {*} str | ||
* @returns | ||
*/ | ||
function lowercaseFirstChar (str) { | ||
if (str == 'AK') return 'ak' | ||
if (str == 'SK') return 'sk' | ||
return str.charAt(0).toLowerCase() + str.slice(1) | ||
} | ||
/** | ||
* 将接收到的不同的参数转成统一的形式,比如 { AK, SK } / { ak, sk} --> {ak, sk} | ||
* | ||
* @param {*} opt | ||
* @returns | ||
*/ | ||
function convertDiffInitOptions (opt) { | ||
if (!opt) return '' | ||
var obj = {} | ||
for(var key in opt) { | ||
const tmpKey = lowercaseFirstChar(key) | ||
obj[tmpKey] = opt[key] | ||
} | ||
return obj | ||
} | ||
module.exports = function (options) { | ||
// 为了兼容性 如果options属性均为大驼峰 则转成首字母小写 | ||
options = convertDiffInitOptions(options) | ||
if (!options || !options.ak || !options.sk || !options.endpoint) { | ||
@@ -50,3 +83,4 @@ throw new Error('require ak and sk、endpoint. visit: http://ks3.ksyun.com/doc/api/index.html. ak=AccessKeyID,sk=AccessKeySecret'); | ||
domainMode: false, // 是否支持上传自定义域名,默认值为false。 | ||
secure: false // 设置secure为true,则使用HTTPS;设置secure为false,则使用HTTP | ||
secure: false, // 设置secure为true,则使用HTTPS;设置secure为false,则使用HTTP | ||
securityToken: '' // 临时角色token | ||
}, options) | ||
@@ -70,4 +104,8 @@ | ||
opt.inited = true | ||
// bucket更替为bucketName | ||
opt.bucketName = opt.bucket | ||
delete opt.bucket | ||
return opt | ||
} |
@@ -41,10 +41,9 @@ var debug = require('debug')('app'); | ||
var core = this; | ||
this.ak = ak; | ||
this.sk = sk; | ||
this.endpoint = endpoint; | ||
this.bucketName = bucket || null; | ||
this.timeout = timeout | ||
this.domainMode = domainMode | ||
for (let v in options) { | ||
core[v] = options[v] | ||
} | ||
if(region) { | ||
@@ -51,0 +50,0 @@ config.setRegion(region); |
@@ -31,9 +31,9 @@ var requestPromise = require('request'); | ||
const request = requestPromise(uri, data, function(err, res, result) { | ||
const request = requestPromise(uri, data, function(err, response, body) { | ||
var rerr = null; | ||
if (err || Math.floor(res.statusCode / 100) !== 2) { | ||
if (err || Math.floor(response.statusCode / 100) !== 2) { | ||
rerr = { | ||
code: res && res.statusCode || - 1, | ||
error: err || result.error || result || '' | ||
code: response && response.statusCode || - 1, | ||
error: err || body.error || body || '' | ||
}; | ||
@@ -43,3 +43,3 @@ } | ||
debug('err',err); | ||
debug('response',res); | ||
debug('response',response); | ||
if (cb) { | ||
@@ -60,3 +60,7 @@ var data = ''; | ||
// `buf.toString` 会有问题 | ||
cb(rerr, data, res, body); | ||
// rerr: 异常信息 | ||
// data: 转格式后的数据 | ||
// response: response | ||
// body: 原始数据 | ||
cb(rerr, data, response, body); | ||
} | ||
@@ -63,0 +67,0 @@ }); |
@@ -139,2 +139,3 @@ var fs = require('fs'); | ||
if (newKey.includes('//')) newKey = newKey.replace(/\/\//g, '/%2F') | ||
if (newKey.includes('\'')) newKey = newKey.replace(/\'/g, '%27') | ||
return newKey | ||
@@ -254,3 +255,6 @@ } | ||
}; | ||
return y | ||
const tmp = JSON.stringify(y) | ||
const res = this.convert_val(tmp) | ||
return JSON.parse(res) | ||
}, | ||
@@ -317,3 +321,4 @@ xml_to_object: function(xmlcode) { | ||
if (rest.charAt(0) == "'") { | ||
rest = 'unescape(' + rest + ')' | ||
// rest = 'unescape(' + rest + ')' | ||
rest = 'decodeURIComponent(' + rest + ')' | ||
}; | ||
@@ -452,2 +457,13 @@ if (already && ! eval(objname + ".sort")) { | ||
return x | ||
}, | ||
convert_val: function (val) { | ||
let s = ''; | ||
if (val.length == 0) return ''; | ||
s = val.replace(/</g, '<'); | ||
s = s.replace(/>/g, '>'); | ||
s = s.replace(/'/g, '\''); | ||
s = s.replace(/"/g, '\"'); | ||
s = s.replace(/&/g, '&'); | ||
return s; | ||
} | ||
@@ -879,2 +895,10 @@ }; | ||
/** | ||
* 验证是否符合服务端加密方式。目前合法值:AES256 | ||
* @param {*} encrypt | ||
*/ | ||
function verifyServerEncryption (encrypt) { | ||
return encrypt == 'AES256' | ||
} | ||
module.exports = { | ||
@@ -912,4 +936,5 @@ isArray, | ||
clearEmpty, | ||
encodePresignedUrlKey | ||
encodePresignedUrlKey, | ||
verifyServerEncryption | ||
} | ||
{ | ||
"name": "ks3", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"description": "本代码库为`金山云存储KS3`服务.主要提供`KS3 nodejs SDK`和`命令行工具`.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -35,4 +35,6 @@ # KS3-SDK-Nodejs | ||
// 全部测试 | ||
mocha | ||
npm run test | ||
// 建议测试时使用主账户的ak、sk | ||
// 指定自己ak,sk和bucket做测试 | ||
@@ -62,6 +64,7 @@ AK=$ak SK=$sk BUCKET=$bucket mocha | ||
以下调用详细信息,可以访问[官方文档](https://docs.ksyun.com/documents/39060) | ||
以下调用详细信息,可以访问[官方文档](http://ks3.ksyun.com/doc/api/index.html) | ||
`ks3.service.get` : 可以通过该操作来列出客户所有的 Bucket 信息 | ||
<br> | ||
#### **bucket相关** | ||
@@ -76,2 +79,4 @@ `ks3.bucket.put` : 创建一个新的Bucket | ||
`ks3.bucket.getLocation` : 获取bucket的位置 | ||
`ks3.bucket.getACL` : 获取Bucket的ACL | ||
@@ -81,7 +86,42 @@ | ||
`ks3.bucket.listMultipartUploads` : 获取Bucket碎片 | ||
`ks3.bucket.getLogging` : 获得Bucket的日志信息 | ||
`ks3.bucket.putLogging` : 设置Bucket的日志信息 | ||
`ks3.bucket.putLogging` : 设置Bucket的日志信息 | ||
`ks3.bucket.getBucketCors` : 获取bucket的Cors信息 | ||
`ks3.bucket.putBucketCors` : 设置bucket的Cors信息 | ||
`ks3.bucket.deleteBucketCors` : 删除bucket的Cors信息 | ||
`ks3.bucket.getBucketReplicationConfiguration` : 获取bucket的复制规则 | ||
`ks3.bucket.putBucketReplicationConfiguration` : 设置bucket的复制规则 | ||
`ks3.bucket.deleteBucketReplicationConfiguration` : 删除bucket的复制规则 | ||
`ks3.bucket.getBucketMirror` : 获取bucket的镜像回源规则 | ||
`ks3.bucket.putBucketMirror` : 设置bucket的镜像回源规则 | ||
`ks3.bucket.deleteBucketMirror` : 删除bucket的镜像回源规则 | ||
`ks3.bucket.getBucketPolicy` : 获取bucket的策略 | ||
`ks3.bucket.putBucketPolicy` : 设置bucket的策略 | ||
`ks3.bucket.deleteBucketPolicy` : 删除bucket的策略 | ||
`ks3.bucket.getBucketLifecycle` : 获取bucket的生命周期 | ||
`ks3.bucket.putBucketLifecycle` : 设置bucket的生命周期 | ||
`ks3.bucket.deleteBucketLifecycle` : 删除bucket的生命周期 | ||
<br> | ||
#### **object相关** | ||
`ks3.object.del` : 删除指定Object | ||
@@ -97,4 +137,14 @@ | ||
`ks3.object.headObject` : 获取指定Object元数据 | ||
`ks3.object.head` : 获取指定Object元数据 | ||
`ks3.object.copy` : 复制Object | ||
`ks3.object.restore` : 解冻Object | ||
`ks3.object.rename` : Object重命名 | ||
`ks3.object.modifyStorageClass` : 更新Object的存储类型 | ||
`ks3.object.generatePresignedUrl` : 生成分享外链 | ||
`ks3.object.multitpart_upload_init` : 调用这个接口会初始化一个分块上传并且返回一个upload id, upload id 用来标识属于当前object的具体的块,并且用来标识完成分块上传或者取消分块上传 | ||
@@ -109,8 +159,14 @@ | ||
`ks3.object.upload_list_part` : 罗列出已经上传的块 | ||
`ks3.object.putObjectTagging` : 设置标签 | ||
`ks3.object.getObjectTagging` : 获取标签 | ||
`ks3.object.deleteObjectTagging` : 删除标签 | ||
<br> | ||
`ks3.upload.start` : 文件(文件夹)上传 | ||
~~`ks3.upload.start` : 文件(文件夹)上传~~ | ||
<br> | ||
`ks3.download.start`: 文件下载(分块下载) | ||
~~`ks3.download.start`: 文件下载(分块下载)~~ | ||
<br> | ||
@@ -130,8 +186,9 @@ | ||
## KS3 | ||
## KS3 | ||
> ks3命令行从v1.1.0开始废弃,将在v1.1.5中删除,如有此需求可根据当前项目代码进行修改 | ||
关于命令行工具,文档请查看 `./bin/readme.md`,或者[查看这里](https://github.com/ks3sdk/ks3-nodejs-sdk/blob/master/bin/readme.md#ks3-命令行文档) | ||
~~关于命令行工具,文档请查看 `./bin/readme.md`,或者[查看这里](https://github.com/ks3sdk/ks3-nodejs-sdk/blob/master/bin/readme.md#ks3-命令行文档)~~ | ||
功能包括上传文件和文件夹.上传过程中会根据文件大小进行简单上传和分块上传 | ||
~~功能包括上传文件和文件夹.上传过程中会根据文件大小进行简单上传和分块上传~~ | ||
如果大文件在上传过程中发生意外,限次上传文件的时候会从上次断开的地方续传. | ||
~~如果大文件在上传过程中发生意外,限次上传文件的时候会从上次断开的地方续传.~~ |
@@ -451,13 +451,20 @@ var KS3 = require('..'); | ||
describe('delete bucket', function () { | ||
it ('delete bucket', function (done) { | ||
client.bucket.del(function(err, data, res) { | ||
should.not.exist(err); | ||
res.should.have.status(204); // 删除bucket,成功的状态码为204 | ||
done(); | ||
}) | ||
// describe('delete bucket', function () { | ||
// it ('delete bucket', function (done) { | ||
// client.bucket.del(function(err, data, res) { | ||
// should.not.exist(err); | ||
// res.should.have.status(204); // 删除bucket,成功的状态码为204 | ||
// done(); | ||
// }) | ||
// }) | ||
// }) | ||
after(function (done) { | ||
client.bucket.del(function(err, data, res) { | ||
should.not.exist(err); | ||
res.should.have.status(204); // 删除bucket,成功的状态码为204 | ||
done(); | ||
}) | ||
}) | ||
}); |
@@ -21,2 +21,16 @@ var KS3 = require('..'); | ||
it('use Uppercase camel-case should return true', function () { | ||
true && (function () { | ||
new KS3({ | ||
AK: ak, | ||
SK: sk, | ||
Endpoint: endpoint, | ||
Internal: true, | ||
Secure: true, | ||
DomainMode: true, | ||
BucketName: 'liubo-test' | ||
}) | ||
}).should.not.throw() | ||
}) | ||
// 自定义域名的判断需要对请求的uri进行对比 | ||
@@ -23,0 +37,0 @@ // it('should equal with endpoint if domainMode value true', function () { |
@@ -23,2 +23,4 @@ var KS3 = require('..'); | ||
var storageClass = 'ARCHIVE' | ||
var ServerSideEncryption = 'AES256' | ||
before (function (done) { | ||
@@ -249,3 +251,3 @@ this.timeout(30000) | ||
it('return Stream', function (done) { | ||
const req = client.object.get({ | ||
const req = client.object.getObjectStream({ | ||
Key: 'word.txt' | ||
@@ -586,2 +588,58 @@ }) | ||
// 加密相关 | ||
describe('encrypt', function () { | ||
it('return a error, only AES256 supported.', function() { | ||
(function() { client.object.put({ | ||
Body: 'This is a encrypt content ~', | ||
Key: key, | ||
ServerSideEncryption: 'AES128' | ||
}, function (){}) }).should.throw ('check your encrypt type, we now only support "AES256".'); | ||
}) | ||
it('upload and set encrypt', function(done) { | ||
client.object.put({ | ||
Body: 'This is a encrypt content ~', | ||
Key: key, | ||
ServerSideEncryption | ||
}, function (err, data, res){ | ||
should.not.exist(err) | ||
res.should.have.status(200) | ||
done() | ||
}) | ||
}) | ||
it('copy encrypt file', function (done) { | ||
client.object.copy({ | ||
destinationBucket: bucketName, | ||
destinationObject: key + '-copy', | ||
sourceBucket: bucketName, | ||
sourceKey: key | ||
}, function (err, data, res) { | ||
should.not.exist(err) | ||
done() | ||
}) | ||
}) | ||
it('update file storageClass', function (done) { | ||
client.object.modifyStorageClass({ | ||
Key: key, | ||
storageClass: 'STANDARD_IA' | ||
}, function (err, data, res) { | ||
should.not.exist(err) | ||
done() | ||
}) | ||
}) | ||
it('rename encrypt file', function(done) { | ||
client.object.rename({ | ||
Key: key, | ||
newKey: 'new-' + key | ||
}, function (err, data, res) { | ||
should.not.exist(err) | ||
done() | ||
}) | ||
}) | ||
}) | ||
after(function (done) { | ||
@@ -588,0 +646,0 @@ client.config({ |
@@ -63,4 +63,4 @@ var util = require('../lib/util'); | ||
it ('should be return true', function () { | ||
(util.encodePresignedUrlKey('#####()!~\'.png') === '%23%23%23%23%23%28%29%21%7E%27.png').should.be.ok | ||
(util.encodePresignedUrlKey('#####()!~\'.png') === '%23%23%23%23%23%28%29%21~%27.png').should.be.ok | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
7226541
67
6618
188