{"version":3,"sources":["jsdelivr-header.js","/npm/esdk-obs-nodejs@3.26.2/lib/obs.js"],"names":[],"mappings":"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","file":"/npm/esdk-obs-nodejs@3.26.2/lib/obs.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/esdk-obs-nodejs@3.26.2/lib/obs.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","﻿/**\n * Copyright 2019 Huawei Technologies Co.,Ltd.\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n * this file except in compliance with the License.  You may obtain a copy of the\n * License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed\n * under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n * CONDITIONS OF ANY KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations under the License.\n *\n */\n\nconst util = require('util');\nconst Utils = require('./utils');\nconst LogUtil = require('./log');\nconst enums = require('./enums');\nconst {\n\tMAX_UPLOAD_PART_COUNT,\n\n\tMIN_UPLOAD_PART_SIZE,\n\tMAX_UPLOAD_PART_SIZE,\n\tDEFAULT_UPLOAD_PART_SIZE,\n\n\tMIN_DOWNLOAD_PART_SIZE,\n\tMAX_DOWNLOAD_PART_SIZE,\n\tDEFAULT_DOWNLOAD_PART_SIZE,\n} = enums;\nfunction ObsClient(param){\n\tthis.factory(param);\n}\n\nfunction capitalize(key){\n\treturn key.slice(0,1).toUpperCase() + key.slice(1);\n}\n\nconst methods = [\n    'headBucket',\n    'getBucketMetadata',\n    'deleteBucket',\n    'setBucketQuota',\n    'getBucketQuota',\n    'getBucketStorageInfo',\n    'setBucketPolicy',\n    'getBucketPolicy',\n    'deleteBucketPolicy',\n    'setBucketVersioningConfiguration',\n    'getBucketVersioningConfiguration',\n    'getBucketLocation',\n    'listVersions',\n    'listObjects',\n    'setBucketLifecycleConfiguration',\n    'getBucketLifecycleConfiguration',\n    'deleteBucketLifecycleConfiguration',\n    'setBucketAcl',\n    'getBucketAcl',\n    'setBucketLoggingConfiguration',\n    'getBucketLoggingConfiguration',\n    'setBucketWebsiteConfiguration',\n    'getBucketWebsiteConfiguration',\n    'deleteBucketWebsiteConfiguration',\n    'setBucketNotification',\n    'getBucketNotification',\n    'setBucketTagging',\n    'deleteBucketTagging',\n    'getBucketTagging',\n    'setObjectTagging',\n    'deleteObjectTagging',\n    'getObjectTagging',\n    'setBucketReplication',\n    'deleteBucketReplication',\n    'getBucketReplication',\n    'getObject',\n    'setObjectMetadata',\n    'getObjectMetadata',\n    'setObjectAcl',\n    'getObjectAcl',\n    'deleteObject',\n    'deleteObjects',\n    'listMultipartUploads',\n    'listParts',\n    'abortMultipartUpload',\n    'completeMultipartUpload',\n    'setBucketCors',\n    'getBucketCors',\n    'deleteBucketCors',\n    'optionsBucket',\n    'optionsObject',\n    'setBucketStoragePolicy',\n    'getBucketStoragePolicy',\n    'getBucketEncryption',\n    'setBucketEncryption',\n    'deleteBucketEncryption',\n    'getBucketDirectColdAccess',\n    'setBucketDirectColdAccess',\n    'deleteBucketDirectColdAccess',\n    'renameObject',\n    'getBucketRequesterPayment',\n    'setBucketRequesterPayment',\n    'putBucketPublicAccessBlock',\n    'getBucketPublicAccessBlock',\n    'deleteBucketPublicAccessBlock',\n    'getBucketPolicyPublicStatus',\n    'getBucketPublicStatus',\n    'setBucketCustomDomain',\n    'getBucketCustomDomain',\n    'deleteBucketCustomDomain',\n];\n\nfunction createAction(method){\n\treturn function(param, callback){\n\t\tthis.exec(capitalize(method), param, callback);\n\t};\n}\n\nfor(let i=0;i<methods.length;i++){\n\tlet method = methods[i];\n\tObsClient.prototype[method] = createAction(method);\n}\n\nObsClient.prototype.createBucket = function(param, callback){\n\tif(this.util && this.util.isCname){\n\t\treturn callback('createBucket is not allowed in customdomain mode', null);\n\t}\n\tthis.exec('CreateBucket', param, callback);\n};\n\nObsClient.prototype.listBuckets = function(param, callback){\n\tif(this.util && this.util.isCname){\n\t\treturn callback('listBuckets is not allowed in customdomain mode', null);\n\t}\n\tthis.exec('ListBuckets', param, callback);\n};\n\nObsClient.prototype.putObject = function(param, callback){\n\t\n\tif(('Body' in param) && ('SourceFile' in param)){\n\t\tlet err = 'the input body and sourcefile exist at same time,please specify one of eigther a string or file to be send!';\n\t\tif(this.log.isLevelEnabled('error')){\n\t\t\tthis.log.runLog('error', 'PutObject', err);\n\t\t}\n\t\treturn callback(new Error(err), null);\n\t}\n\t\n\tif(!('ContentType' in param)){\n\t\tif('Key' in param){\n\t\t\tparam.ContentType = this.util.mimeTypes[param.Key.substring(param.Key.lastIndexOf('.') + 1)];\n\t\t}\n\t\tif(!param.ContentType && ('SourceFile' in param)){\n\t\t\tparam.ContentType = this.util.mimeTypes[param.SourceFile.substring(param.SourceFile.lastIndexOf('.') + 1)];\n\t\t}\n\t}\n\t\n\tthis.exec('PutObject', param, callback);\n};\n\nObsClient.prototype.modifyObject = function(param, callback){\n\n\tif(('Body' in param) && ('SourceFile' in param)){\n\t\tlet err = 'the input body and sourcefile exist at same time,please specify one of eigther a string or file to be send!';\n\t\tif(this.log.isLevelEnabled('error')){\n\t\t\tthis.log.runLog('error', 'ModifyObject', err);\n\t\t}\n\t\treturn callback(new Error(err), null);\n\t}\n\n\tif(!('ContentType' in param)){\n\t\tif('Key' in param){\n\t\t\tparam.ContentType = this.util.mimeTypes[param.Key.substring(param.Key.lastIndexOf('.') + 1)];\n\t\t}\n\t\tif(!param.ContentType && ('SourceFile' in param)){\n\t\t\tparam.ContentType = this.util.mimeTypes[param.SourceFile.substring(param.SourceFile.lastIndexOf('.') + 1)];\n\t\t}\n\t}\n\n\tthis.exec('ModifyObject', param, callback);\n};\n\nObsClient.prototype.appendObject = function(param, callback){\n\t\n\tif(('Body' in param) && ('SourceFile' in param)){\n\t\tlet err = 'the input body and sourcefile exist at same time,please specify one of eigther a string or file to be send!';\n\t\tif(this.log.isLevelEnabled('error')){\n\t\t\tthis.log.runLog('error', 'PutObject', err);\n\t\t}\n\t\treturn callback(new Error(err), null);\n\t}\n\t\n\tif(!('ContentType' in param)){\n\t\tif('Key' in param){\n\t\t\tparam.ContentType = this.util.mimeTypes[param.Key.substring(param.Key.lastIndexOf('.') + 1)];\n\t\t}\n\t\tif(!param.ContentType && ('SourceFile' in param)){\n\t\t\tparam.ContentType = this.util.mimeTypes[param.SourceFile.substring(param.SourceFile.lastIndexOf('.') + 1)];\n\t\t}\n\t}\n\t\n\tthis.exec('AppendObject', param, callback);\n};\n\nObsClient.prototype.copyObject = function(param, callback){\n\tlet key = 'CopySource';\n\tif(key in param){\n\t\tlet val = param[key];\n\t\tlet index = val.lastIndexOf('?versionId=');\n\t\tif(index > 0){\n\t\t\tparam[key] = this.util.encodeURIWithSafe(val.slice(0, index)) + val.slice(index);\n\t\t}else{\n\t\t\tparam[key] = this.util.encodeURIWithSafe(val);\n\t\t}\n\t}\n\tthis.exec('CopyObject', param, callback);\n};\n\nObsClient.prototype.copyPart = function(param, callback){\n\tlet key = 'CopySource';\n\tif(key in param){\n\t\tlet val = param[key];\n\t\tlet index = val.lastIndexOf('?versionId=');\n\t\tif(index > 0){\n\t\t\tparam[key] = this.util.encodeURIWithSafe(val.slice(0, index)) + val.slice(index);\n\t\t}else{\n\t\t\tparam[key] = this.util.encodeURIWithSafe(val);\n\t\t}\n\t}\n\tthis.exec('CopyPart', param, callback);\n};\n\nObsClient.prototype.restoreObject = function(param, callback){\n\tthis.exec('RestoreObject', param, function(err, result){\n\t\tif(!err && result.InterfaceResult && result.CommonMsg.Status < 300){\n\t\t\tresult.InterfaceResult.RestoreStatus = result.CommonMsg.Status === 200 ? 'AVALIABLE' : 'INPROGRESS';\n\t\t}\n\t\tcallback(err, result);\n\t});\n};\n\nObsClient.prototype.initiateMultipartUpload = function(param, callback){\n\tif(!('ContentType' in param) && 'Key' in param){\n\t\tparam.ContentType = this.util.mimeTypes[param.Key.substring(param.Key.lastIndexOf('.') + 1)];\n\t}\n\tthis.exec('InitiateMultipartUpload', param, callback);\n};\n\n\nObsClient.prototype.uploadPart = function(param, callback){\n\tif(('Body' in param) && ('SourceFile' in param)){\n\t\tlet err = 'the input body and sourcefile exist at same time,please specify one of eigther a string or file to be send!';\n\t\tif(this.log.isLevelEnabled('error')){\n\t\t\tthis.log.runLog('error', 'UploadPart', err);\n\t\t}\n\t\treturn callback(new Error(err), null);\n\t}\n\tthis.exec('UploadPart', param, callback);\n};\n\n\nObsClient.prototype.uploadFile = function(param, callback){\n\tparam = param || {};\n\tlet _log = this.log;\n\tlet obsClient = this;\n\tlet funcName = 'uploadFile';\n\tlet start = new Date().getTime();\n\t// 接收参数\n\tlet progressCallback = param.ProgressCallback || function(){};\n\tlet resumeCallback = param.ResumeCallback || function(){};\n\tcallback = callback || function(){};\n\tlet _callback = function(code, message, result){\n\t\tif(_log.isLevelEnabled('info')){\n\t\t\t_log.runLog('info', funcName, 'ObsClient cost ' +  (new Date().getTime()-start) + ' ms');\n\t\t}\n\t\tif(typeof code === 'string'){\n\t\t\tif(message){\n\t\t\t\tcode += ':' + String(message);\n\t\t\t}\n\t\t\tcallback(code, result);\n\t\t\treturn;\n\t\t}\n\t\tcallback(code ? (code.CommonMsg.Code + ':' + code.CommonMsg.Message) : null, result);\n\t};\n\t\n\tif(_log.isLevelEnabled('info')){\n\t\t_log.runLog('info', funcName, 'enter ' + funcName + '...' );\n\t}\n\n\tlet bucket = param.Bucket;\n\tif(!bucket){\n\t\t_callback('InvalidArgument','Bucket is a required element!');\n\t\treturn;\n\t}\n\tbucket = String(bucket);\n\n\tlet key = param.Key;\n\tif(!key){\n\t\t_callback('InvalidArgument', 'Key is a required element!');\n\t\treturn;\n\t}\n\tkey = String(key);\n\n\tlet uploadFile = param.UploadFile;\n\tif(!uploadFile){\n\t\t_callback('InvalidArgument', 'UploadFile is a required element!');\n\t\treturn;\n\t}\n\tlet fs = require('fs');\n\tuploadFile = String(uploadFile); \n\t\n\tif(!fs.existsSync(uploadFile)){\n\t\t_callback('InvalidArgument', 'UploadFile does not exist!');\n\t\treturn;\n\t}\n\tlet fstat = fs.statSync(uploadFile);\n\tif(!fstat.isFile()){\n\t\t_callback('InvalidArgument', 'UploadFile is not a file!');\n\t\treturn;\n\t}\n\t\n\tlet fileSize = fstat.size;\n\t\n\tlet enableCheckpoint = param.EnableCheckpoint;\n\tlet checkpointFile = null;\n\tlet enableCheckSum = false;\n\n\tlet taskNum = parseInt(param.TaskNum, 10) || 20;\n\t\n\tif(enableCheckpoint){\n\t\tcheckpointFile = param.CheckpointFile;\n\t\tcheckpointFile = (checkpointFile && checkpointFile !== '') ? String(checkpointFile) : uploadFile + '.upload_record';\n\t\tlet pathLib = require('path');\n\t\tlet fileDir = pathLib.dirname(checkpointFile);\n\t\tif(!fs.existsSync(fileDir)){\n\t\t\tlet mkdirsSync = function(dirname){\n\t\t\t    if(fs.existsSync(dirname)){\n\t\t\t        return true;\n\t\t\t    }else{\n\t\t\t        if(mkdirsSync(pathLib.dirname(dirname))){\n\t\t\t            fs.mkdirSync(dirname);\n\t\t\t            return true;\n\t\t\t        }\n\t\t\t    }\n\t\t\t};\n\t\t\tmkdirsSync(fileDir);\n\t\t}\n\t\tenableCheckSum = param.EnableCheckSum;\n\t}\n\tif(_log.isLevelEnabled('debug')){\n\t\t_log.runLog('debug', funcName, 'Begin to uploadFile to OBS from file:' + uploadFile);\n\t}\n\t\n\tlet events = require('events');\n\tlet eventEmitter = new events.EventEmitter();\n\t\n\tlet calculateUploadCheckpointMD5 = function(uploadCheckpoint){\n\t\tlet data = [];\n\t\tdata.push(uploadCheckpoint.bucketName);\n\t\tdata.push(uploadCheckpoint.objectKey);\n\t\tdata.push(uploadCheckpoint.uploadFile);\n\t\tdata.push(String(uploadCheckpoint.partSize));\n\t\tdata.push(String(uploadCheckpoint.partCount));\n\t\tif(uploadCheckpoint.contentType){\n\t\t\tdata.push(uploadCheckpoint.contentType);\n\t\t}\n\t\tif(uploadCheckpoint.acl){\n\t\t\tdata.push(uploadCheckpoint.acl);\n\t\t}\n\t\tif(uploadCheckpoint.websiteRedirectLocation){\n\t\t\tdata.push(uploadCheckpoint.websiteRedirectLocation);\n\t\t}\n\t\tif(uploadCheckpoint.sseKms){\n\t\t\tdata.push(uploadCheckpoint.sseKms);\n\t\t}\n\t\tif(uploadCheckpoint.sseKmsKey){\n\t\t\tdata.push(uploadCheckpoint.sseKmsKey);\n\t\t}\n\t\tif(uploadCheckpoint.sseC){\n\t\t\tdata.push(uploadCheckpoint.sseC);\n\t\t}\n\t\tif(uploadCheckpoint.sseCKey){\n\t\t\tdata.push(uploadCheckpoint.sseCKey);\n\t\t}\n\t\tif(uploadCheckpoint.metadata){\n\t\t\tdata.push(JSON.stringify(uploadCheckpoint.metadata));\n\t\t}\n\t\tif(uploadCheckpoint.uploadId){\n\t\t\tdata.push(uploadCheckpoint.uploadId);\n\t\t}\n\t\tif(uploadCheckpoint.partsMeta && (uploadCheckpoint.partsMeta instanceof Object)){\n\t\t\tfor(let key in uploadCheckpoint.partsMeta){\n\t\t\t\tif ({}.hasOwnProperty.call(uploadCheckpoint.partsMeta, key)) {\n\t\t\t\t\tdata.push(String(key));\n\t\t\t\t\tlet partMeta = uploadCheckpoint.partsMeta[key];\n\t\t\t\t\tif(partMeta){\n\t\t\t\t\t\tdata.push(String(partMeta.offset));\n\t\t\t\t\t\tdata.push(String(partMeta.partSize));\n\t\t\t\t\t\tdata.push(String(partMeta.isCompleted));\n\t\t\t\t\t\tdata.push(String(partMeta.etag));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn obsClient.util.bufMD5(Buffer.from(data.join(''), 'utf8'));\n\t};\n\t\n\tlet writeCheckpointFileSync = function(checkpointFile, uploadCheckpoint){\n\t\ttry{\n\t\t\tfs.writeFileSync(checkpointFile, JSON.stringify(uploadCheckpoint));\n\t\t\treturn true;\n\t\t}catch(e){\n\t\t\t_callback('WriteCheckpointFileError', e);\n\t\t\tif(_log.isLevelEnabled('debug')){\n\t\t\t\t_log.runLog('debug', funcName, 'Write checkpoint file failed and abort upload, uploadId ' + uploadCheckpoint.uploadId);\n\t\t\t}\n\t\t\tif(uploadCheckpoint.uploadId){\n\t\t\t\tobsClient.abortMultipartUpload({\n\t\t\t\t\tBucket:uploadCheckpoint.bucketName,\n\t\t\t\t\tKey:uploadCheckpoint.objectKey,\n\t\t\t\t\tUploadId:uploadCheckpoint.uploadId,\n\t\t\t\t},function(e, r){\n\t\t\t\t\tif(!e && (r.CommonMsg.Status < 300 || r.CommonMsg.Status === 404)){\n\t\t\t\t\t\tfs.unlink(checkpointFile, function(){});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}else{\n\t\t\t\tfs.unlink(checkpointFile, function(){});\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t};\n\t\n\tlet abortRequest = function(uploadCheckpoint, checkpointFile, code, message){\n\t\tif(uploadCheckpoint && uploadCheckpoint.uploadId){\n\t\t\tobsClient.abortMultipartUpload({\n\t\t\t\tBucket:uploadCheckpoint.bucketName,\n\t\t\t\tKey:uploadCheckpoint.objectKey,\n\t\t\t\tUploadId:uploadCheckpoint.uploadId,\n\t\t\t},function(e, r){\n\t\t\t\tif(!e && (r.CommonMsg.Status < 300 || r.CommonMsg.Status === 404)){\n\t\t\t\t\tif(checkpointFile){\n\t\t\t\t\t\tfs.unlink(checkpointFile, function(){});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t_callback(code, message);\n\t\t\t});\n\t\t}else{\n\t\t\tif(checkpointFile){\n\t\t\t\tfs.unlink(checkpointFile, function(){});\n\t\t\t}\n\t\t\t_callback(code, message);\n\t\t}\n\t};\n\t\n\tlet transResultToError = function(result){\n\t\tlet ret = [];\n\t\tif(result && result.CommonMsg){\n\t\t\tret.push('Status:' + result.CommonMsg.Status);\n\t\t\tret.push('Code:' + result.CommonMsg.Code);\n\t\t\tret.push('Message:' + result.CommonMsg.Message);\n\t\t}\n\t\treturn ret.join(',');\n\t};\n\t\n\teventEmitter.on('start to uploadFile', function(uploadCheckpoint){\n\t\tif(!uploadCheckpoint){\n\t\t\tuploadCheckpoint = {};\n\t\t}\n\t\tif(!uploadCheckpoint.partsMeta){\n\t\t\tuploadCheckpoint.partsMeta = {};\n\t\t}\n\t\tlet startToUploadFile = function(uploadId){\n\t\t\tlet finishedCount = 0;\n\t\t\tlet hasError = false;\n\t\t\tlet isAbort = false;\n\t\t\tlet finishedBytes = 0;\n\t\t\tif(uploadCheckpoint.partsMeta){\n\t\t\t\tfor(let i of Object.keys(uploadCheckpoint.partsMeta)){\n\t\t\t\t\tif(uploadCheckpoint.partsMeta[i].isCompleted){\n\t\t\t\t\t\tfinishedBytes += uploadCheckpoint.partSize\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet partsLoaded = {};\n\t\t\tlet startTime = new Date().getTime();\n\n\t\t\tresumeCallback({\n\t\t\t\tcancel : function(){\n\t\t\t\t\tisAbort = true;\n\t\t\t\t\t_callback('Upload suspened', 'The process of uploadFile is suspened, you can try again')\n\t\t\t\t},\n\t\t\t\tabort : function(){\n\t\t\t\t\tisAbort = true;\n\t\t\t\t\tabortRequest(uploadCheckpoint, checkpointFile, 'Upload isAbort', 'The process of uploadFile is isAbort');\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tlet progressCallbacks = function(partNumber, loaded){\n\t\t\t\tif(isAbort){\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfinishedBytes += loaded;\n\t\t\t\tif(partsLoaded[partNumber]){\n\t\t\t\t\tfinishedBytes -= partsLoaded[partNumber];\n\t\t\t\t}\n\t\t\t\tpartsLoaded[partNumber] = loaded;\n\t\t\t\tprogressCallback(finishedBytes, uploadCheckpoint.uploadFileStat.fileSize, (new Date().getTime() - startTime) / 1000);\n\t\t\t}; \n\n\t\t\t// 段进度\n\t\t\tlet createProgressCallbackByPartNumber = function(partNumber){\n\t\t\t\treturn function(loaded, total, cost){\n\t\t\t\t\tprogressCallbacks(partNumber, loaded);\n\t\t\t\t};\n\t\t\t};\n\t\t\tlet completedRequest = function(){\n\t\t\t\tif(finishedCount === uploadCheckpoint.partCount){\n\t\t\t\t\tif(!hasError){\n\t\t\t\t\t\tlet parts = [];\n\t\t\t\t\t\tfor(let partNumber in uploadCheckpoint.partsMeta){\n\t\t\t\t\t\t\tif ({}.hasOwnProperty.call(uploadCheckpoint.partsMeta, partNumber)) {\n\t\t\t\t\t\t\t\tparts.push({\n\t\t\t\t\t\t\t\t\tPartNumber : partNumber,\n\t\t\t\t\t\t\t\t\tETag : uploadCheckpoint.partsMeta[partNumber].etag\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tobsClient.completeMultipartUpload({\n\t\t\t\t\t\t\tBucket: uploadCheckpoint.bucketName,\n\t\t\t\t\t\t\tKey : uploadCheckpoint.objectKey,\n\t\t\t\t\t\t\tUploadId : uploadId,\n\t\t\t\t\t\t\tParts: parts\n\t\t\t\t\t\t}, function(err, result){\n\t\t\t\t\t\t\tif(err || result.CommonMsg.Status >= 500){ \n\t\t\t\t\t\t\t\tif(checkpointFile){\n\t\t\t\t\t\t\t\t\t_callback('IncompletedUpload', err ? err : transResultToError(result));\n\t\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\t\tabortRequest(uploadCheckpoint, checkpointFile, 'UploadFileFailed', err ? err : transResultToError(result));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}else if(result.CommonMsg.Status >= 300 && result.CommonMsg.Status < 500){\n\t\t\t\t\t\t\t\tabortRequest(uploadCheckpoint, checkpointFile, result.CommonMsg.Code, result.CommonMsg.Message);\n\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\tif(checkpointFile){\n\t\t\t\t\t\t\t\t\tfs.unlink(checkpointFile, function(){});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t_callback(null, null, result);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}else{\n\t\t\t\t\t\tif(checkpointFile){\n\t\t\t\t\t\t\t_callback('IncompletedUpload','UploadFile finished with error, you can retry with the same parameters');\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\tabortRequest(uploadCheckpoint, checkpointFile, 'UploadFileFailed', 'UploadFile finished with error!');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\t\n\t\t\teventEmitter.on('doUpload', function(currentGroupIndex, groupCount, taskNum){\n\t\t\t\tlet start = (currentGroupIndex - 1) * taskNum;\n\t\t\t\tlet end = (currentGroupIndex === groupCount) ? uploadCheckpoint.partCount : currentGroupIndex * taskNum;\n\t\t\t\tlet finishedCountGroup = 0;\n\t\t\t\twhile(start<end){\n\t\t\t\t\tif(isAbort){\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tlet partNumber = start + 1;\n\t\t\t\t\tif(uploadCheckpoint.partsMeta[partNumber] && uploadCheckpoint.partsMeta[partNumber].isCompleted){\n\t\t\t\t\t\tfinishedCount++;\n\t\t\t\t\t\tfinishedCountGroup++;\n\t\t\t\t\t\tlet _taskNum = (currentGroupIndex === groupCount) ? (uploadCheckpoint.partCount - (currentGroupIndex - 1) * taskNum) : taskNum;\n\t\t\t\t\t\tif(finishedCountGroup === _taskNum && finishedCount < uploadCheckpoint.partCount){\n\t\t\t\t\t\t\teventEmitter.emit('doUpload', currentGroupIndex + 1, groupCount, taskNum);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcompletedRequest();\n\t\t\t\t\t}else{\n\t\t\t\t\t\tlet offset = start * uploadCheckpoint.partSize;\n\t\t\t\t\t\tlet currPartSize = (start + 1 === uploadCheckpoint.partCount) ? uploadCheckpoint.uploadFileStat.fileSize - offset : uploadCheckpoint.partSize;\n\t\t\t\t\t\tobsClient.uploadPart({\n\t\t\t\t\t\t\tBucket : uploadCheckpoint.bucketName,\n\t\t\t\t\t\t\tKey: uploadCheckpoint.objectKey,\n\t\t\t\t\t\t\tPartNumber: partNumber,\n\t\t\t\t\t\t\tUploadId : uploadId,\n\t\t\t\t\t\t\tSourceFile: uploadCheckpoint.uploadFile,\n\t\t\t\t\t\t\tOffset : offset,\n\t\t\t\t\t\t\tPartSize : currPartSize,\n\t\t\t\t\t\t\tSseC : uploadCheckpoint.sseC,\n\t\t\t\t\t\t\tSseCKey : uploadCheckpoint.sseCKey,\n\t\t\t\t\t\t\tProgressCallback : createProgressCallbackByPartNumber(partNumber),\n\t\t\t\t\t\t}, function(err, result) {\n\t\t\t\t\t\t\tif(isAbort){\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlet partMeta = {offset : offset, partSize : currPartSize};\n\t\t\t\t\t\t\tif(err || result.CommonMsg.Status >= 500){\n\t\t\t\t\t\t\t\tpartMeta.isCompleted = false;\n\t\t\t\t\t\t\t\thasError = true;\n\t\t\t\t\t\t\t}else if(result.CommonMsg.Status >= 300 && result.CommonMsg.Status < 500){\n\t\t\t\t\t\t\t\tisAbort = true;\n\t\t\t\t\t\t\t\tabortRequest(uploadCheckpoint, checkpointFile, result.CommonMsg.Code, result.CommonMsg.Message);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\tpartMeta.etag = result.InterfaceResult.ETag;\n\t\t\t\t\t\t\t\tpartMeta.isCompleted = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tuploadCheckpoint.partsMeta[partNumber] = partMeta;\n\t\t\t\t\t\t\tif(_log.isLevelEnabled('debug')){\n\t\t\t\t\t\t\t\t_log.runLog('debug', funcName, 'Part ' + String(partNumber) + ' is finished, uploadId ' + uploadId);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tuploadCheckpoint.md5 = calculateUploadCheckpointMD5(uploadCheckpoint);\n\t\t\t\t\t\t\tif(checkpointFile && !writeCheckpointFileSync(checkpointFile, uploadCheckpoint)){\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfinishedCount++;\n\t\t\t\t\t\t\tfinishedCountGroup++;\n\t\t\t\t\t\t\tlet _taskNum = (currentGroupIndex === groupCount) ? (uploadCheckpoint.partCount - (currentGroupIndex - 1) * taskNum) : taskNum;\n\t\t\t\t\t\t\tif(finishedCountGroup === _taskNum && finishedCount < uploadCheckpoint.partCount){\n\t\t\t\t\t\t\t\teventEmitter.emit('doUpload', currentGroupIndex + 1, groupCount, taskNum);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcompletedRequest();\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tstart++;\n\t\t\t\t}\n\t\t\t});\n\t\t\t\n\t\t\tlet groupCount = (uploadCheckpoint.partCount % taskNum === 0) ? (uploadCheckpoint.partCount / taskNum) : (Math.floor(uploadCheckpoint.partCount / taskNum) + 1);\n\t\t\teventEmitter.emit('doUpload', 1, groupCount, taskNum);\n\t\t};\n\t\t\n\t\tlet uploadId = uploadCheckpoint.uploadId;\n\t\tif(!uploadId){\n\t\t\tlet contentType = uploadCheckpoint.contentType ? uploadCheckpoint.contentType : obsClient.util.mimeTypes[key.substring(key.lastIndexOf('.') + 1)];\n\t\t\t\n\t\t\tif(!contentType){\n\t\t\t\tcontentType = obsClient.util.mimeTypes[uploadFile.substring(uploadFile.lastIndexOf('.') + 1)];\n\t\t\t}\n\t\t\t\n\t\t\tobsClient.initiateMultipartUpload({\n\t\t\t\tBucket : uploadCheckpoint.bucketName,\n\t\t\t\tKey : uploadCheckpoint.objectKey,\n\t\t\t\tACL : uploadCheckpoint.acl,\n\t\t\t\tMetadata : uploadCheckpoint.metadata,\n\t\t\t\tWebsiteRedirectLocation : uploadCheckpoint.websiteRedirectLocation,\n\t\t\t\tContentType : contentType,\n\t\t\t\tSseKms : uploadCheckpoint.sseKms,\n\t\t\t\tSseKmsKey : uploadCheckpoint.sseKmsKey,\n\t\t\t\tSseC : uploadCheckpoint.sseC,\n\t\t\t\tSseCKey : uploadCheckpoint.sseCKey,\n\t\t\t\tExpires : uploadCheckpoint.expires\n\t\t\t}, function(err, result){\n\t\t\t\tif(err){\n\t\t\t\t\tif(checkpointFile){\n\t\t\t\t\t\tfs.unlink(checkpointFile, function(){});\n\t\t\t\t\t}\n\t\t\t\t\t_callback('InitateMultipartUploadFailed',err);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(result.CommonMsg.Status >= 300){\n\t\t\t\t\tif(checkpointFile){\n\t\t\t\t\t\tfs.unlink(checkpointFile, function(){});\n\t\t\t\t\t}\n\t\t\t\t\t_callback(result);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tuploadId = result.InterfaceResult.UploadId;\n\t\t\t\tuploadCheckpoint.uploadId = uploadId;\n\t\t\t\tuploadCheckpoint.md5 = calculateUploadCheckpointMD5(uploadCheckpoint);\n\t\t\t\tif(_log.isLevelEnabled('debug')){\n\t\t\t\t\t_log.runLog('debug', funcName, 'Claim a new upload id ' + uploadId);\n\t\t\t\t}\n\t\t\t\tif(checkpointFile && !writeCheckpointFileSync(checkpointFile, uploadCheckpoint)){\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tstartToUploadFile(uploadId);\n\t\t\t});\n\t\t}else{\n\t\t\tstartToUploadFile(uploadId);\n\t\t}\n\t});\n\t\n\tlet uploadCheckpoint;\n\tlet partSize = parseInt(param.PartSize, 10);\n\tlet partCount;\n\tif(fileSize === 0){\n\t\tpartSize = 0;\n\t\tpartCount = 1;\n\t}else{\n\t\tif (isNaN(partSize) || partSize < MIN_UPLOAD_PART_SIZE || partSize > MAX_UPLOAD_PART_SIZE) {\n\t\t\tpartSize = DEFAULT_UPLOAD_PART_SIZE;\n\t\t}\n\t\tpartCount = Math.floor(fileSize / partSize);\n\t\tif (partCount > MAX_UPLOAD_PART_COUNT) {\n\t\t\tpartCount = MAX_UPLOAD_PART_COUNT;\n\t\t\tpartSize = Math.ceil(fileSize / partCount);\n\t\t} else {\n\t\t\tif(fileSize % partSize !== 0){\n\t\t\t\tpartCount++;\n\t\t\t}\n\t\t}\n\t}\n\tif(_log.isLevelEnabled('debug')){\n\t\t_log.runLog('debug', funcName, 'Total parts count ' + partCount);\n\t}\n\tuploadCheckpoint = {bucketName: bucket, objectKey: key, uploadFile : uploadFile, partSize : partSize, partCount : partCount};\n\tuploadCheckpoint.contentType = param.ContentType;\n\tuploadCheckpoint.acl = param.ACL;\n\tuploadCheckpoint.websiteRedirectLocation = param.WebsiteRedirectLocation;\n\tuploadCheckpoint.sseKms = param.SseKms;\n\tuploadCheckpoint.sseKmsKey = param.SseKmsKey;\n\tuploadCheckpoint.sseC = param.sseC;\n\tuploadCheckpoint.sseCKey = param.SseCKey;\n\tuploadCheckpoint.metadata = param.Metadata;\n\tuploadCheckpoint.expires = param.Expires;\n\tuploadCheckpoint.md5 = calculateUploadCheckpointMD5(uploadCheckpoint);\n\tuploadCheckpoint.uploadFileStat = {fileSize : fileSize, lastModified : fstat.mtime.toUTCString()};\n\t\n\tif(checkpointFile){\n\t\tif(!fs.existsSync(checkpointFile)){// call uploadFile first time\n\t\t\teventEmitter.on('start to writeFile', function(){\n\t\t\t\tfs.writeFile(checkpointFile, JSON.stringify(uploadCheckpoint), function(err){\n\t\t\t\t\tif(err){\n\t\t\t\t\t\t_callback('WriteCheckpointFileError',err);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\teventEmitter.emit('start to uploadFile', uploadCheckpoint);\n\t\t\t\t});\n\t\t\t});\n\t\t\tif(enableCheckSum){\n\t\t\t\tobsClient.util.fileMD5(uploadFile, function(err, checkSum){\n\t\t\t\t\tif(err){\n\t\t\t\t\t\tcheckSum = '';\n\t\t\t\t\t}\n\t\t\t\t\tuploadCheckpoint.uploadFileStat.checkSum = checkSum;\n\t\t\t\t\teventEmitter.emit('start to writeFile');\n\t\t\t\t});\n\t\t\t}else{\n\t\t\t\teventEmitter.emit('start to writeFile');\n\t\t\t}\n\t\t}else{\n\t\t\tfs.readFile(checkpointFile, function(err, data){\n\t\t\t\tif(err){\n\t\t\t\t\tfs.unlink(checkpointFile, function(){});\n\t\t\t\t\t_callback('ReadCheckpointFileError',err);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttry{\n\t\t\t\t\tuploadCheckpoint = JSON.parse(data);\n\t\t\t\t}catch(e){\n\t\t\t\t\tfs.unlink(checkpointFile, function(){});\n\t\t\t\t\t_callback('ParseCheckpointFileError', e);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(!uploadCheckpoint || uploadCheckpoint.bucketName !== bucket || uploadCheckpoint.objectKey !== key || uploadCheckpoint.uploadFile !== uploadFile ||\n\t\t\t\t\t\t!uploadCheckpoint.uploadFileStat || uploadCheckpoint.uploadFileStat.fileSize !== fstat.size || uploadCheckpoint.uploadFileStat.lastModified !== fstat.mtime.toUTCString() ||\n\t\t\t\t\t\tuploadCheckpoint.md5 !== calculateUploadCheckpointMD5(uploadCheckpoint)){\n\t\t\t\t\tabortRequest(uploadCheckpoint, checkpointFile, 'CheckpointFileInvalid', 'CheckpointFile is invalid!');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif(uploadCheckpoint.uploadFileStat.checkSum){\n\t\t\t\t\tobsClient.util.fileMD5(uploadFile, function(err, checkSum){\n\t\t\t\t\t\tif(err || checkSum !== uploadCheckpoint.uploadFileStat.checkSum){\n\t\t\t\t\t\t\tabortRequest(uploadCheckpoint, checkpointFile, 'CheckpointFileInvalid','CheckpointFile is invalid!');\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\teventEmitter.emit('start to uploadFile', uploadCheckpoint);\n\t\t\t\t\t});\n\t\t\t\t}else{\n\t\t\t\t\teventEmitter.emit('start to uploadFile', uploadCheckpoint);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}else{\n\t\teventEmitter.emit('start to uploadFile', uploadCheckpoint);\n\t}\n};\n\n// 当指定了参数DownloadFile，将使用此值作为保存文件名，否则使用对象名作为保存文件名， 保存时将覆盖同名文件。 \n// 另外，还将使用 保存文件名+\".obsnodejssdk.tmp\"后缀的形式 作为下载过程中的临时中间文件名，且也会覆盖同名文件。\n// 另外，当开启了断点延续下载（EnableCheckpoint=true），还将使用 参数CheckpointFile（如果没有指定CheckpointFile将使用对象名）+\".obsnodejssdk.chkpt\"后缀的形式 作为保存历史下载情况和校验信息的文件名，且也会覆盖同名文件。\nObsClient.prototype.downloadFile = function(param, callback){\n\tparam = param || {};\n\tlet _log = this.log;\n\tlet obsClient = this;\n\tlet funcName = 'downloadFile';\n\tlet start = new Date().getTime();\n\tlet progressCallback = param.ProgressCallback || function(){};\n\tlet resumeCallback = param.ResumeCallback || function(){};\n\tcallback = callback || function(){};\n\tlet _callback = function(code, message, result){\n\t\t_log.runLog('info', funcName, 'ObsClient cost ' +  (new Date().getTime() - start) + ' ms');\n\t\tif(typeof code === 'string'){\n\t\t\tif(message){\n\t\t\t\tcode += ':' + String(message);\n\t\t\t}\n\t\t\tcallback(code, result);\n\t\t}else{\n\t\t\tcallback(code ? (code.CommonMsg.Code + ':' + code.CommonMsg.Message) : null, result);\n\t\t}\n\t};\n\t\n\t_log.runLog('debug', funcName, 'enter ' + funcName + '...' );\n\n\tlet bucket = param.Bucket;\n\tif(!bucket){\n\t\t_log.runLog('error', funcName, 'Bucket is a required element!');\n\t\t_callback('InvalidArgument','Bucket is a required element!');\n\t\treturn;\n\t}\n\tbucket = String(bucket);\n\t\n\tlet key = param.Key;\n\tif(!key){\n\t\t_log.runLog('error', funcName, 'Key is a required element!');\n\t\t_callback('InvalidArgument', 'Key is a required element!');\n\t\treturn;\n\t}\n\tkey = String(key);\n\t\n\tlet pathLib = require('path');\n\t\n\tlet downloadFile;\n\tif(!param.DownloadFile){\n\t\tdownloadFile = require('process').cwd() + pathLib.sep + key;\n\t\t_log.runLog('info', funcName, 'DownloadFile is not set, will put file to path:' + downloadFile + \", by default\");\n\t}else{\n\t\tdownloadFile = String(param.DownloadFile);\n\t}\n\tlet tmpSuffix = \".obsnodejssdk.tmp\";\n\tlet chkSuffix = \".obsnodejssdk.chkpt\";\n\tlet downloadTempFile = downloadFile + tmpSuffix;\n\tlet fs = require('fs');\n\n\tlet taskNum = parseInt(param.TaskNum, 10) || 10;\n\t\n\tlet initWriteAndClose4DownloadTmpFile = function(tmpFileFd, tmpFile, tmpFileSize, callback) {\n\t\tlet buffer = Buffer.from('1', 'utf8');\n\t\tlet start = new Date().getTime();\n\t\tfs.write(tmpFileFd, buffer, 0, 1, tmpFileSize - 1, (werr)=>{\n\t\t\t_log.runLog('debug', 'prepareDownloadTempFile', ` prepare ${tmpFile} cost ` + (new Date().getTime() - start) + ' ms');\n\t\t\tif(werr){\n\t\t\t\t_log.runLog('error', 'prepareDownloadTempFile', `ftruncate temp file:${tmpFile} failed , and cost: ${(new Date().getTime() - start) / 1000}`);\n\t\t\t\t_log.runLog('error', 'prepareDownloadTempFile', `ftruncate temp file:${tmpFile} failed , err:${werr.stack}`);\n\t\t\t\tfs.unlinkSync(tmpFile);\n\t\t\t\treturn callback(false, tmpFile);\n\t\t\t}\n\t\t\tfs.close(tmpFileFd, (err)=>{\n\t\t\t\tif(err){\n\t\t\t\t\t_log.runLog('error', 'prepareDownloadTempFile', `close fd failed, err:${err.stack}`);\n\t\t\t\t\tfs.unlinkSync(tmpFile);\n\t\t\t\t\treturn callback(false, tmpFile);\n\t\t\t\t}\n\t\t\t\treturn callback(true, tmpFile);\n\t\t\t});\n\t\t});\n\t}\n\n\tlet initDownloadTmpFile = function(tmpFile, tmpFileSize, callback) {\n\t\tfs.open(tmpFile, 'w', (oerr, fd)=>{\n\t\t\tif(oerr){\n\t\t\t\t_log.runLog('error', 'prepareDownloadTempFile', `create temp download file ${tmpFile}  failed, error:${oerr.stack}`);\n\t\t\t\t_callback('InnerError',  `create temp download file ${tmpFile}  failed, error:${oerr.stack}`);\n\t\t\t\treturn callback(false, tmpFile);\n\t\t\t}\n\n\t\t\tlet start = new Date().getTime();\n\t\t\tfs.ftruncate(fd, tmpFileSize, (terr)=>{\n\t\t\t\tif(terr){\n\t\t\t\t\t// 例如fat、exfat文件系统，将导致fs.ftruncate()报错\n\t\t\t\t\tinitWriteAndClose4DownloadTmpFile(fd, tmpFile, tmpFileSize, callback);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t_log.runLog('debug', 'prepareDownloadTempFile', ` prepare ${tmpFile} cost ` + (new Date().getTime() - start) + ' ms');\n\t\t\t\t\tfs.close(fd, (err)=>{\n\t\t\t\t\t\tif(err){\n\t\t\t\t\t\t\t_log.runLog('error', 'prepareDownloadTempFile', `close fd failed, err:${err.stack}`);\n\t\t\t\t\t\t\tfs.unlinkSync(tmpFile);\n\t\t\t\t\t\t\treturn callback(false, tmpFile);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn callback(true, tmpFile);\n\t\t\t\t\t});\n\t\t\t\t}\t\n\t\t\t});\n\t\t});\t\n\t}\n\n\tconst prepareDownloadTempFile = util.promisify((tmpFile, tmpFileSize, callback) => {\n\t\tif(fs.existsSync(tmpFile)){\n\t\t\ttry{\n\t\t\t\tfs.unlinkSync(tmpFile);\n\t\t\t}catch(e){\n\t\t\t\t_log.runLog('error', 'prepareDownloadTempFile',  `delete ${tmpFile} file failed , exception: ${e}`);\n\t\t\t\t_callback('DeleteTempFileError', `delete ${tmpFile} file failed , exception: ${e}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tinitDownloadTmpFile(tmpFile, tmpFileSize, callback);\n\t});\n\n\tlet mkdirsSync = function(dirname){\n\t\tif(fs.existsSync(dirname)){\n\t\t\treturn true;\n\t\t}else{\n\t\t\tif(mkdirsSync(pathLib.dirname(dirname))){\n\t\t\t\tfs.mkdirSync(dirname);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t};\n\n\tobsClient.getObjectMetadata({\n\t\tBucket : bucket,\n\t\tKey : key,\n\t\tVersionId : param.VersionId,\n\t\tSseC: param.SseC,\n\t\tSseCKey: param.SseCKey,\n\t}, function(err, result){\n\t\t_log.runLog('debug', funcName, ` getObjectMetadata of ${key} cost ` + (new Date().getTime() - start) + ' ms');\n\n\t\tlet enableCheckpoint = param.EnableCheckpoint;\n\t\tlet checkpointFile = null;\n\t\t\n\t\tif(enableCheckpoint){\n\t\t\tcheckpointFile = param.CheckpointFile;\n\t\t\tcheckpointFile = (checkpointFile && checkpointFile !== '') ? String(checkpointFile) : downloadFile + chkSuffix;\n\t\t\tlet checkPointFileDir = pathLib.dirname(checkpointFile);\n\t\t\tif(!fs.existsSync(checkPointFileDir)){\n\t\t\t\tmkdirsSync(checkPointFileDir);\n\t\t\t}\n\t\t}\n\t\t\n\t\tlet tempFileDir = pathLib.dirname(downloadTempFile);\n\t\tif(!fs.existsSync(tempFileDir)){\n\t\t\tmkdirsSync(tempFileDir);\n\t\t}\n\t\t\n\t\tif(err || result.CommonMsg.Status >= 500){\n\t\t\t_log.runLog('warn', funcName,  'the peer server occur exception!');\n\t\t\t_callback('GetObjectSizeError', err);\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tif(result.CommonMsg.Status >= 300 && result.CommonMsg.Status < 500){\n\t\t\t_log.runLog('warn', funcName,  result.CommonMsg.Message);\n\t\t\t_callback(result);\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tlet objectSize = parseInt(result.InterfaceResult.ContentLength, 10);\n\t\t\n\t\tif(objectSize === 0){\n\t\t\tfs.writeFileSync(downloadFile, Buffer.from(''));\n\t\t\tcallback(null, result);\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tlet objestStat = result;\n\t\t\n\t\tlet events = require('events');\n\t\tlet eventEmitter = new events.EventEmitter();\n\t\t\n\t\tlet calculateDownloadCheckpointMD5 = function(downloadCheckpoint){\n\t\t\tlet data = [];\n\t\t\tdata.push(downloadCheckpoint.bucketName);\n\t\t\tdata.push(downloadCheckpoint.objectKey);\n\t\t\tdata.push(downloadCheckpoint.downloadFile);\n\t\t\tdata.push(String(downloadCheckpoint.partSize));\n\t\t\tdata.push(String(downloadCheckpoint.partCount));\n\t\t\tif(downloadCheckpoint.versionId){\n\t\t\t\tdata.push(downloadCheckpoint.versionId);\n\t\t\t}\n\t\t\tif(downloadCheckpoint.ifMatch){\n\t\t\t\tdata.push(downloadCheckpoint.ifMatch);\n\t\t\t}\n\t\t\tif(downloadCheckpoint.ifModifiedSince){\n\t\t\t\tdata.push(downloadCheckpoint.ifModifiedSince);\n\t\t\t}\n\t\t\tif(downloadCheckpoint.ifNoneMatch){\n\t\t\t\tdata.push(downloadCheckpoint.ifNoneMatch);\n\t\t\t}\n\t\t\tif(downloadCheckpoint.ifUnmodifiedSince){\n\t\t\t\tdata.push(downloadCheckpoint.ifUnmodifiedSince);\n\t\t\t}\n\t\t\tif(downloadCheckpoint.sseC){\n\t\t\t\tdata.push(downloadCheckpoint.sseC);\n\t\t\t}\n\t\t\tif(downloadCheckpoint.sseCKey){\n\t\t\t\tdata.push(downloadCheckpoint.sseCKey);\n\t\t\t}\n\t\t\tif(downloadCheckpoint.partsMeta && (downloadCheckpoint.partsMeta instanceof Object)){\n\t\t\t\t// key是分段段号，且在partsMeta上最小编号是1。  \n\t\t\t\tfor(let key in downloadCheckpoint.partsMeta){\n\t\t\t\t\tif ({}.hasOwnProperty.call(downloadCheckpoint.partsMeta, key)) {\n\t\t\t\t\t\tdata.push(String(key));\n\t\t\t\t\t\tlet partMeta = downloadCheckpoint.partsMeta[key];\n\t\t\t\t\t\tif(partMeta){\n\t\t\t\t\t\t\tdata.push(String(partMeta.startPos));\n\t\t\t\t\t\t\tdata.push(String(partMeta.endPos));\n\t\t\t\t\t\t\tdata.push(String(partMeta.isCompleted));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn obsClient.util.bufMD5(Buffer.from(data.join(''), 'utf8'));\n\t\t};\n\t\t\n\t\tlet writeCheckpointFileSync = function(checkpointFile, downloadCheckpoint){\n\t\t\ttry{\n\t\t\t\tif(fs.existsSync(downloadTempFile)){\n\t\t\t\t\tlet tempFileStat = fs.statSync(downloadTempFile);\n\t\t\t\t\tif(!downloadCheckpoint.tempFileStatus){\n\t\t\t\t\t\tdownloadCheckpoint.tempFileStatus = {};\n\t\t\t\t\t}\n\t\t\t\t\tdownloadCheckpoint.tempFileStatus.fileName = downloadTempFile;\n\t\t\t\t\tdownloadCheckpoint.tempFileStatus.fileSize = tempFileStat.size;\n\t\t\t\t\tdownloadCheckpoint.tempFileStatus.lastModified = tempFileStat.mtime.toUTCString();\n\t\t\t\t}\n\t\t\t\tfs.writeFileSync(checkpointFile, JSON.stringify(downloadCheckpoint));\n\t\t\t\treturn true;\n\t\t\t}catch(e){\n\t\t\t\tfs.unlinkSync(checkpointFile, function(){});\n\t\t\t\tfs.unlinkSync(downloadTempFile, function(){});\n\t\t\t\t_callback('WriteCheckpointFileError', e);\n\t\t\t\t_log.runLog('error', funcName, 'Write checkpoint file failed, err: ' + e);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t};\n\t\t\n\t\teventEmitter.on('start to downloadFile', function(downloadCheckpoint){\n\t\t\tif(!downloadCheckpoint){\n\t\t\t\tdownloadCheckpoint = {};\n\t\t\t}\n\t\t\t\n\t\t\tif(!downloadCheckpoint.partsMeta){\n\t\t\t\tdownloadCheckpoint.partsMeta = {};\n\t\t\t}\n\t\t\t\n\t\t\t_log.runLog('debug', funcName, 'Begin to downloadFile from OBS to:' + downloadFile);\n\t\t\t\n\t\t\tlet finishedCount = 0;\n\t\t\tlet hasError = false;\n\t\t\tlet isAbort = false;\n\t\t\tlet finishedBytes = 0;\n\t\t\tif(downloadCheckpoint.partsMeta){\n\t\t\t\tfor(let i of Object.keys(downloadCheckpoint.partsMeta)){\n\t\t\t\t\tif(downloadCheckpoint.partsMeta[i].isCompleted){\n\t\t\t\t\t\tfinishedBytes += downloadCheckpoint.partSize\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet partsLoaded = {};\n\t\t\tlet startTime = new Date().getTime();\n\n\t\t\tresumeCallback({\n\t\t\t\tcancel : function(){\n\t\t\t\t\tisAbort = true;\n\t\t\t\t\t_callback('Download suspened', 'The process of downloadFile is suspened, you can try again')\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tlet progressCallbacks = function(partNumber, loaded){\n\t\t\t\tif(isAbort){\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfinishedBytes += loaded;\n\t\t\t\tif(partsLoaded[partNumber]){\n\t\t\t\t\tfinishedBytes -= partsLoaded[partNumber];\n\t\t\t\t}\n\t\t\t\tpartsLoaded[partNumber] = loaded;\n\t\t\t\tprogressCallback(finishedBytes, downloadCheckpoint.objectStatus.objectSize, (new Date().getTime() - startTime) / 1000);\n\t\t\t}; \n\n\t\t\t// 段进度\n\t\t\tlet createProgressCallbackByStartPart = function(partNumber){\n\t\t\t\treturn function(loaded, total, cost){\n\t\t\t\t\tprogressCallbacks(partNumber, loaded);\n\t\t\t\t};\n\t\t\t};\n\t\t\tlet tryCompletedDownload = function(){\n\t\t\t\tif(finishedCount !== downloadCheckpoint.partCount){\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t_log.runLog('debug', funcName, ` getObject of ${key} cost ` + (new Date().getTime() - start) + ' ms');\n\n\t\t\t\tif(!hasError){\n\t\t\t\t\tfs.rename(downloadTempFile, downloadFile, function(err){\n\t\t\t\t\t\tif(err){\n\t\t\t\t\t\t\t_log.runLog('error', 'completedDownload',  `DownloadFile finished but rename temp file error: ${err.stack}`);\n\t\t\t\t\t\t\tif(checkpointFile){\n\t\t\t\t\t\t\t\tif(!writeCheckpointFileSync(checkpointFile, downloadCheckpoint)){\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t_callback('IncompletedDownload',`you can retry with the same parameters, DownloadFile finished but rename temp file error: ${err.stack}`);\n\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\tfs.unlinkSync(downloadTempFile, function(){});\n\t\t\t\t\t\t\t\t_callback('DownloadFileFailed', `DownloadFile finished but rename temp file error: ${err.stack}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// rename成功后，删除checkpointFile\n\t\t\t\t\t\tif(checkpointFile){\n\t\t\t\t\t\t\tfs.unlinkSync(checkpointFile, function(){});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(result && result.InterfaceResult){\n\t\t\t\t\t\t\tdelete result.InterfaceResult.ContentLength;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t_callback(null, null, result);\n\t\t\t\t\t});\n\t\t\t\t}else{\t\n\t\t\t\t\tif(checkpointFile){\n\t\t\t\t\t\tif(!writeCheckpointFileSync(checkpointFile, downloadCheckpoint)){\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t_callback('IncompletedDownload','DownloadFile finished with error, you can retry with the same parameters');\n\t\t\t\t\t}else{\n\t\t\t\t\t\tfs.unlinkSync(downloadTempFile, function(){});\n\t\t\t\t\t\t_callback('DownloadFileFailed','DownloadFile finished with error');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\t\n\t\t\teventEmitter.on('doDownload', function(currentGroupIndex, groupCount, taskNum){\n\t\t\t\tlet start = (currentGroupIndex - 1) * taskNum;\n\t\t\t\tlet end = (currentGroupIndex === groupCount) ? downloadCheckpoint.partCount : currentGroupIndex * taskNum;\n\t\t\t\tlet finishedCountInGroup = 0;\n\n\t\t\t\tlet currStepEnd = function(i, partMeta, doNextRoundDownload) {\n\t\t\t\t\tdownloadCheckpoint.partsMeta[i] = partMeta;\n\t\t\t\t\tdownloadCheckpoint.md5 = calculateDownloadCheckpointMD5(downloadCheckpoint);\n\t\t\t\t\tif(checkpointFile && !writeCheckpointFileSync(checkpointFile, downloadCheckpoint)){\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tfinishedCount++;\n\t\t\t\t\tfinishedCountInGroup++;\n\n\t\t\t\t\tif(!doNextRoundDownload) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet _taskNum = (currentGroupIndex === groupCount) ? (downloadCheckpoint.partCount - (currentGroupIndex - 1) * taskNum) : taskNum;\n\t\t\t\t\tif(finishedCountInGroup === _taskNum && finishedCount < downloadCheckpoint.partCount){\n\t\t\t\t\t\teventEmitter.emit('doDownload', currentGroupIndex + 1, groupCount, taskNum);\n\t\t\t\t\t}\n\t\t\t\t\telse if(finishedCountInGroup === _taskNum && finishedCount === downloadCheckpoint.partCount){\n\t\t\t\t\t\ttryCompletedDownload();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlet checkSkipPartI = function(i) {\n\t\t\t\t\tif(downloadCheckpoint.partsMeta[i] && downloadCheckpoint.partsMeta[i].isCompleted){\n\t\t\t\t\t\tfinishedCount++;\n\t\t\t\t\t\tfinishedCountInGroup++;\n\t\t\t\t\t\tlet _taskNum = (currentGroupIndex === groupCount) ? (downloadCheckpoint.partCount - (currentGroupIndex - 1) * taskNum) : taskNum;\n\t\t\t\t\t\tif(finishedCountInGroup === _taskNum && finishedCount < downloadCheckpoint.partCount){\n\t\t\t\t\t\t\t// 开启下一组下载\n\t\t\t\t\t\t\teventEmitter.emit('doDownload', currentGroupIndex + 1, groupCount, taskNum);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(finishedCountInGroup === _taskNum && finishedCount === downloadCheckpoint.partCount){\n\t\t\t\t\t\t\ttryCompletedDownload();\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}else {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlet savePartIdata = function(i, startPos, partMeta, result) {\n\t\t\t\t\tlet stream;\n\n\t\t\t\t\ttry{\n\t\t\t\t\t\tlet res = result.InterfaceResult.Content;\n\n\t\t\t\t\t\tstream = fs.createWriteStream(downloadTempFile, {\n\t\t\t\t\t\t\tflags : 'r+',\n\t\t\t\t\t\t\tstart : startPos,\n\t\t\t\t\t\t\tautoClose: true // 如果 autoClose 被设置为 true（默认的行为），则当 'error' 或 'finish' 事件时，文件描述符会被自动地关闭\n\t\t\t\t\t\t});\n\t\t\t\t\t\tstream.on('error', (err) => {\n\t\t\t\t\t\t\thasError = true;\n\t\t\t\t\t\t\tpartMeta.isCompleted = false;\n\t\t\t\t\t\t\tcurrStepEnd(i, partMeta, false);\n\t\t\t\t\t\t\t_log.runLog('warn', funcName, `write to downloadTempFile occur exception : ${err.stack}`);\n\t\t\t\t\t\t\t_callback('DownloadFileFailed',`write to downloadTempFile occur exception : ${err.stack}`);\n\t\t\t\t\t\t\tdelete result.InterfaceResult.Content;\n\t\t\t\t\t\t});\n\t\t\t\t\t\t\n\t\t\t\t\t\tres.on('error', (err) => {\n\t\t\t\t\t\t\t// 如果可读流在处理期间发送错误，则可写流目标不会自动关闭。 如果发生错误，则需要手动关闭每个流以防止内存泄漏。\n\t\t\t\t\t\t\thasError = true;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tstream.close();\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t_log.runLog('warn', funcName, 'close downloadTempFile stream failed!');\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// error事件之后，不会有除了close事件之外的其他事件\n\n\t\t\t\t\t\t\tpartMeta.isCompleted = false;\n\t\t\t\t\t\t\tcurrStepEnd(i, partMeta, false);\n\t\t\t\t\t\t\t_log.runLog('warn', funcName, `getObject occur exception during the processing data time : ${err.stack}!`);\n\t\t\t\t\t\t\t_callback('DownloadFileFailed',`getObject occur exception during the processing data time : ${err.stack}!`);\n\t\t\t\t\t\t\tdelete result.InterfaceResult.Content;\n\t\t\t\t\t\t}).on('end', () => {\n\t\t\t\t\t\t\tif (!res.complete) {\n\t\t\t\t\t\t\t\thasError = true;\n\t\t\t\t\t\t\t\tpartMeta.isCompleted = false;\n\t\t\t\t\t\t\t\t_log.runLog('warn', funcName, 'getObject occur exception that does not complete the data transmission!');\n\t\t\t\t\t\t\t\t_callback('DownloadFileFailed','getObject occur exception that does not complete the data transmission!');\n\t\t\t\t\t\t\t\tdelete result.InterfaceResult.Content;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tpartMeta.isCompleted = true;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tcurrStepEnd(i, partMeta, true);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tres.pipe(stream, {end: true});\n\t\t\t\t\t}catch(e){\n\t\t\t\t\t\thasError = true;\n\t\t\t\t\t\t_log.runLog('warn', funcName, 'write to downloadTempFile occering execption:' + e);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlet downLoadPartI = function(i) {\n\t\t\t\t\tif(checkSkipPartI(i)) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet startPos = (i-1) * downloadCheckpoint.partSize;\n\t\t\t\t\tlet endPos = (i === downloadCheckpoint.partCount) ? (downloadCheckpoint.objectStatus.objectSize-1) : (i * downloadCheckpoint.partSize - 1);\n\t\t\t\t\tlet partStartTime = new Date().getTime();\n\n\t\t\t\t\tobsClient.getObject({\n\t\t\t\t\t\tBucket: downloadCheckpoint.bucketName,\n\t\t\t\t\t\tKey: downloadCheckpoint.objectKey,\n\t\t\t\t\t\tVersionId : downloadCheckpoint.versionId,\n\t\t\t\t\t\tRange: 'bytes=' + startPos + '-' + endPos,\n\t\t\t\t\t\tSaveAsStream : true,\n\t\t\t\t\t\tIfMatch : downloadCheckpoint.ifMatch,\n\t\t\t\t\t\tIfModifiedSince : downloadCheckpoint.ifModifiedSince,\n\t\t\t\t\t\tIfNoneMatch : downloadCheckpoint.ifNoneMatch,\n\t\t\t\t\t\tIfUnmodifiedSince : downloadCheckpoint.ifUnmodifiedSince,\n\t\t\t\t\t\tSseC : downloadCheckpoint.sseC,\n\t\t\t\t\t\tSseCKey : downloadCheckpoint.sseCKey,\n\t\t\t\t\t\tProgressCallback : createProgressCallbackByStartPart(i),\n\t\t\t\t\t}, function(err, result) {\n\t\t\t\t\t\t_log.runLog('debug', funcName, ` get part data, first to get the response, cost ` + (new Date().getTime() - partStartTime) + ' ms');\n\n\t\t\t\t\t\tlet partMeta = {startPos : startPos, endPos : endPos};\n\n\t\t\t\t\t\tif(err || result.CommonMsg.Status >= 500){\n\t\t\t\t\t\t\tpartMeta.isCompleted = false;\n\t\t\t\t\t\t\t// hasError 控制completedDownload()是否rename tempDownloadFile to DownloadFile.\n\t\t\t\t\t\t\thasError = true;\n\t\t\t\t\t\t\tcurrStepEnd(i, partMeta, true);\n\t\t\t\t\t\t\t_callback('DownloadFileFailed','the peer server occur exception!');\n\t\t\t\t\t\t\t_log.runLog('warn', funcName, 'the peer server occur exception!');\n\t\t\t\t\t\t}else if(result.CommonMsg.Status >= 300 && result.CommonMsg.Status < 500){\n\t\t\t\t\t\t\tisAbort = true;\n\t\t\t\t\t\t\t_callback(result);\n\t\t\t\t\t\t\t_log.runLog('warn', funcName,  result.CommonMsg.Message);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\tsavePartIdata(i, startPos, partMeta, result);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\twhile(start < end) {\n\t\t\t\t\tif(isAbort){\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet i = start + 1;\n\t\t\t\t\tdownLoadPartI(i);\n\t\t\t\t\tstart++;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tlet groupCount = (downloadCheckpoint.partCount % taskNum === 0) ? (downloadCheckpoint.partCount / taskNum) : (Math.floor(downloadCheckpoint.partCount / taskNum) + 1);\n\t\t\tlet defaultMaxListeners = eventEmitter.getMaxListeners();\n\t\t\tif(groupCount > defaultMaxListeners) {\n\t\t\t\teventEmitter.setMaxListeners(groupCount + 1);\n\t\t\t\t_log.runLog('debug', funcName, 'eventEmitter setMaxListeners from  ' + defaultMaxListeners + ' to ' + eventEmitter.getMaxListeners());\n\t\t\t}\n\n\t\t\teventEmitter.emit('doDownload', 1, groupCount, taskNum);\n\t\t});\n\t\t\n\t\tlet downloadCheckpoint;\n\t\tlet _tmpDownloadCheckpoint;\n\t\tlet partSize = parseInt(param.PartSize, 10);\n\t\tif (isNaN(partSize) || partSize < MIN_DOWNLOAD_PART_SIZE || partSize > MAX_DOWNLOAD_PART_SIZE) {\n\t\t\tpartSize = DEFAULT_DOWNLOAD_PART_SIZE;\n\t\t}\n\t\tlet partCount = objectSize % partSize === 0 ? Math.floor(objectSize / partSize) : Math.floor(objectSize / partSize) + 1;\n\t\t_log.runLog('debug', funcName, 'Total parts count ' + partCount);\n\t\tdownloadCheckpoint = {bucketName: bucket, objectKey: key, downloadFile : downloadFile, partSize : partSize, partCount : partCount};\n\t\tdownloadCheckpoint.versionId = param.VersionId;\n\t\tdownloadCheckpoint.ifMatch = param.IfMatch;\n\t\tdownloadCheckpoint.ifModifiedSince = param.IfModifiedSince;\n\t\tdownloadCheckpoint.ifNoneMatch = param.IfNoneMatch;\n\t\tdownloadCheckpoint.ifUnmodifiedSince = param.IfUnmodifiedSince;\n\t\tdownloadCheckpoint.sseC = param.SseC;\n\t\tdownloadCheckpoint.sseCKey = param.SseCKey;\n\t\tdownloadCheckpoint.md5 = calculateDownloadCheckpointMD5(downloadCheckpoint);\n\t\tdownloadCheckpoint.objectStatus = {objectSize : objectSize, lastModified : objestStat.InterfaceResult.LastModified, etag: objestStat.InterfaceResult.ETag};\n\t\t\n\t\tlet tryContinueDownload_noChkFile = function() {\n\t\t\tfs.writeFile(checkpointFile, JSON.stringify(downloadCheckpoint), function(err){\n\t\t\t\tif(err){\n\t\t\t\t\t_log.runLog('error', funcName, `failed to write to checkpointFile: ${err.stack}`);\n\t\t\t\t\t_callback('WriteCheckpointFileError', `failed to write to checkpointFile: ${err.stack}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tprepareDownloadTempFile(downloadTempFile, objectSize, (isPrepareSucceed, tmpFile) => {\n\t\t\t\t\tif(isPrepareSucceed){\n\t\t\t\t\t\teventEmitter.emit('start to downloadFile', downloadCheckpoint);\n\t\t\t\t\t}\n\t\t\t\t}).catch((reason) => {\n\t\t\t\t\t_log.runLog('error', funcName, 'failed to download file: ' + key + ', reason: ' + reason);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\tlet verifyDownloadTempFileStatus = function(tempFileStatusInChk){\n\t\t\tif(!tempFileStatusInChk || !tempFileStatusInChk.fileName || !tempFileStatusInChk.lastModified || !tempFileStatusInChk.fileSize){\n\t\t\t\t_log.runLog('warn',  'verifyTempFileStatus' , ' tempFileStatus infomation is not integrity.');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif(!fs.existsSync(downloadTempFile)){\n\t\t\t\t_log.runLog('warn', 'verifyTempFileStatus',  downloadTempFile + ' does not exist.');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tlet tempFileStat = fs.statSync(downloadTempFile);\n\t\t\tif( tempFileStatusInChk.fileName !== downloadTempFile \n\t\t\t\t|| tempFileStatusInChk.lastModified !== tempFileStat.mtime.toUTCString() \n\t\t\t\t|| tempFileStatusInChk.fileSize !==  tempFileStat.size){\n\t\t\t\t_log.runLog('warn',  'verifyTempFileStatus' , ' the tempFileStatus information in checkpointfile is not consistent.');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t};\n\n\t\tlet tryContinueDownload_hasChkFile = function() {\n\t\t\tfs.readFile(checkpointFile, function(err, data){\n\t\t\t\t_tmpDownloadCheckpoint = downloadCheckpoint;\n\n\t\t\t\tif(err){\n\t\t\t\t\t_log.runLog('error', funcName, `read checkpointFile occur error: ${err.stack}`);\n\t\t\t\t\tfs.unlinkSync(checkpointFile, function(){});\n\t\t\t\t\t_callback('ReadCheckpointFileError', `read checkpointFile occur error: ${err.stack}`);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttry{\n\t\t\t\t\t\tdownloadCheckpoint = JSON.parse(data);\n\t\t\t\t\t}catch(e){\n\t\t\t\t\t\t_log.runLog('error', funcName, 'pasre checkpointFile data occur exception : ' + e);\n\t\t\t\t\t\tfs.unlinkSync(checkpointFile, function(){});\n\t\t\t\t\t\t_callback('ParseCheckpointFileError', 'pasre checkpointFile data occur exception : ' + e);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// verify : downloadTempFile  vs  checkpointfile\n\t\t\t\tif(!downloadCheckpoint || downloadCheckpoint.bucketName !== bucket || downloadCheckpoint.objectKey !== key || downloadCheckpoint.downloadFile !== downloadFile || \n\t\t\t\t\t\t!downloadCheckpoint.objectStatus || downloadCheckpoint.objectStatus.objectSize !== objectSize || downloadCheckpoint.objectStatus.lastModified !== objestStat.InterfaceResult.LastModified || downloadCheckpoint.objectStatus.etag !== objestStat.InterfaceResult.ETag \n\t\t\t\t\t\t|| !verifyDownloadTempFileStatus(downloadCheckpoint.tempFileStatus) || downloadCheckpoint.md5 !== calculateDownloadCheckpointMD5(downloadCheckpoint)){\n\t\t\t\t\t// 校验不通过，不使用延续下载，需执行prepareDownloadTempFile()\n\t\t\t\t\tfs.unlinkSync(checkpointFile, function(){});\n\t\t\t\t\t_log.runLog('warn',  funcName , 'CheckpointFile is invalid!');\n\n\t\t\t\t\tdownloadCheckpoint = _tmpDownloadCheckpoint;\n\t\t\t\t\tprepareDownloadTempFile(downloadTempFile, objectSize, (isPrepareSucceed, tmpFile) => {\n\t\t\t\t\t\tif(isPrepareSucceed){\n\t\t\t\t\t\t\teventEmitter.emit('start to downloadFile', downloadCheckpoint);\n\t\t\t\t\t\t}\n\t\t\t\t\t}).catch((reason) => {\n\t\t\t\t\t\t_log.runLog('error', funcName, 'failed to download file: ' + key + ', reason: ' + reason);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// 校验通过，使用断点延续下载，即不执行prepareDownloadTempFile()\n\t\t\t\t\t_log.runLog('debug',  funcName , 'CheckpointFile is valid!');\n\t\t\t\t\teventEmitter.emit('start to downloadFile', downloadCheckpoint);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t});\n\t\t}\n\n\t\tlet tryContinueDownload = function() {\n\t\t\tif(!fs.existsSync(checkpointFile)){\n\t\t\t\ttryContinueDownload_noChkFile();\n\t\t\t}else{\n\t\t\t\ttryContinueDownload_hasChkFile();\n\t\t\t}\n\t\t}\n\n\t\tif(checkpointFile){\n\t\t\t// 启用l了断点续接下载\n\t\t\ttryContinueDownload();\n\t\t}else{\n\t\t\t// 没有启用断点续接下载\n\t\t\tprepareDownloadTempFile(downloadTempFile, objectSize, (isPrepareSucceed, tmpFile) => {\n\t\t\t\tif(isPrepareSucceed){\n\t\t\t\t\teventEmitter.emit('start to downloadFile', downloadCheckpoint);\n\t\t\t\t}\n\t\t\t}).catch((reason) => {\n\t\t\t\t_log.runLog('error', funcName, 'failed to download file: ' + key + ', reason: ' + reason);\n\t\t\t});\n\t\t}\n\t});\n};\n\nfunction isFunction(obj){\n\treturn Object.prototype.toString.call(obj) === '[object Function]';\n}\n\nfunction createPromise(current){\n\treturn function(param, callback){\n\t\tif(isFunction(param)){\n\t\t\tcurrent.call(this, null, param);\n\t\t\treturn;\n\t\t}\n\t\tif(isFunction(callback)){\n\t\t\tcurrent.call(this, param, callback);\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tlet that = this;\n\t\treturn new Promise(function(resolve, reject) {\n\t\t\tcurrent.call(that, param, function(err, result){\n\t\t\t\tif(err){\n\t\t\t\t\treturn reject(err);\n\t\t\t\t}\n\t\t\t\tresolve(result);\n\t\t\t});\n\t\t});\n\t};\n}\n\nif(isFunction(Promise)){\n\tfor(let key in ObsClient.prototype){\n\t\tif ({}.hasOwnProperty.call(ObsClient.prototype, key)) {\n\t\t\tlet current = ObsClient.prototype[key];\n\t\t\tObsClient.prototype[key] = createPromise(current);\n\t\t}\n\t}\n}\n\nObsClient.prototype.close = function(){\n\tif(this.util){\n\t\tthis.util.close();\n\t\tdelete this.util;\n\t}\n};\n\nObsClient.prototype.refreshShadowClient = function () {\n  if (this.util) {\n    this.util.refreshShadowClient();\n\t}\n};\n\nObsClient.prototype.exec = function(funcName, param, callback){\n\tlet _log = this.log;\n\tif(_log.isLevelEnabled('info')){\n\t\t_log.runLog('info', funcName, 'enter ' + funcName + '...' );\n\t}\n\tlet start = new Date().getTime();\n\tparam = param || {};\n\tlet _callback = function(err, msg){\n\t\tif(_callback.$called){\n\t\t\treturn;\n\t\t}\n\t\t_callback.$called = true;\n\t\tif(_log.isLevelEnabled('info')){\n\t\t\t_log.runLog('info', funcName, 'ObsClient cost ' +  (new Date().getTime() - start) + ' ms');\n\t\t}\n\t\t\n\t\tif(err && !(err instanceof Error)){\n\t\t\terr = new Error(err);\n\t\t}\n\t\tcallback(err, msg);\n\t};\n\tthis.util.exec(funcName, param , _callback);\n};\n\nObsClient.prototype.initLog = function(param){\n\tparam = param || {};\n\tthis.log.initLog(param.file_full_path, param.max_log_size, param.backups, param.level, param.log_to_console, param.name, param.logger);\n\tif(this.log.isLevelEnabled('warn')){\n\t\tlet msg = ['[OBS SDK Version=' + this.util.obsSdkVersion];\n\t\tif(this.util.server){\n\t\t\tlet port = this.util.port ? ':' + this.util.port : '';\n\t\t\tmsg.push('Endpoint=' + (this.util.is_secure? 'https' : 'http') + '://' + this.util.server + port);\n\t\t}\n\t\tmsg.push('Access Mode=' + (this.util.path_style ? 'Path' : 'Virtual Hosting') + ']');\n\t\tthis.log.runLog('warn', 'init', msg.join('];['));\n\t}\n};\n\nObsClient.prototype.factory = function(param){\n\tthis.log = new LogUtil();\n\tthis.util = new Utils(this.log);\n\tparam = param || {};\n\tthis.util.initFactory(param.access_key_id, param.secret_access_key, param.is_secure,\n\t\t\tparam.server, param.path_style, param.signature, param.region, param.port, param.max_retry_count,\n\t\t\tparam.timeout, param.ssl_verify, param.long_conn_param, param.security_token, param.is_signature_negotiation, param.is_cname,\n\t\t\tparam.max_connections, param.http_agent, param.https_agent, param.user_agent, param.third_http_lib, param.no_proxy_list,param.is_shadow_client, param.iam_domain, param.shadow_expires);\n};\n\nObsClient.prototype.refresh = function(access_key_id, secret_access_key, security_token,is_shadow_client){\n\tthis.util.refresh(access_key_id, secret_access_key, security_token,is_shadow_client);\n};\n\nObsClient.prototype.enums = enums;\n\nObsClient.prototype.createV2SignedUrlSync = function(param){\n\treturn this.util.createV2SignedUrlSync(param);\n};\n\nObsClient.prototype.createV4SignedUrlSync = function(param){\n\treturn this.util.createV4SignedUrlSync(param);\n};\n\n\nObsClient.prototype.createSignedUrlSync = function(param){\n\treturn this.util.createSignedUrlSync(param);\n};\n\nObsClient.prototype.createV4PostSignatureSync = function(param){\n\treturn this.util.createV4PostSignatureSync(param);\n};\n\nObsClient.prototype.createPostSignatureSync = function(param){\n\treturn this.util.createPostSignatureSync(param);\n};\n\nfor(let key in ObsClient.prototype){\n\tif ({}.hasOwnProperty.call(ObsClient.prototype, key)) {\n\t\tObsClient.prototype[capitalize(key)] = ObsClient.prototype[key];\n\t}\n}\n\nfor(let key in ObsClient.prototype){\n\tif ({}.hasOwnProperty.call(ObsClient.prototype, key)) {\n\t\tlet index = key.indexOf('Configuration');\n\t\tif (index > 0 && index + 'Configuration'.length === key.length) {\n\t\t\tObsClient.prototype[key.slice(0, index)] = ObsClient.prototype[key];\n\t\t}\n\t}\n}\n\nmodule.exports = ObsClient;\n\n"]}