From 3ec2aa62a5a599ffb4cc396d6eaaec293f862676 Mon Sep 17 00:00:00 2001 From: ikbear Date: Mon, 31 Dec 2012 11:47:25 +0800 Subject: [PATCH 1/5] Upload with uptoken and stream --- NEWS.md | 11 ++++++++++- demo/rs_demo.js | 10 +++++++--- docs/README.md | 2 +- lib/rs.js | 33 ++++++++++++++++++++++++++------- lib/util.js | 12 +++++++----- package.json | 2 +- 6 files changed, 52 insertions(+), 18 deletions(-) diff --git a/NEWS.md b/NEWS.md index 2a01fc7d..d05a38d7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,14 @@ #CHANGELOG +## v2.3.2 + +2012-12-31 + +updated: + +- 修复crc32编码but +- 修复使用UploadToken方式上传时流式上传bug,流式上传不检查crc32 + ## v2.3.0 2012-11-23 @@ -7,4 +16,4 @@ updated: - 启用新的 uploadToken(上传凭证)上传方式,可由客户方业务服务器生成上传凭证。上传前无需请求七牛云存储,减少http请求。 -- 增加断点续上传支持,并行断点传输速度更快 \ No newline at end of file +- 增加断点续上传支持,并行断点传输速度更快 diff --git a/demo/rs_demo.js b/demo/rs_demo.js index 176fac65..84a04bf9 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 = ''; @@ -34,8 +36,10 @@ qiniu.rs.mkbucket(conn, bucket, function(resp) { callbackParams = {}, enableCrc32Check = true; - rs.uploadFileWithToken(uploadToken, localFile, key, mimeType, customMeta, callbackParams, enableCrc32Check, function(resp){ - console.log("\n===> Upload File with Token result: ", resp); + var stream = fs.createReadStream(localFile); + var filename = path.basename(localFile); + rs.uploadWithToken(uploadToken, filename, stream, key, mimeType, customMeta, callbackParams, function(resp){ + console.log("\n===> Upload Stream with Token result: ", resp); if (resp.code != 200) { clear(rs); return; 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/rs.js b/lib/rs.js index 6016263e..f4866990 100644 --- a/lib/rs.js +++ b/lib/rs.js @@ -117,13 +117,16 @@ 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, filename, stream, key, mimeType, customMeta, callbackParams, onret) { /* - * func UploadWithToken(uploadToken, localFile, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret) => (data PutRet, code int, err Error) + * func UploadWithToken(uploadToken, filename, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, 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 === null) { + mimeType = mime.lookup(filename); + } + var actionString = util.generateActionString('', bucket, key, mimeType, customMeta, false); if (callbackParams === null) { callbackParams = { "bucket": bucket, @@ -134,9 +137,7 @@ 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 form = formstream(); - var mimeType = mime.lookup(localFile); form.field('action', actionString); form.field('params', callbackQueryString); form.field('multipart', true); @@ -147,7 +148,6 @@ 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) @@ -162,8 +162,27 @@ Service.prototype.uploadFileWithToken = function(uploadToken, localFile, key, mi onret({code: -1, error: err.toString(), detail: err}); return; } + var bucket = self.bucket; + var filename = path.basename(localFile); var stream = fs.createReadStream(localFile); - self.uploadWithToken(uploadToken, localFile, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret); + var actionString = util.generateActionString(localFile, bucket, key, mimeType, customMeta, enableCrc32Check); + if (callbackParams === null) { + callbackParams = { + "bucket": bucket, + "key": key, + "mime_type": mimeType + }; + } + var callbackQueryString = util.generateQueryString(callbackParams); + var form = formstream(); + form.field('action', actionString); + form.field('params', callbackQueryString); + form.field('multipart', true); + form.field('auth', uploadToken); + form.stream('file', stream, filename, mimeType); + form = new util.Form(form, form.headers()['Content-Type']); + var url = config.UP_HOST + "/upload"; + return self.conn.callWithToken(uploadToken, url, form, onret); }); }; diff --git a/lib/util.js b/lib/util.js index 7a0d02c9..576dc0c6 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1,4 +1,5 @@ var fs = require('fs'); +var path = require('path'); var mime = require('mime'); var crypto = require('crypto'); var crc32 = require('crc32'); @@ -16,16 +17,14 @@ exports.encode = function(v) { }; exports.generateActionString = function(localFile, bucket, key, mimeType, customMeta, enableCrc32Check) { - if (!fs.existsSync(localFile)) { - return; - } + var filename = path.basename(localFile); if (key == null) { var today = new Date(); - key = crypto.createHash('sha1').update(localFile + today.toString()).digest('hex'); + key = crypto.createHash('sha1').update(filename+ today.toString()).digest('hex'); } var entryUri = bucket + ":" + key; if (mimeType === "") { - mimeType = mime.lookup(localFile); + mimeType = mime.lookup(filename); if (mimeType === "") { mimeType = "application/octet-stream"; } @@ -35,6 +34,9 @@ exports.generateActionString = function(localFile, bucket, key, mimeType, custom actionParams += '/meta/' + this.encode(customMeta); } if (enableCrc32Check) { + if (!fs.existsSync(localFile)) { + return; + } var fileStat = fs.statSync(localFile); var fileSize = fileStat.size; var buf = new Buffer(fileSize); 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": { From df3ee62b2c9684c8d1e2c346f475bdfdd732cb97 Mon Sep 17 00:00:00 2001 From: ikbear Date: Mon, 7 Jan 2013 16:13:35 +0800 Subject: [PATCH 2/5] Update changelog doc --- NEWS.md => CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename NEWS.md => CHANGELOG.md (94%) diff --git a/NEWS.md b/CHANGELOG.md similarity index 94% rename from NEWS.md rename to CHANGELOG.md index d05a38d7..555ea0ae 100644 --- a/NEWS.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ updated: -- 修复crc32编码but +- 修复crc32编码 - 修复使用UploadToken方式上传时流式上传bug,流式上传不检查crc32 ## v2.3.0 From 702ac42a5935fa8fc0a52adf2dc6bd8bfd1c92ba Mon Sep 17 00:00:00 2001 From: ikbear Date: Wed, 9 Jan 2013 17:06:01 +0800 Subject: [PATCH 3/5] Add enableCrc32Check option to stream upload --- demo/rs_demo.js | 6 ++--- lib/rs.js | 67 +++++++++++++++++++++++-------------------------- lib/util.js | 30 +++++++--------------- 3 files changed, 42 insertions(+), 61 deletions(-) diff --git a/demo/rs_demo.js b/demo/rs_demo.js index 84a04bf9..7efe9c1f 100644 --- a/demo/rs_demo.js +++ b/demo/rs_demo.js @@ -36,10 +36,8 @@ qiniu.rs.mkbucket(conn, bucket, function(resp) { callbackParams = {}, enableCrc32Check = true; - var stream = fs.createReadStream(localFile); - var filename = path.basename(localFile); - rs.uploadWithToken(uploadToken, filename, stream, key, mimeType, customMeta, callbackParams, function(resp){ - console.log("\n===> Upload Stream with Token result: ", resp); + rs.uploadFileWithToken(uploadToken, localFile, key, mimeType, customMeta, callbackParams, enableCrc32Check, function(resp){ + console.log("\n===> Upload File with Token result: ", resp); if (resp.code != 200) { clear(rs); return; diff --git a/lib/rs.js b/lib/rs.js index f4866990..b244c363 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,16 +117,16 @@ Service.prototype.uploadFile = function(upToken, key, mimeType, localFile, onret }); }; -Service.prototype.uploadWithToken = function(uploadToken, filename, stream, key, mimeType, customMeta, callbackParams, onret) { +Service.prototype.uploadWithToken = function(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, fileCrc32, onret) { /* - * func UploadWithToken(uploadToken, filename, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret) => (data PutRet, code int, err Error) + * func UploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, fileCrc32, onret) => (data PutRet, code int, err Error) * 使用upload_token以multipart/form-data形式上传ReadStream流 **/ var bucket = this.bucket; - if (mimeType === null) { - mimeType = mime.lookup(filename); + if (!mimeType) { + mimeType = "application/octet-stream"; } - var actionString = util.generateActionString('', bucket, key, mimeType, customMeta, false); + var actionString = util.generateActionString(bucket, key, mimeType, customMeta, enableCrc32Check, fileCrc32); if (callbackParams === null) { callbackParams = { "bucket": bucket, @@ -137,6 +137,7 @@ Service.prototype.uploadWithToken = function(uploadToken, filename, stream, key, var callbackQueryString = util.generateQueryString(callbackParams); var url = config.UP_HOST + "/upload"; + var filename = path.basename(key); var form = formstream(); form.field('action', actionString); form.field('params', callbackQueryString); @@ -153,37 +154,31 @@ Service.prototype.uploadFileWithToken = function(uploadToken, localFile, key, mi * 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 bucket = self.bucket; - var filename = path.basename(localFile); - var stream = fs.createReadStream(localFile); - var actionString = util.generateActionString(localFile, bucket, key, mimeType, customMeta, enableCrc32Check); - if (callbackParams === null) { - callbackParams = { - "bucket": bucket, - "key": key, - "mime_type": mimeType - }; - } - var callbackQueryString = util.generateQueryString(callbackParams); - var form = formstream(); - form.field('action', actionString); - form.field('params', callbackQueryString); - form.field('multipart', true); - form.field('auth', uploadToken); - form.stream('file', stream, filename, mimeType); - form = new util.Form(form, form.headers()['Content-Type']); - var url = config.UP_HOST + "/upload"; - return self.conn.callWithToken(uploadToken, url, form, onret); - }); + var fileCrc32 = '' + , 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); + fileCrc32 = parseInt("0x" + crc32(buf)).toString(); + } + + return self.uploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, fileCrc32, onret); + }); }; Service.prototype.get = function(key, attName, onret) { diff --git a/lib/util.js b/lib/util.js index 576dc0c6..43adef85 100644 --- a/lib/util.js +++ b/lib/util.js @@ -2,7 +2,6 @@ var fs = require('fs'); var path = require('path'); var mime = require('mime'); var crypto = require('crypto'); -var crc32 = require('crc32'); // ------------------------------------------------------------------------------------------ // func encode @@ -16,34 +15,23 @@ exports.encode = function(v) { return exports.base64ToUrlsafe(encoded); }; -exports.generateActionString = function(localFile, bucket, key, mimeType, customMeta, enableCrc32Check) { - var filename = path.basename(localFile); - if (key == null) { - var today = new Date(); - key = crypto.createHash('sha1').update(filename+ today.toString()).digest('hex'); +exports.generateActionString = function(bucket, key, mimeType, customMeta, enableCrc32Check, fileCrc32) { + if (!key) { + console.error("Please specify your key!"); + return; } var entryUri = bucket + ":" + key; - if (mimeType === "") { - mimeType = mime.lookup(filename); - 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) { - if (!fs.existsSync(localFile)) { - return; - } - 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 ((fileCrc32 !== undefined) && (fileCrc32 !== null)) { + actionParams += '/crc32/' + fileCrc32; + } } return actionParams; } From b46acbfafd7376f45e515e3d92386dec7dc191d2 Mon Sep 17 00:00:00 2001 From: ikbear Date: Mon, 14 Jan 2013 15:37:31 +0800 Subject: [PATCH 4/5] fix fd close and enableCrc32Check bug --- CHANGELOG.md | 1 - lib/rs.js | 17 +++++++++-------- lib/util.js | 8 +++----- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 555ea0ae..fab57a52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,4 +16,3 @@ updated: updated: - 启用新的 uploadToken(上传凭证)上传方式,可由客户方业务服务器生成上传凭证。上传前无需请求七牛云存储,减少http请求。 -- 增加断点续上传支持,并行断点传输速度更快 diff --git a/lib/rs.js b/lib/rs.js index b244c363..647c630d 100644 --- a/lib/rs.js +++ b/lib/rs.js @@ -117,16 +117,17 @@ Service.prototype.uploadFile = function(upToken, key, mimeType, localFile, onret }); }; -Service.prototype.uploadWithToken = function(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, fileCrc32, onret) { +Service.prototype.uploadWithToken = function(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret) { /* - * func UploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, fileCrc32, onret) => (data PutRet, code int, err Error) + * func UploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret) => (data PutRet, code int, err Error) * 使用upload_token以multipart/form-data形式上传ReadStream流 **/ var bucket = this.bucket; if (!mimeType) { mimeType = "application/octet-stream"; } - var actionString = util.generateActionString(bucket, key, mimeType, customMeta, enableCrc32Check, fileCrc32); + + var actionString = util.generateActionString(bucket, key, mimeType, customMeta, enableCrc32Check); if (callbackParams === null) { callbackParams = { "bucket": bucket, @@ -164,20 +165,20 @@ Service.prototype.uploadFileWithToken = function(uploadToken, localFile, key, mi onret({code: -1, error: err.toString(), detail: err}); return; } - var fileCrc32 = '' - , stream = fs.createReadStream(localFile); + var 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); - fileCrc32 = parseInt("0x" + crc32(buf)).toString(); + fs.closeSync(fd); + enableCrc32Check = parseInt("0x" + crc32(buf)).toString(); } - return self.uploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, fileCrc32, onret); + self.uploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret); }); }; diff --git a/lib/util.js b/lib/util.js index 43adef85..a6a086c3 100644 --- a/lib/util.js +++ b/lib/util.js @@ -15,7 +15,7 @@ exports.encode = function(v) { return exports.base64ToUrlsafe(encoded); }; -exports.generateActionString = function(bucket, key, mimeType, customMeta, enableCrc32Check, fileCrc32) { +exports.generateActionString = function(bucket, key, mimeType, customMeta, enableCrc32Check) { if (!key) { console.error("Please specify your key!"); return; @@ -29,10 +29,8 @@ exports.generateActionString = function(bucket, key, mimeType, customMeta, enabl actionParams += '/meta/' + this.encode(customMeta); } if (enableCrc32Check) { - if ((fileCrc32 !== undefined) && (fileCrc32 !== null)) { - actionParams += '/crc32/' + fileCrc32; - } - } + actionParams += '/crc32/' + enableCrc32Check; + } return actionParams; } From c55014b8a475b3e3d786ae346b9a406ad5615a00 Mon Sep 17 00:00:00 2001 From: ikbear Date: Tue, 15 Jan 2013 00:21:51 +0800 Subject: [PATCH 5/5] fix crc32 and action string bug --- lib/auth.js | 16 ++++++++++++---- lib/rs.js | 13 +++++++------ lib/util.js | 6 +++--- 3 files changed, 22 insertions(+), 13 deletions(-) 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 647c630d..bb4756ce 100644 --- a/lib/rs.js +++ b/lib/rs.js @@ -117,9 +117,9 @@ Service.prototype.uploadFile = function(upToken, key, mimeType, localFile, onret }); }; -Service.prototype.uploadWithToken = function(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret) { +Service.prototype.uploadWithToken = function(uploadToken, stream, key, mimeType, customMeta, callbackParams, crc32, onret) { /* - * func UploadWithToken(uploadToken, 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; @@ -127,7 +127,7 @@ Service.prototype.uploadWithToken = function(uploadToken, stream, key, mimeType, mimeType = "application/octet-stream"; } - var actionString = util.generateActionString(bucket, key, mimeType, customMeta, enableCrc32Check); + var actionString = util.generateActionString(bucket, key, mimeType, customMeta, crc32); if (callbackParams === null) { callbackParams = { "bucket": bucket, @@ -165,7 +165,8 @@ Service.prototype.uploadFileWithToken = function(uploadToken, localFile, key, mi onret({code: -1, error: err.toString(), detail: err}); return; } - var stream = fs.createReadStream(localFile); + var fileCrc32 = null + , stream = fs.createReadStream(localFile); if (enableCrc32Check) { var fileStat = fs.statSync(localFile) @@ -175,10 +176,10 @@ Service.prototype.uploadFileWithToken = function(uploadToken, localFile, key, mi fs.readSync(fd, buf, 0, fileSize, 0); fs.closeSync(fd); - enableCrc32Check = parseInt("0x" + crc32(buf)).toString(); + fileCrc32 = parseInt("0x" + crc32(buf)).toString(); } - self.uploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, enableCrc32Check, onret); + self.uploadWithToken(uploadToken, stream, key, mimeType, customMeta, callbackParams, fileCrc32, onret); }); }; diff --git a/lib/util.js b/lib/util.js index a6a086c3..bc81a9dc 100644 --- a/lib/util.js +++ b/lib/util.js @@ -15,7 +15,7 @@ exports.encode = function(v) { return exports.base64ToUrlsafe(encoded); }; -exports.generateActionString = function(bucket, key, mimeType, customMeta, enableCrc32Check) { +exports.generateActionString = function(bucket, key, mimeType, customMeta, crc32) { if (!key) { console.error("Please specify your key!"); return; @@ -28,8 +28,8 @@ exports.generateActionString = function(bucket, key, mimeType, customMeta, enabl if (customMeta !== "") { actionParams += '/meta/' + this.encode(customMeta); } - if (enableCrc32Check) { - actionParams += '/crc32/' + enableCrc32Check; + if ((crc32 !== undefined) && (crc32 !== null) && (crc32 !== "")) { + actionParams += '/crc32/' + crc32; } return actionParams; }