diff --git a/NEWS.md b/CHANGELOG.md similarity index 60% rename from NEWS.md rename to CHANGELOG.md index 2a01fc7d..fab57a52 100644 --- a/NEWS.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ #CHANGELOG +## v2.3.2 + +2012-12-31 + +updated: + +- 修复crc32编码 +- 修复使用UploadToken方式上传时流式上传bug,流式上传不检查crc32 + ## v2.3.0 2012-11-23 @@ -7,4 +16,3 @@ updated: - 启用新的 uploadToken(上传凭证)上传方式,可由客户方业务服务器生成上传凭证。上传前无需请求七牛云存储,减少http请求。 -- 增加断点续上传支持,并行断点传输速度更快 \ No newline at end of file diff --git a/demo/rs_demo.js b/demo/rs_demo.js index 176fac65..7efe9c1f 100644 --- a/demo/rs_demo.js +++ b/demo/rs_demo.js @@ -1,5 +1,7 @@ -var qiniu = require('../index.js'); +var fs = require('fs'); +var path = require('path'); var mime = require('mime'); +var qiniu = require('../index.js'); qiniu.conf.ACCESS_KEY = ''; qiniu.conf.SECRET_KEY = ''; diff --git a/docs/README.md b/docs/README.md index a784f41a..bc4ccd3c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -467,7 +467,7 @@ options "crop": , "quality": , "rotate": , - "format": , =jpg, gif, png, tif, etc. + "format": , = jpg, gif, png, tif, etc. "auto_orient": } diff --git a/lib/auth.js b/lib/auth.js index a7715090..b6961762 100644 --- a/lib/auth.js +++ b/lib/auth.js @@ -12,12 +12,20 @@ function UploadToken(opts) { UploadToken.prototype.generateSignature = function() { var params = { - "scope": this.scope, "deadline": this.expires + Math.floor(Date.now() / 1000), - "callbackUrl": this.callbackUrl, - "callbackBodyType": this.callbackBodyType, - "customer": this.customer, }; + if (this.scope !== null) { + params["scope"] = this.scope; + } + if (this.callbackUrl !== null) { + params["callbackurl"] = this.callbackUrl; + } + if (this.callbackBodyType !== null) { + params["callbackBodyType"] = this.callbackBodyType; + } + if (this.customer !== null) { + params["customer"] = this.customer; + } var paramsString = JSON.stringify(params) return util.encode(paramsString); }; diff --git a/lib/rs.js b/lib/rs.js index 6016263e..bb4756ce 100644 --- a/lib/rs.js +++ b/lib/rs.js @@ -1,6 +1,6 @@ var fs = require('fs'); var path = require('path'); -var crc = require('crc'); +var crc32 = require('crc32'); var mime = require('mime'); var formstream = require('formstream'); var config = require('./conf.js'); @@ -84,7 +84,7 @@ Service.prototype.upload = function(upToken, key, mimeType, filename, stream, on **/ var self = this; if (!mimeType) { - mimeType = mime.lookup(filename); + mimeType = "application/octet-stream"; } var entryURI = this.bucket + ':' + key; entryURI = '/rs-put/' + util.encode(entryURI) + '/mimeType/' + util.encode(mimeType); @@ -117,13 +117,17 @@ Service.prototype.uploadFile = function(upToken, key, mimeType, localFile, onret }); }; -Service.prototype.uploadWithToken = function(uploadToken, localFile, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret) { +Service.prototype.uploadWithToken = function(uploadToken, stream, key, mimeType, customMeta, callbackParams, crc32, onret) { /* - * func UploadWithToken(uploadToken, localFile, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret) => (data PutRet, code int, err Error) + * func UploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, crc32, onret) => (data PutRet, code int, err Error) * 使用upload_token以multipart/form-data形式上传ReadStream流 **/ var bucket = this.bucket; - var actionString = util.generateActionString(localFile, bucket, key, mimeType, customMeta, enableCrc32Check); + if (!mimeType) { + mimeType = "application/octet-stream"; + } + + var actionString = util.generateActionString(bucket, key, mimeType, customMeta, crc32); if (callbackParams === null) { callbackParams = { "bucket": bucket, @@ -134,9 +138,8 @@ Service.prototype.uploadWithToken = function(uploadToken, localFile, stream, key var callbackQueryString = util.generateQueryString(callbackParams); var url = config.UP_HOST + "/upload"; - var filename = path.basename(localFile); + var filename = path.basename(key); var form = formstream(); - var mimeType = mime.lookup(localFile); form.field('action', actionString); form.field('params', callbackQueryString); form.field('multipart', true); @@ -147,24 +150,37 @@ Service.prototype.uploadWithToken = function(uploadToken, localFile, stream, key return this.conn.callWithToken(uploadToken, url, form, onret); }; - Service.prototype.uploadFileWithToken = function(uploadToken, localFile, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret) { /* * func UploadFileWithToken(uploadToken, localFile, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret) => (data PutRet, code int, err Error) * 使用upload_token以multipart/form-data形式上传文件 **/ - var self = this; + var self = this + , bucket = self.bucket; if (!mimeType) { - mimeType = mime.lookup(localFile); + mimeType = mime.lookup(localFile); + } + fs.stat(localFile, function(err, fi) { + if (err) { + onret({code: -1, error: err.toString(), detail: err}); + return; } - fs.stat(localFile, function(err, fi) { - if (err) { - onret({code: -1, error: err.toString(), detail: err}); - return; - } - var stream = fs.createReadStream(localFile); - self.uploadWithToken(uploadToken, localFile, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret); - }); + var fileCrc32 = null + , stream = fs.createReadStream(localFile); + + if (enableCrc32Check) { + var fileStat = fs.statSync(localFile) + , fileSize = fileStat.size + , buf = new Buffer(fileSize) + , fd = fs.openSync(localFile, 'r'); + + fs.readSync(fd, buf, 0, fileSize, 0); + fs.closeSync(fd); + fileCrc32 = parseInt("0x" + crc32(buf)).toString(); + } + + self.uploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, fileCrc32, onret); + }); }; Service.prototype.get = function(key, attName, onret) { diff --git a/lib/util.js b/lib/util.js index 7a0d02c9..bc81a9dc 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1,7 +1,7 @@ var fs = require('fs'); +var path = require('path'); var mime = require('mime'); var crypto = require('crypto'); -var crc32 = require('crc32'); // ------------------------------------------------------------------------------------------ // func encode @@ -15,34 +15,22 @@ exports.encode = function(v) { return exports.base64ToUrlsafe(encoded); }; -exports.generateActionString = function(localFile, bucket, key, mimeType, customMeta, enableCrc32Check) { - if (!fs.existsSync(localFile)) { +exports.generateActionString = function(bucket, key, mimeType, customMeta, crc32) { + if (!key) { + console.error("Please specify your key!"); return; } - if (key == null) { - var today = new Date(); - key = crypto.createHash('sha1').update(localFile + today.toString()).digest('hex'); - } var entryUri = bucket + ":" + key; - if (mimeType === "") { - mimeType = mime.lookup(localFile); - if (mimeType === "") { - mimeType = "application/octet-stream"; - } + if (!mimeType) { + mimeType = "application/octet-stream"; } var actionParams = '/rs-put/' + this.encode(entryUri) + '/mimeType/' + this.encode(mimeType); if (customMeta !== "") { actionParams += '/meta/' + this.encode(customMeta); } - if (enableCrc32Check) { - var fileStat = fs.statSync(localFile); - var fileSize = fileStat.size; - var buf = new Buffer(fileSize); - var fd = fs.openSync(localFile, 'r'); - fs.readSync(fd, buf, 0, fileSize, 0); - var fileCrc32 = parseInt("0x" + crc32(buf)).toString(); - actionParams += '/crc32/' + fileCrc32; - } + if ((crc32 !== undefined) && (crc32 !== null) && (crc32 !== "")) { + actionParams += '/crc32/' + crc32; + } return actionParams; } diff --git a/package.json b/package.json index 18c5b240..2bf4a595 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "qiniu", - "version": "2.3.1", + "version": "2.3.2", "description": "Node wrapper for Qiniu Resource (Cloud) Storage API", "main": "index.js", "directories": {