Comparing version 2.3.2 to 2.4.2
#CHANGELOG | ||
## v2.4.2 | ||
Issue [#48](https://github.com/qiniu/nodejs-sdk/pull/48): | ||
- 去除 auth.GetPolicy.scope 的默认值:"*/*" | ||
Issue [#46](https://github.com/qiniu/nodejs-sdk/pull/46): | ||
- 更新 v2.4.1 的文档(docs/README.md) | ||
## v2.4.1 | ||
2013-02-09 | ||
Issue [#43](https://github.com/qiniu/nodejs-sdk/pull/43): | ||
- imageMogr bugfix: auto-orient | ||
- auth.UploadToken, auth.DownloadToken 改为 auth.PutPolicy, auth.GetPolicy | ||
- auth.UploadToken.generateToken() 改为 auth.PutPolicy.token() | ||
- auth.DownloadToken.generateToken() 改为 auth.GetPolicy.token() | ||
- auth.DownloadToken.pattern 改为 auth.GetPolicy.scope | ||
## v2.4.0 | ||
2013-01-23 | ||
Issue [#36](https://github.com/qiniu/nodejs-sdk/pull/36): | ||
- 增加 auth.DownloadToken 类 | ||
- auth.UploadToken 增加:escape、asyncOps 成员,generateSignature 改名为 generateToken | ||
- 增加 rs.copy, rs.move, rs.batchGet, rs.batchStat, rs.batchDelete, rs.batchCopy, rs.batchMove | ||
- 增加 Travis-CI 的支持 | ||
Issue [#32](https://github.com/qiniu/nodejs-sdk/pull/32): | ||
- auth.UploadToken.generateSignature 各个参数调整为可选 | ||
- uploadWithToken 非兼容调整: rs.uploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, crc32, onret) | ||
- generateActionString 非兼容调整: action = util.generateActionString(bucket, key, mimeType, customMeta, crc32) | ||
## v2.3.2 | ||
@@ -7,7 +49,6 @@ | ||
updated: | ||
- 修复crc32编码 | ||
- 修复使用UploadToken方式上传时流式上传bug,流式上传不检查crc32 | ||
## v2.3.0 | ||
@@ -17,4 +58,3 @@ | ||
updated: | ||
- 启用新的 uploadToken(上传凭证)上传方式,可由客户方业务服务器生成上传凭证。上传前无需请求七牛云存储,减少http请求。 | ||
- 启用新的 uploadToken(上传凭证)上传方式,可由客户方业务服务器生成上传凭证。上传前无需请求七牛云存储,减少http请求。 |
@@ -5,3 +5,36 @@ var crypto = require('crypto'); | ||
function UploadToken(opts) { | ||
exports.PutPolicy = PutPolicy; | ||
exports.GetPolicy = GetPolicy; | ||
// ------------------------------------------------------------------------------------------ | ||
// func generateSignature | ||
function generateSignature(params) { | ||
var paramsString = JSON.stringify(params); | ||
return util.encode(paramsString); | ||
} | ||
// ------------------------------------------------------------------------------------------ | ||
// func generateEncodedDigest | ||
function generateEncodedDigest(signature) { | ||
var hmac = crypto.createHmac('sha1', config.SECRET_KEY); | ||
hmac.update(signature); | ||
var digest = hmac.digest('base64'); | ||
return util.base64ToUrlsafe(digest); | ||
} | ||
// ------------------------------------------------------------------------------------------ | ||
// func generateToken | ||
function generateToken(params) { | ||
var signature = generateSignature(params); | ||
var encodedDigest = generateEncodedDigest(signature); | ||
return config.ACCESS_KEY + ":" + encodedDigest + ":" + signature; | ||
} | ||
// ------------------------------------------------------------------------------------------ | ||
// type PutPolicy | ||
function PutPolicy(opts) { | ||
this.scope = opts.scope || null; | ||
@@ -12,7 +45,9 @@ this.expires = opts.expires || 3600; | ||
this.customer = opts.customer || null; | ||
this.escape = opts.escape || 0; | ||
this.asyncOps = opts.asyncOps || null; | ||
} | ||
UploadToken.prototype.generateSignature = function() { | ||
PutPolicy.prototype.token = function() { | ||
var params = { | ||
"deadline": this.expires + Math.floor(Date.now() / 1000), | ||
"deadline": this.expires + Math.floor(Date.now() / 1000) | ||
}; | ||
@@ -31,19 +66,28 @@ if (this.scope !== null) { | ||
} | ||
var paramsString = JSON.stringify(params) | ||
return util.encode(paramsString); | ||
if (this.asyncOps !== null) { | ||
params["asyncOps"] = this.asyncOps; | ||
} | ||
if (this.escape) { | ||
params["escape"] = this.excape; | ||
} | ||
return generateToken(params); | ||
}; | ||
UploadToken.prototype.generateEncodedDigest = function(signature) { | ||
var hmac = crypto.createHmac('sha1', config.SECRET_KEY); | ||
hmac.update(signature); | ||
var digest = hmac.digest('base64'); | ||
return util.base64ToUrlsafe(digest); | ||
}; | ||
// ------------------------------------------------------------------------------------------ | ||
// type GetPolicy | ||
UploadToken.prototype.generateToken = function() { | ||
var signature = this.generateSignature(); | ||
var encoded_digest = this.generateEncodedDigest(signature); | ||
return config.ACCESS_KEY + ":" + encoded_digest + ":" + signature; | ||
function GetPolicy(opts) { | ||
this.expires = opts.expires || 3600; | ||
this.scope = opts.scope; // GetPolicy.scope 没有默认值:用 "*/*" 访问权限太高! | ||
} | ||
GetPolicy.prototype.token = function() { | ||
var params = { | ||
S: this.scope, | ||
E: this.expires + Math.floor(Date.now() / 1000), | ||
}; | ||
return generateToken(params); | ||
}; | ||
exports.UploadToken = UploadToken; | ||
// ------------------------------------------------------------------------------------------ | ||
@@ -18,2 +18,5 @@ /* | ||
var params_string = "", key = null, val = null; | ||
if (undefined !== opts.auto_orient && opts.auto_orient === true){ | ||
params_string += "/auto-orient"; | ||
} | ||
for (var i=0; i < keys.length; i++) { | ||
@@ -25,5 +28,2 @@ key = keys[i]; | ||
} | ||
if(undefined !== opts.auto_orient && opts.auto_orient === true){ | ||
params_string += "/auto-orient"; | ||
} | ||
return 'imageMogr' + params_string; | ||
@@ -30,0 +30,0 @@ }; |
@@ -253,2 +253,60 @@ var fs = require('fs'); | ||
Service.prototype.copy = function(sourceBucket, sourceKey, targetBucket, targetKey, onret) { | ||
/* | ||
* func Copy(sourceBucket, sourceKey, targetBucket, targetKey, onret) => Bool | ||
* 拷贝某个资源表中的文件到另一个资源表中的某个文件 | ||
*/ | ||
var url = config.RS_HOST + generateMoveOrCopyOpString('copy', sourceBucket, sourceKey, targetBucket, targetKey); | ||
this.conn.callWith(url, null, onret); | ||
}; | ||
Service.prototype.move = function(sourceBucket, sourceKey, targetBucket, targetKey, onret) { | ||
/* | ||
* func Move(sourceBucket, sourceKey, targetBucket, targetKey, onret) => Bool | ||
* 移动某个资源表中的文件到另一个资源表中的某个文件 | ||
*/ | ||
var url = config.RS_HOST + generateMoveOrCopyOpString('move', sourceBucket, sourceKey, targetBucket, targetKey); | ||
this.conn.callWith(url, null, onret); | ||
}; | ||
Service.prototype.batchGet = function(bucket, keys, onret) { | ||
/* | ||
* func BatchGet(bucket, keys, onret) => GetRet[] | ||
* 为每个key生成一个短期有效的下载地址 | ||
*/ | ||
batch(this, "get", bucket, keys, onret); | ||
}; | ||
Service.prototype.batchStat = function(bucket, keys, onret) { | ||
/* | ||
* func BatchStat(bucket, keys, onret) => Entry[] | ||
* 查看每个key所对应文件的属性 | ||
*/ | ||
batch(this, "stat", bucket, keys, onret); | ||
}; | ||
Service.prototype.batchDelete = function(bucket, keys, onret) { | ||
/* | ||
* func BatchDelete(bucket, keys, onret) => Bool[] | ||
* 批量删除每个key所对应的资源 | ||
*/ | ||
batch(this, "delete", bucket, keys, onret); | ||
}; | ||
Service.prototype.batchCopy = function(entries, onret) { | ||
/* | ||
* func BatchCopy(entries, onret) => Bool[] | ||
* 批量拷贝文件 | ||
*/ | ||
batchMoveOrCopy(this, 'copy', entries, onret); | ||
}; | ||
Service.prototype.batchMove = function(entries, onret) { | ||
/* | ||
* func BatchMove(entries, onret) => Bool[] | ||
* 批量移动文件 | ||
*/ | ||
batchMoveOrCopy(this, 'move', entries, onret); | ||
}; | ||
/* | ||
@@ -314,2 +372,40 @@ * 持久化存储一个经过云端服务处理过后的资源 | ||
// ------------------------------------------------------------------------------------------ | ||
// private functions | ||
function generateMoveOrCopyOpString(command, sourceBucket, sourceKey, targetBucket, targetKey) { | ||
var sourceEntryURI = sourceBucket + ":" + sourceKey; | ||
var targetEntryURI = targetBucket + ":" + targetKey; | ||
var url = '/' + command + '/' + util.encode(sourceEntryURI) + '/' + util.encode(targetEntryURI); | ||
return url; | ||
}; | ||
function batch(rs, command, bucket, keys, onret) { | ||
var ops = [] | ||
, length = keys.length | ||
, url = config.RS_HOST + '/batch?'; | ||
for(var i = 0; i < length; i++) { | ||
console.log("Entry URI is: ", bucket + ":" + keys[i]); | ||
var encodedEntryURI = util.encode(bucket + ":" + keys[i]); | ||
ops.push("op=/" + command + "/" + encodedEntryURI); | ||
} | ||
url += ops.join("&"); | ||
console.log("Batch URL: ", url); | ||
rs.conn.callWith(url, null, onret); | ||
} | ||
function batchMoveOrCopy(rs, command, entries, onret) { | ||
var ops = [] | ||
, length = ops.length | ||
, url = config.RS_HOST + '/batch?'; | ||
for(var i = 0; i < length; i++) { | ||
ops.push('op=' + moveOrCopy(command, entries[i][0], entries[i][1], entries[i][2], entries[i][3])); | ||
} | ||
url += ops.join("&"); | ||
rs.conn.callWith(url, null, onret); | ||
} | ||
// ------------------------------------------------------------------------------------------ |
{ | ||
"name": "qiniu", | ||
"version": "2.3.2", | ||
"version": "2.4.2", | ||
"description": "Node wrapper for Qiniu Resource (Cloud) Storage API", | ||
@@ -10,3 +10,3 @@ "main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error => no test specified\" && exit 1\"" | ||
"test": "make test" | ||
}, | ||
@@ -13,0 +13,0 @@ "repository": { |
# Node wrapper for Qiniu Resource (Cloud) Storage API | ||
[![Build Status](https://travis-ci.org/qiniu/nodejs-sdk.png?branch=master)](https://travis-ci.org/qiniu/nodejs-sdk) | ||
![logo](http://qiniutek.com/images/logo-2.png) | ||
@@ -54,10 +56,9 @@ | ||
var opts = { | ||
scope: "yet_another_bucket", | ||
scope: "yet_another_bucket", // 可以是 "<bucketName>" 或 "<bucketName>:<key>" | ||
expires: 3600, | ||
callbackUrl: "http://www.example.com/notifications/qiniurs", // 可选 | ||
callbackBodyType: "application/x-www-form-urlencoded", // 可选 | ||
customer: "username@example.com" // 可选 | ||
}; | ||
var token = new qiniu.auth.UploadToken(opts); | ||
var uploadToken = token.generateToken(); | ||
var uploadPolicy = new qiniu.auth.PutPolicy(opts); | ||
var uploadToken = uploadPolicy.token(); | ||
@@ -64,0 +65,0 @@ // 上传文件第2步 |
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
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
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
33875
716
1
139