{"ast":null,"code":"/**\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\nimport URI from 'urijs';\nimport axios from 'axios';\nimport SHA from 'jssha';\nimport { Base64 } from 'js-base64';\nimport md5 from 'blueimp-md5';\nimport xml2js from './xml2js';\nimport obsModel from './obsModel';\nimport v2Model from './v2Model';\nimport { ContentMD5, ContentSHA256 } from './enums';\nconst crypto = {\n createHmac: function (algorithm, key) {\n let algorithmKey;\n if (algorithm === 'sha1') {\n algorithmKey = 'SHA-1';\n } else if (algorithm === 'sha512') {\n algorithmKey = 'SHA-512';\n } else {\n algorithmKey = 'SHA-256';\n }\n let shaObj = new SHA(algorithmKey, 'TEXT');\n shaObj.setHMACKey(key, key instanceof ArrayBuffer ? 'ARRAYBUFFER' : 'TEXT');\n return {\n update: function (message) {\n shaObj.update(message);\n return this;\n },\n digest: function (type) {\n if (type === 'hex') {\n return shaObj.getHMAC('HEX');\n }\n if (type === 'base64') {\n return shaObj.getHMAC('B64');\n }\n return shaObj.getHMAC('ARRAYBUFFER');\n }\n };\n },\n createHash: function (algorithm) {\n if (algorithm === 'md5') {\n return {\n update: function (message) {\n if (!this.message) {\n this.message = message;\n } else {\n this.message += message;\n }\n return this;\n },\n digest: function (type) {\n if (type === 'hex') {\n return md5(this.message);\n }\n if (type === 'base64') {\n let encodeFunc = window.btoa ? window.btoa : Base64.encode;\n return encodeFunc(md5(this.message, false, true));\n }\n if (type === 'rawbase64') {\n let encodeFunc = window.btoa ? window.btoa : Base64.encode;\n return encodeFunc(md5(this.message, false, true));\n }\n return md5(this.message, false, true);\n }\n };\n }\n let algorithmKey;\n if (algorithm === 'sha1') {\n algorithmKey = 'SHA-1';\n } else if (algorithm === 'sha512') {\n algorithmKey = 'SHA-512';\n } else {\n algorithmKey = 'SHA-256';\n }\n let shaObj = new SHA(algorithmKey, 'TEXT');\n return {\n update: function (message) {\n shaObj.update(message);\n return this;\n },\n digest: function (type) {\n if (type === 'hex') {\n return shaObj.getHash('HEX');\n }\n if (type === 'base64') {\n return shaObj.getHash('B64');\n }\n return shaObj.getHash('ARRAYBUFFER');\n }\n };\n }\n};\nconst urlLib = {\n parse: function (url) {\n let uri = URI.parse(url);\n return {\n hostname: uri.hostname,\n port: uri.port,\n host: uri.hostname,\n protocol: uri.protocol ? uri.protocol + ':' : '',\n query: uri.query,\n path: uri.path + (uri.query ? '?' + uri.query : ''),\n pathname: uri.path,\n search: uri.query ? '?' + uri.query : ''\n };\n }\n};\nconst CONTENT_SHA256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';\nconst OBS_SDK_VERSION = '3.22.3';\nconst mimeTypes = {\n '7z': 'application/x-7z-compressed',\n 'aac': 'audio/x-aac',\n 'ai': 'application/postscript',\n 'aif': 'audio/x-aiff',\n 'asc': 'text/plain',\n 'asf': 'video/x-ms-asf',\n 'atom': 'application/atom+xml',\n 'avi': 'video/x-msvideo',\n 'bmp': 'image/bmp',\n 'bz2': 'application/x-bzip2',\n 'cer': 'application/pkix-cert',\n 'crl': 'application/pkix-crl',\n 'crt': 'application/x-x509-ca-cert',\n 'css': 'text/css',\n 'csv': 'text/csv',\n 'cu': 'application/cu-seeme',\n 'deb': 'application/x-debian-package',\n 'doc': 'application/msword',\n 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'dvi': 'application/x-dvi',\n 'eot': 'application/vnd.ms-fontobject',\n 'eps': 'application/postscript',\n 'epub': 'application/epub+zip',\n 'etx': 'text/x-setext',\n 'flac': 'audio/flac',\n 'flv': 'video/x-flv',\n 'gif': 'image/gif',\n 'gz': 'application/gzip',\n 'htm': 'text/html',\n 'html': 'text/html',\n 'ico': 'image/x-icon',\n 'ics': 'text/calendar',\n 'ini': 'text/plain',\n 'iso': 'application/x-iso9660-image',\n 'jar': 'application/java-archive',\n 'jpe': 'image/jpeg',\n 'jpeg': 'image/jpeg',\n 'jpg': 'image/jpeg',\n 'js': 'text/javascript',\n 'json': 'application/json',\n 'latex': 'application/x-latex',\n 'log': 'text/plain',\n 'm4a': 'audio/mp4',\n 'm4v': 'video/mp4',\n 'mid': 'audio/midi',\n 'midi': 'audio/midi',\n 'mov': 'video/quicktime',\n 'mp3': 'audio/mpeg',\n 'mp4': 'video/mp4',\n 'mp4a': 'audio/mp4',\n 'mp4v': 'video/mp4',\n 'mpe': 'video/mpeg',\n 'mpeg': 'video/mpeg',\n 'mpg': 'video/mpeg',\n 'mpg4': 'video/mp4',\n 'oga': 'audio/ogg',\n 'ogg': 'audio/ogg',\n 'ogv': 'video/ogg',\n 'ogx': 'application/ogg',\n 'pbm': 'image/x-portable-bitmap',\n 'pdf': 'application/pdf',\n 'pgm': 'image/x-portable-graymap',\n 'png': 'image/png',\n 'pnm': 'image/x-portable-anymap',\n 'ppm': 'image/x-portable-pixmap',\n 'ppt': 'application/vnd.ms-powerpoint',\n 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n 'ps': 'application/postscript',\n 'qt': 'video/quicktime',\n 'rar': 'application/x-rar-compressed',\n 'ras': 'image/x-cmu-raster',\n 'rss': 'application/rss+xml',\n 'rtf': 'application/rtf',\n 'sgm': 'text/sgml',\n 'sgml': 'text/sgml',\n 'svg': 'image/svg+xml',\n 'swf': 'application/x-shockwave-flash',\n 'tar': 'application/x-tar',\n 'tif': 'image/tiff',\n 'tiff': 'image/tiff',\n 'torrent': 'application/x-bittorrent',\n 'ttf': 'application/x-font-ttf',\n 'txt': 'text/plain',\n 'wav': 'audio/x-wav',\n 'webm': 'video/webm',\n 'wma': 'audio/x-ms-wma',\n 'wmv': 'video/x-ms-wmv',\n 'woff': 'application/x-font-woff',\n 'wsdl': 'application/wsdl+xml',\n 'xbm': 'image/x-xbitmap',\n 'xls': 'application/vnd.ms-excel',\n 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'xml': 'application/xml',\n 'xpm': 'image/x-xpixmap',\n 'xwd': 'image/x-xwindowdump',\n 'yaml': 'text/yaml',\n 'yml': 'text/yaml',\n 'zip': 'application/zip'\n};\nconst allowedResourceParameterNames = ['inventory', 'acl', 'backtosource', 'policy', 'torrent', 'logging', 'location', 'storageinfo', 'quota', 'storageclass', 'storagepolicy', 'mirrorbacktosource', 'requestpayment', 'versions', 'versioning', 'versionid', 'uploads', 'uploadid', 'partnumber', 'website', 'notification', 'replication', 'lifecycle', 'deletebucket', 'delete', 'cors', 'restore', 'tagging', 'append', 'position', 'response-content-type', 'response-content-language', 'response-expires', 'response-cache-control', 'response-content-disposition', 'response-content-encoding', 'x-image-process', 'x-image-save-object', 'x-image-save-bucket', 'x-oss-process', 'encryption', 'obsworkflowtriggerpolicy', 'x-workflow-limit', 'x-workflow-prefix', 'x-workflow-start', 'x-workflow-template-name', 'x-workflow-graph-name', 'x-workflow-execution-state', 'x-workflow-category', 'x-workflow-prefix', 'x-workflow-create', 'directcoldaccess', 'customdomain', 'cdnnotifyconfiguration', 'metadata', 'dispolicy', 'obscompresspolicy', 'template_name', 'template_name_prefix', 'x-workflow-status', 'x-workflow-type', 'x-workflow-forbid', 'sfsacl', 'obsbucketalias', 'obsalias', 'rename', 'name', 'modify', 'attname', 'inventory', 'truncate', 'object-lock', \"retention\", 'x-obs-security-token'];\nconst allowedResponseHttpHeaderMetadataNames = ['content-type', 'content-md5', 'content-length', 'content-language', 'expires', 'origin', 'cache-control', 'content-disposition', 'content-encoding', 'x-default-storage-class', 'location', 'date', 'etag', 'host', 'last-modified', 'content-range', 'x-reserved', 'access-control-allow-origin', 'access-control-allow-headers', 'access-control-max-age', 'access-control-allow-methods', 'access-control-expose-headers', 'connection', 'x-obs-location-clustergroup-id'];\nconst commonHeaders = {\n 'content-length': 'ContentLength',\n 'date': 'Date',\n 'x-reserved': 'Reserved'\n};\nconst obsAllowedStorageClass = ['STANDARD', 'WARM', 'COLD', 'DEEP_ARCHIVE', 'INTELLIGENT_TIERING'];\nconst v2AllowedStorageClass = ['STANDARD', 'STANDARD_IA', 'GLACIER', 'DEEP_ARCHIVE', 'INTELLIGENT_TIERING'];\nconst obsAllowedAcl = ['private', 'public-read', 'public-read-write', 'public-read-delivered', 'public-read-write-delivered'];\nconst v2AllowedAcl = ['private', 'public-read', 'public-read-write', 'authenticated-read', 'bucket-owner-read', 'bucket-owner-full-control', 'log-delivery-write'];\nconst obsAllowedUri = ['Everyone', 'LogDelivery'];\nconst v2AllowedUri = ['http://acs.amazonaws.com/groups/global/AllUsers', 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers', 'http://acs.amazonaws.com/groups/s3/LogDelivery'];\nconst obsAllowedEvent = ['ObjectCreated', 'ObjectCreated:*', 'ObjectCreated:Put', 'ObjectCreated:Post', 'ObjectCreated:Copy', 'ObjectCreated:CompleteMultipartUpload', 'ObjectRemoved', 'ObjectRemoved:*', 'ObjectRemoved:Delete', 'ObjectRemoved:DeleteMarkerCreated', 'ObjectChanged:*', 'ObjectChanged:Rename', 'ObjectChanged:Truncate', 'ObjectChanged:Modify'];\nconst v2AllowedEvent = ['ObjectCreated', 's3:ObjectCreated:*', 's3:ObjectCreated:Put', 's3:ObjectCreated:Post', 's3:ObjectCreated:Copy', 's3:ObjectCreated:CompleteMultipartUpload', 'ObjectRemoved', 's3:ObjectRemoved:*', 's3:ObjectRemoved:Delete', 's3:ObjectRemoved:DeleteMarkerCreated', 'ObjectRemoved:*', 'ObjectRemoved:Delete', 'ObjectRemoved:DeleteMarkerCreated', 'ObjectChanged:*', 'ObjectChanged:Rename', 'ObjectChanged:Truncate', 'ObjectChanged:Modify'];\nconst ignoreNegotiationMethod = ['CreateBucket', 'SetBucketAlias', 'BindBucketAlias', 'UnbindBucketAlias', 'DeleteBucketAlias', 'GetBucketAlias'];\nconst negotiateMethod = 'HeadApiVersion';\nconst obsSignatureContext = {\n signature: 'obs',\n headerPrefix: 'x-obs-',\n headerMetaPrefix: 'x-obs-meta-',\n authPrefix: 'OBS'\n};\nconst v2SignatureContext = {\n signature: 'v2',\n headerPrefix: 'x-amz-',\n headerMetaPrefix: 'x-amz-meta-',\n authPrefix: 'AWS'\n};\nfunction encodeURIWithSafe(str, safe, skipEncoding) {\n str = String(str);\n if (str.length === 0) {\n return '';\n }\n if (skipEncoding) {\n return str;\n }\n let ret;\n if (safe) {\n ret = [];\n for (const element of str) {\n ret.push(safe.indexOf(element) >= 0 ? element : encodeURIComponent(element));\n }\n ret = ret.join('');\n } else {\n ret = encodeURIComponent(str);\n }\n return ret.replace(/!/g, '%21').replace(/\\*/g, '%2A').replace(/'/g, '%27').replace(/\\(/g, '%28').replace(/\\)/g, '%29');\n}\nfunction headerTostring(obj) {\n return JSON ? JSON.stringify(obj) : '';\n}\nfunction parseObjectFromHeaders(sentAs, headers) {\n let metadata = {};\n for (let key in headers) {\n if ({}.hasOwnProperty.call(headers, key)) {\n let k = String(key).toLowerCase();\n if (k.indexOf(sentAs) === 0) {\n metadata[k.slice(sentAs.length)] = headers[key];\n }\n }\n }\n return metadata;\n}\nfunction isArray(obj) {\n return Object.prototype.toString.call(obj) === '[object Array]';\n}\nfunction isFunction(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n}\nfunction isObject(obj) {\n return Object.prototype.toString.call(obj) === '[object Object]';\n}\nfunction makeObjFromXml(xml, bc) {\n if (typeof xml === 'object') {\n return bc(null, xml);\n }\n try {\n return bc(null, xml2js.parseString(xml));\n } catch (err) {\n return bc(err, null);\n }\n}\nfunction getExpireDate(utcDateStr) {\n let date = new Date(Date.parse(utcDateStr));\n let hour = date.getUTCHours();\n let min = date.getUTCMinutes();\n let sec = date.getUTCSeconds();\n let day = date.getUTCDate();\n let moth = date.getUTCMonth() + 1;\n let year = date.getUTCFullYear();\n let expireDate = '';\n expireDate += year + '-';\n if (moth < 10) {\n expireDate += '0';\n }\n expireDate += moth + '-';\n if (day < 10) {\n expireDate += '0';\n }\n expireDate += day + 'T';\n if (hour < 10) {\n expireDate += '0';\n }\n expireDate += hour + ':';\n if (min < 10) {\n expireDate += '0';\n }\n expireDate += min + ':';\n if (sec < 10) {\n expireDate += '0';\n }\n expireDate += sec + 'Z';\n return expireDate;\n}\nfunction getDates(utcDateStr) {\n let date = new Date(Date.parse(utcDateStr));\n let hour = date.getUTCHours();\n let min = date.getUTCMinutes();\n let sec = date.getUTCSeconds();\n let day = date.getUTCDate();\n let moth = date.getUTCMonth() + 1;\n let year = date.getUTCFullYear();\n let shortDate = '';\n let longDate = '';\n shortDate += year;\n if (moth < 10) {\n shortDate += '0';\n }\n shortDate += moth;\n if (day < 10) {\n shortDate += '0';\n }\n shortDate += day;\n longDate += shortDate + 'T';\n if (hour < 10) {\n longDate += '0';\n }\n longDate += hour;\n if (min < 10) {\n longDate += '0';\n }\n longDate += min;\n if (sec < 10) {\n longDate += '0';\n }\n longDate += sec + 'Z';\n return [shortDate, longDate];\n}\nfunction getSignedAndCanonicalHeaders(header) {\n let arrheadKey = [];\n let arrhead = {};\n for (let key in header) {\n if ({}.hasOwnProperty.call(header, key)) {\n arrheadKey.push(key.toLowerCase());\n arrhead[key.toLowerCase()] = header[key];\n }\n }\n arrheadKey = arrheadKey.sort();\n let signedHeaders = '';\n let canonicalHeaders = '';\n for (let i = 0; i < arrheadKey.length; i++) {\n if (i !== 0) {\n signedHeaders += ';';\n }\n signedHeaders += arrheadKey[i];\n canonicalHeaders += arrheadKey[i] + ':' + arrhead[arrheadKey[i]] + '\\n';\n }\n return [signedHeaders, canonicalHeaders];\n}\nfunction createV4Signature(shortDate, sk, region, stringToSign) {\n let dateKey = crypto.createHmac('sha256', 'AWS4' + sk).update(shortDate).digest();\n let dateRegionKey = crypto.createHmac('sha256', dateKey).update(region).digest();\n let dateRegionServiceKey = crypto.createHmac('sha256', dateRegionKey).update('s3').digest();\n let signingKey = crypto.createHmac('sha256', dateRegionServiceKey).update('aws4_request').digest();\n let signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest('hex');\n return signature;\n}\nfunction getV4Signature(shortDate, longDate, sk, region, canonicalRequest) {\n let scop = shortDate + '/' + region + '/s3/aws4_request';\n let stringToSign = 'AWS4-HMAC-SHA256\\n';\n stringToSign += longDate + '\\n';\n stringToSign += scop + '\\n';\n stringToSign += crypto.createHash('sha256').update(canonicalRequest).digest('hex');\n return createV4Signature(shortDate, sk, region, stringToSign);\n}\nfunction Utils(log_in) {\n this.log = log_in;\n this.ak = null;\n this.sk = null;\n this.securityToken = null;\n this.isSecure = true;\n this.server = null;\n this.pathStyle = false;\n this.signatureContext = null;\n this.isSignatureNegotiation = true;\n this.bucketSignatureCache = {};\n this.region = 'region';\n this.port = null;\n this.timeout = 300;\n this.obsSdkVersion = OBS_SDK_VERSION;\n this.isCname = false;\n this.bucketEventEmitters = {};\n this.useRawXhr = false;\n}\nUtils.prototype.encodeURIWithSafe = encodeURIWithSafe;\nUtils.prototype.mimeTypes = mimeTypes;\nUtils.prototype.refresh = function (ak, sk, securityToken) {\n this.ak = ak ? String(ak).trim() : null;\n this.sk = sk ? String(sk).trim() : null;\n this.securityToken = securityToken ? String(securityToken).trim() : null;\n};\nUtils.prototype.initFactory = function (ak, sk, isSecure, server, pathStyle, signature, region, port, timeout, securityToken, isSignatureNegotiation, isCname, urlPrefix, regionDomains, setRequestHeaderHook, useRawXhr, checksumAlgorithm) {\n this.refresh(ak, sk, securityToken);\n this.urlPrefix = urlPrefix || '';\n this.regionDomains = regionDomains || null;\n this.setRequestHeaderHook = setRequestHeaderHook || null;\n this.checkAlgorithm = ContentMD5;\n if (typeof checksumAlgorithm === 'string' && checksumAlgorithm.toLowerCase() === 'sha256') {\n this.checkAlgorithm = ContentSHA256;\n }\n if (!server) {\n throw new Error('Server is not set');\n }\n server = String(server).trim();\n if (server.indexOf('https://') === 0) {\n server = server.slice('https://'.length);\n isSecure = true;\n } else if (server.indexOf('http://') === 0) {\n server = server.slice('http://'.length);\n isSecure = false;\n }\n let index = server.lastIndexOf('/');\n while (index >= 0) {\n server = server.slice(0, index);\n index = server.lastIndexOf('/');\n }\n index = server.indexOf(':');\n if (index >= 0) {\n port = server.slice(index + 1);\n server = server.slice(0, index);\n }\n this.server = server;\n if (/^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$/.test(this.server)) {\n pathStyle = true;\n }\n if (isSecure !== undefined) {\n this.isSecure = isSecure;\n }\n if (pathStyle !== undefined) {\n this.pathStyle = pathStyle;\n }\n if (signature !== undefined) {\n signature = String(signature).trim().toLowerCase();\n } else {\n signature = 'obs';\n }\n if (isSignatureNegotiation !== undefined) {\n this.isSignatureNegotiation = isSignatureNegotiation;\n }\n this.isCname = isCname;\n if (this.pathStyle || this.isCname) {\n this.isSignatureNegotiation = false;\n if (signature === 'obs') {\n signature = 'v2';\n }\n }\n this.signatureContext = signature === 'obs' ? obsSignatureContext : v2SignatureContext;\n if (region !== undefined) {\n this.region = String(region);\n }\n this.port = port ? parseInt(port, 10) : this.isSecure ? 443 : 80;\n if (timeout !== undefined) {\n this.timeout = parseInt(timeout, 10);\n }\n if (useRawXhr !== undefined) {\n this.useRawXhr = useRawXhr;\n }\n};\nUtils.prototype.SseKmsAdapter = function (value, signatureContext) {\n value = value || '';\n value = String(value);\n let index = value.indexOf('aws:');\n if (signatureContext.signature === 'obs') {\n return index === 0 ? value.slice(4) : value;\n }\n return index === 0 ? value : 'aws:' + value;\n};\nUtils.prototype.SseModeAdapter = function (value, signatureContext) {\n value = value || '';\n value = String(value);\n let index = value.indexOf('aws:');\n if (signatureContext.signature === 'obs') {\n return index === 0 ? value.slice(4) : value;\n }\n return index === 0 ? value : 'aws:' + value;\n};\nUtils.prototype.BucketAdapter = function (value, signatureContext) {\n value = value || '';\n value = String(value);\n let index = value.indexOf('arn:aws:s3:::');\n if (signatureContext.signature === 'obs') {\n return index === 0 ? value.slice('arn:aws:s3:::'.length) : value;\n }\n return index === 0 ? value : 'arn:aws:s3:::' + value;\n};\nUtils.prototype.EventAdapter = function (value, signatureContext) {\n value = value || '';\n value = String(value);\n if (signatureContext.signature === 'obs') {\n if (obsAllowedEvent.indexOf(value) >= 0) {\n return value;\n }\n if (v2AllowedEvent.indexOf(value) >= 0) {\n return value.substring(3);\n }\n return '';\n }\n if (v2AllowedEvent.indexOf(value) >= 0) {\n return value;\n }\n if (obsAllowedEvent.indexOf(value) >= 0) {\n return 's3:' + value;\n }\n return '';\n};\nUtils.prototype.EventsAdapter = function (value, signatureContext) {\n return this.EventAdapter(value, signatureContext);\n};\nUtils.prototype.URIAdapter = function (value, signatureContext) {\n value = value || '';\n value = String(value);\n if (signatureContext.signature === 'obs') {\n if (obsAllowedUri.indexOf(value) >= 0) {\n return value;\n }\n if (value === 'AllUsers' || value === 'http://acs.amazonaws.com/groups/global/AllUsers') {\n return 'Everyone';\n }\n return '';\n }\n if (v2AllowedUri.indexOf(value) >= 0) {\n return value;\n }\n if (value === 'Everyone' || value === 'AllUsers') {\n return 'http://acs.amazonaws.com/groups/global/AllUsers';\n }\n if (value === 'AuthenticatedUsers') {\n return 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers';\n }\n if (value === 'LogDelivery') {\n return 'http://acs.amazonaws.com/groups/s3/LogDelivery';\n }\n return '';\n};\nUtils.prototype.StorageClassAdapter = function (value, signatureContext) {\n value = value || '';\n value = String(value).toUpperCase();\n if (signatureContext.signature === 'obs') {\n if (obsAllowedStorageClass.indexOf(value) >= 0) {\n return value;\n }\n if (value === 'STANDARD_IA') {\n return 'WARM';\n }\n if (value === 'GLACIER') {\n return 'COLD';\n }\n return '';\n }\n if (v2AllowedStorageClass.indexOf(value) >= 0) {\n return value;\n }\n if (value === 'WARM') {\n return 'STANDARD_IA';\n }\n if (value === 'COLD') {\n return 'GLACIER';\n }\n return '';\n};\nUtils.prototype.ACLAdapter = function (value, signatureContext) {\n value = value || '';\n value = String(value).toLowerCase();\n if (signatureContext.signature === 'obs') {\n if (obsAllowedAcl.indexOf(value) >= 0) {\n return value;\n }\n return '';\n }\n if (value === 'public-read-delivered') {\n value = 'public-read';\n } else if (value === 'public-read-write-delivered') {\n value = 'public-read-write';\n }\n if (v2AllowedAcl.indexOf(value) >= 0) {\n return value;\n }\n return '';\n};\nUtils.prototype.doExec = function (funcName, param, callback) {\n let opt = this.makeParam(funcName, param);\n if ('err' in opt) {\n return callback(opt.err, null);\n }\n this.sendRequest(funcName, opt, callback);\n};\nUtils.prototype.doNegotiation = function (funcName, param, callback, checkBucket, checkCache, setCache) {\n let o = null;\n let that = this;\n if (checkCache && param.Bucket) {\n let item = this.bucketSignatureCache[param.Bucket];\n if (item && item.signatureContext && item.expireTime > new Date().getTime()) {\n param.signatureContext = item.signatureContext;\n let opt = this.makeParam(funcName, param);\n if ('err' in opt) {\n return callback(opt.err, null);\n }\n opt.signatureContext = item.signatureContext;\n return this.sendRequest(funcName, opt, callback);\n }\n o = this.bucketEventEmitters[param.Bucket];\n if (!o) {\n o = {\n s: 0,\n n: function () {\n while (this.e && this.e.length > 0) {\n this.e.shift()();\n }\n }\n };\n this.bucketEventEmitters[param.Bucket] = o;\n }\n if (o.s) {\n o.e.push(function () {\n that.doNegotiation(funcName, param, callback, checkBucket, checkCache, setCache);\n });\n return;\n }\n o.e = [];\n o.s = 1;\n }\n this.doExec(negotiateMethod, checkBucket ? {\n Bucket: param.Bucket,\n hasRegion: param.hasRegion\n } : {}, function (err, result) {\n if (err) {\n callback(err, null);\n if (o) {\n o.s = 0;\n o.n();\n }\n return;\n }\n if (checkBucket && result.CommonMsg.Status === 404 || result.CommonMsg.Status >= 500) {\n callback(err, result);\n if (o) {\n o.s = 0;\n o.n();\n }\n return;\n }\n let signatureContext = v2SignatureContext;\n if (result.CommonMsg.Status < 300 && result.InterfaceResult && result.InterfaceResult.ApiVersion >= '3.0') {\n signatureContext = obsSignatureContext;\n }\n if (setCache) {\n that.bucketSignatureCache[param.Bucket] = {\n signatureContext: signatureContext,\n expireTime: new Date().getTime() + 15 + Math.ceil(Math.random() * 5) * 60 * 1000\n };\n }\n if (o) {\n o.s = 0;\n o.n();\n }\n param.signatureContext = signatureContext;\n let opt = that.makeParam(funcName, param);\n if ('err' in opt) {\n return callback(opt.err, null);\n }\n opt.signatureContext = signatureContext;\n that.sendRequest(funcName, opt, callback);\n });\n};\nUtils.prototype.exec = function (funcName, param, callback) {\n let that = this;\n if (that.isSignatureNegotiation && funcName !== negotiateMethod) {\n if (funcName === 'ListBuckets') {\n that.doNegotiation(funcName, param, callback, false, false, false);\n } else if (ignoreNegotiationMethod.indexOf(funcName) > -1) {\n let _callback = function (err, result) {\n if (!err && result.CommonMsg.Status === 400 && result.CommonMsg.Message === 'Unsupported Authorization Type' && param.signatureContext && param.signatureContext.signature === 'v2') {\n param.signatureContext = v2SignatureContext;\n let opt = that.makeParam(funcName, param);\n if ('err' in opt) {\n return callback(opt.err, null);\n }\n opt.signatureContext = param.signatureContext;\n that.sendRequest(funcName, opt, callback);\n return;\n }\n callback(err, result);\n };\n that.doNegotiation(funcName, param, _callback, false, true, false);\n } else {\n that.doNegotiation(funcName, param, callback, true, true, true);\n }\n return;\n }\n that.doExec(funcName, param, callback);\n};\nUtils.prototype.sliceBlob = function (blob, start, end, type) {\n type = type || blob.type;\n if (blob.mozSlice) {\n return blob.mozSlice(start, end, type);\n }\n if (blob.webkitSlice) {\n return blob.webkitSlice(start, end, type);\n }\n return blob.slice(start, end, type);\n};\nUtils.prototype.toXml = function (mXml, xmlMeta, root, sentAs, signatureContext) {\n let xml = '';\n if (root !== null) {\n xml += this.buildXml(mXml, xmlMeta, root, sentAs, signatureContext);\n return xml;\n }\n for (let key in xmlMeta) {\n if (key in mXml) {\n let _sentAs = xmlMeta[key].sentAs || key;\n xml += this.buildXml(mXml, xmlMeta[key], key, _sentAs, signatureContext);\n }\n }\n return xml;\n};\nUtils.prototype.buildXml = function (mXml, xmlMeta, key, sentAs, signatureContext) {\n let xml = '';\n let type = xmlMeta.type;\n if (type === 'array') {\n for (let i = 0; i < mXml[key].length; i++) {\n if (xmlMeta.items.type === 'object') {\n if (!mXml[key][i]) {\n return xml;\n }\n let result = this.toXml(mXml[key][i], xmlMeta.items.parameters, null, null, signatureContext);\n if (result !== '') {\n xml += '<' + sentAs + '>' + result + '';\n }\n } else if (xmlMeta.items.type === 'adapter') {\n xml += '<' + sentAs + '>' + String(this[key + 'Adapter'](mXml[key][i], signatureContext)).replace(/&/g, '&').replace(/'/g, ''').replace(/\"/g, '"') + '';\n } else if (xmlMeta.items.type !== 'array') {\n xml += '<' + sentAs + '>' + String(mXml[key][i]).replace(/&/g, '&').replace(/'/g, ''').replace(/\"/g, '"') + '';\n }\n }\n } else if (type === 'object') {\n if (!mXml[key]) {\n return xml;\n }\n let result = this.toXml(mXml[key], xmlMeta.parameters, null, null, signatureContext);\n if (result !== '') {\n xml += '<' + sentAs;\n if ('data' in xmlMeta) {\n if ('xsiNamespace' in xmlMeta.data) {\n xml += ' xmlns:xsi=\"' + xmlMeta.data.xsiNamespace + '\"';\n }\n if ('xsiType' in xmlMeta.data) {\n xml += ' xsi:type=\"' + mXml[key][xmlMeta.data.xsiType] + '\"';\n }\n }\n xml += '>';\n xml += result + '';\n }\n } else if (type === 'adapter') {\n xml += '<' + sentAs + '>' + String(this[key + 'Adapter'](mXml[key], signatureContext)).replace(/&/g, '&').replace(/'/g, ''').replace(/\"/g, '"') + '';\n } else if (type !== 'ignore') {\n xml += '<' + sentAs + '>' + String(mXml[key]).replace(/&/g, '&').replace(/'/g, ''').replace(/\"/g, '"') + '';\n }\n if (xml && xmlMeta.wrapper) {\n let _wrapper = xmlMeta.wrapper;\n xml = '<' + _wrapper + '>' + xml + '';\n }\n return xml;\n};\nUtils.prototype.jsonToObject = function (model, obj, root, ifRootXMlDecode) {\n let opt = {};\n if (root !== null) {\n this.buildObject(model, obj, root, opt, ifRootXMlDecode);\n } else {\n for (let key in model) {\n if ({}.hasOwnProperty.call(model, key)) {\n this.buildObject(model, obj, key, opt, ifRootXMlDecode);\n }\n }\n }\n return opt;\n};\nUtils.prototype.buildObject = function (model, obj, key, opt, ifRootXMlDecode) {\n let setValue = function (value) {\n if (value === undefined) {\n return \"\";\n }\n return value && model[key].decode && ifRootXMlDecode ? decodeURIComponent(value.replace(/\\+/g, '%20')) : value;\n };\n if (isObject(obj)) {\n let flag = true;\n let wrapper = model[key].wrapper;\n if (wrapper && wrapper in obj) {\n obj = obj[wrapper];\n flag = isObject(obj);\n }\n if (flag) {\n let sentAs = model[key].sentAs || key;\n if (sentAs in obj) {\n if (model[key].type === 'object') {\n opt[key] = this.jsonToObject(model[key].parameters, obj[sentAs], null, ifRootXMlDecode);\n } else if (model[key].type === 'array') {\n let arr = [];\n if (!isArray(obj[sentAs])) {\n arr[0] = model[key].items.type === 'object' ? this.jsonToObject(model[key].items.parameters, obj[sentAs], null, ifRootXMlDecode) : setValue(obj[sentAs]['#text'] || '');\n } else {\n for (let i = 0; i < obj[sentAs].length; i++) {\n arr[i] = model[key].items.type === 'object' ? this.jsonToObject(model[key].items.parameters, obj[sentAs][i], null, ifRootXMlDecode) : setValue(obj[sentAs][i]['#text']);\n }\n }\n opt[key] = arr;\n } else {\n opt[key] = setValue(obj[sentAs]['#text']);\n }\n }\n }\n }\n if (opt[key] === undefined) {\n if (model[key].type === 'object') {\n opt[key] = model[key].parameters ? this.jsonToObject(model[key].parameters, null, null, ifRootXMlDecode) : {};\n } else if (model[key].type === 'array') {\n opt[key] = [];\n }\n }\n};\nUtils.prototype.makeParam = function (methodName, param) {\n let signatureContext = param.signatureContext || this.signatureContext;\n let model = signatureContext.signature === 'obs' ? obsModel[methodName] : v2Model[methodName];\n let method = model.httpMethod;\n let uri = '/';\n let urlPath = '';\n let xml = '';\n let exheaders = {};\n let opt = {};\n opt.$requestParam = param;\n if ('urlPath' in model) {\n urlPath += '?';\n urlPath += model.urlPath;\n }\n for (let key in model.parameters) {\n if ({}.hasOwnProperty.call(model.parameters, key)) {\n let meta = model.parameters[key];\n if (key === 'Bucket' && this.isCname) {\n continue;\n }\n let _value = param[key];\n if (meta.type === 'callback' && _value === undefined && meta.parameters && (param['CallbackUrl'] !== undefined || param['CallbackBody'] !== undefined)) {\n _value = {};\n for (let _key of Object.keys(meta.parameters)) {\n const _meta = meta.parameters[_key];\n const _keyValue = param[_key];\n if (_meta.required && (_keyValue === null || _keyValue === undefined || Object.prototype.toString.call(_keyValue) === '[object String]' && _keyValue === '')) {\n opt.err = _key + ' is a required element!';\n this.log.runLog('error', methodName, opt.err);\n return opt;\n }\n const newKey = _key.slice(0, 1).toLowerCase() + _key.slice(1);\n _value[newKey] = _keyValue;\n }\n }\n if (meta.required && (_value === null || _value === undefined || Object.prototype.toString.call(_value) === '[object String]' && _value === '')) {\n opt.err = key + ' is a required element!';\n this.log.runLog('error', methodName, opt.err);\n return opt;\n }\n if (_value !== null && _value !== undefined) {\n if (meta.type === 'srcFile' || meta.type === 'dstFile') {\n opt[meta.type] = _value;\n continue;\n }\n if (meta.type === 'plain') {\n opt[key] = _value;\n }\n let sentAs = meta.sentAs || key;\n if (meta.withPrefix) {\n sentAs = signatureContext.headerPrefix + sentAs;\n }\n if (meta.location === 'uri') {\n if (uri !== '/') {\n uri += '/';\n }\n uri += _value;\n } else if (meta.location === 'header') {\n let safe = meta.encodingSafe || ' ;/?:@&=+$,';\n if (meta.type === 'object') {\n if (signatureContext.headerMetaPrefix === sentAs) {\n for (let item in _value) {\n if ({}.hasOwnProperty.call(_value, item)) {\n let value = _value[item];\n item = String(item).trim().toLowerCase();\n exheaders[item.indexOf(sentAs) === 0 ? item : sentAs + item] = encodeURIWithSafe(value, safe);\n }\n }\n }\n } else if (meta.type === 'array') {\n let arr = [];\n for (let item in _value) {\n if ({}.hasOwnProperty.call(_value, item)) {\n arr[item] = encodeURIWithSafe(_value[item], safe);\n }\n }\n exheaders[sentAs] = arr;\n } else if (meta.type === 'password') {\n let encodeFunc = window.btoa ? window.btoa : Base64.encode;\n exheaders[sentAs] = encodeFunc(_value);\n let pwdSentAs = meta.pwdSentAs || sentAs + '-MD5';\n exheaders[pwdSentAs] = this.rawBufMD5(_value);\n } else if (meta.type === 'number' && Number(_value)) {\n exheaders[sentAs] = encodeURIWithSafe(String(_value), safe);\n } else if (meta.type === 'boolean') {\n exheaders[sentAs] = encodeURIWithSafe(_value ? 'true' : 'false', safe);\n } else if (meta.type === 'callback') {\n exheaders[sentAs] = Base64.encode(JSON.stringify(_value));\n } else if (meta.type === 'adapter') {\n let val = this[key + 'Adapter'](_value, signatureContext);\n if (val) {\n exheaders[sentAs] = encodeURIWithSafe(String(val), safe);\n }\n } else {\n exheaders[sentAs] = encodeURIWithSafe(String(_value), safe, meta.skipEncoding);\n }\n } else if (meta.location === 'urlPath') {\n let sep = urlPath === '' ? '?' : '&';\n let value = _value;\n if (meta.type !== 'number' || meta.type === 'number' && Number(value) >= 0) {\n urlPath += sep + encodeURIWithSafe(sentAs, '/') + '=' + encodeURIWithSafe(String(value), '/');\n }\n } else if (meta.location === 'xml') {\n let mxml = this.toXml(param, meta, key, sentAs, signatureContext);\n if (mxml) {\n xml += mxml;\n }\n } else if (meta['location'] === 'body') {\n xml = _value;\n }\n }\n }\n }\n let isFile = opt.dstFile === 'file';\n if (!('Content-Type' in exheaders) && !isFile) {\n exheaders['Content-Type'] = 'binary/octet-stream';\n }\n if ('data' in model && 'xmlRoot' in model.data) {\n if (xml || model.data.xmlAllowEmpty) {\n let xmlRoot = model.data.xmlRoot;\n xml = '<' + xmlRoot + '>' + xml + '';\n exheaders['Content-Type'] = 'application/xml';\n }\n }\n if (isFile) {\n opt.rawUri = uri;\n }\n exheaders.Host = this.server + (this.port === 80 || this.port === 443 ? '' : ':' + this.port);\n if (!this.pathStyle && !this.isCname) {\n let uriList = uri.split('/');\n if (uriList.length >= 2 && uriList[1]) {\n exheaders.Host = uriList[1] + '.' + exheaders.Host;\n let requestUri = uri.replace(uriList[1], '');\n if (requestUri.indexOf('//') === 0) {\n requestUri = requestUri.slice(1);\n }\n if (signatureContext.signature === 'v4') {\n uri = requestUri;\n } else if (requestUri === '/') {\n uri += '/';\n }\n opt.requestUri = encodeURIWithSafe(requestUri, '/');\n }\n }\n opt.method = method;\n opt.uri = encodeURIWithSafe(uri, '/');\n opt.urlPath = urlPath;\n if (xml) {\n if (model.data && model.data.md5) {\n this.checkAlgorithm === ContentSHA256 ? exheaders[`${signatureContext.headerPrefix}${ContentSHA256.toLowerCase()}`] = this.bufSHA256(xml, 'hex') : exheaders[ContentMD5] = this.bufMD5(xml);\n exheaders['Content-Length'] = xml.length === 0 ? '0' : String(xml.length);\n }\n opt.xml = xml;\n this.log.runLog('debug', methodName, 'request content:' + xml);\n }\n opt.headers = exheaders;\n if ('srcFile' in opt) {\n if (opt.srcFile instanceof window.File || opt.srcFile instanceof window.Blob) {\n let fileSize = opt.srcFile.size;\n if ('Content-Length' in opt.headers || 'PartSize' in opt || 'Offset' in opt) {\n let offset = opt.Offset;\n offset = offset && offset >= 0 && offset < fileSize ? offset : 0;\n let partSize;\n if ('PartSize' in opt) {\n partSize = opt.PartSize;\n } else if ('Content-Length' in opt.headers) {\n partSize = parseInt(opt.headers['Content-Length'], 10);\n } else {\n partSize = fileSize;\n }\n partSize = partSize && partSize > 0 && partSize <= fileSize - offset ? partSize : fileSize - offset;\n opt.PartSize = partSize;\n opt.Offset = offset;\n opt.headers['Content-Length'] = String(opt.PartSize);\n }\n }\n }\n return opt;\n};\nUtils.prototype.parseCommonHeaders = function (opt, headers, signatureContext) {\n for (let key in commonHeaders) {\n if ({}.hasOwnProperty.call(commonHeaders, key)) {\n opt.InterfaceResult[commonHeaders[key]] = headers[key];\n }\n }\n opt.InterfaceResult.RequestId = headers[signatureContext.headerPrefix + 'request-id'];\n opt.InterfaceResult.Id2 = headers[signatureContext.headerPrefix + 'id-2'];\n opt.CommonMsg.RequestId = opt.InterfaceResult.RequestId;\n opt.CommonMsg.Id2 = opt.InterfaceResult.Id2;\n};\nUtils.prototype.contrustCommonMsg = function (opt, obj, headers, signatureContext) {\n opt.InterfaceResult = {};\n this.parseCommonHeaders(opt, headers, signatureContext);\n for (let key in obj) {\n if (obj[key].location !== 'header') {\n continue;\n }\n let sentAs = obj[key].sentAs || key;\n if (obj[key].withPrefix) {\n sentAs = signatureContext.headerPrefix + sentAs;\n }\n if (obj[key].type === 'object') {\n opt.InterfaceResult[key] = parseObjectFromHeaders(sentAs, headers);\n } else {\n let val = null;\n if (sentAs in headers) {\n val = headers[sentAs];\n } else if (sentAs.toLowerCase() in headers) {\n val = headers[sentAs.toLowerCase()];\n }\n if (val !== null) {\n opt.InterfaceResult[key] = val;\n }\n }\n }\n};\nUtils.prototype.getRequest = function (methodName, serverback, signatureContext, retryCount, params, bc) {\n let regionDomains = this.regionDomains;\n let opt = {};\n let log = this.log;\n let model = signatureContext.signature === 'obs' ? obsModel[methodName + 'Output'] : v2Model[methodName + 'Output'];\n model = model || {};\n let obj = model.parameters || {};\n opt.CommonMsg = {\n Status: serverback.status,\n Code: '',\n Message: '',\n HostId: '',\n RequestId: '',\n InterfaceResult: null\n };\n let headers = serverback.headers;\n let headersStr = headerTostring(headers);\n log.runLog('info', methodName, 'get response start, statusCode:' + serverback.status);\n log.runLog('debug', methodName, 'response msg :statusCode:' + serverback.status + ', headers:' + headersStr);\n let doLog = function () {\n let logMsg = 'Status:' + opt.CommonMsg.Status + ', Code:' + opt.CommonMsg.Code + ', Message:' + opt.CommonMsg.Message;\n log.runLog('debug', methodName, 'exec interface ' + methodName + ' finish, ' + logMsg);\n bc(null, opt);\n };\n if (serverback.status >= 300 && serverback.status < 400 && serverback.status !== 304 && retryCount <= 5) {\n let location = headers.location || headers.Location;\n if (location) {\n let err = 'http code is 3xx, need to redirect to ' + location;\n log.runLog('warn', methodName, err);\n let redirectErr = new Error('redirect');\n redirectErr.location = location;\n redirectErr.bucketLocation = headers['x-amz-bucket-region'] || headers['x-obs-bucket-region'];\n return bc(redirectErr);\n }\n let bucketLocation = headers['x-amz-bucket-region'] || headers['x-obs-bucket-location'];\n if (bucketLocation && regionDomains[bucketLocation]) {\n let regionServer = (this.isSecure ? 'https://' : 'http://') + regionDomains[bucketLocation];\n if (isFunction(this.setRequestHeaderHook)) {\n this.setRequestHeaderHook(headers, params, methodName, regionDomains[bucketLocation]);\n }\n let err = 'get redirect code 3xx, need to redirect to' + regionServer;\n log.runLog('error', methodName, err);\n let redirectErr = new Error('redirect');\n redirectErr.location = regionServer;\n return bc(redirectErr);\n }\n log.runLog('error', methodName, 'get redirect code 3xx, but no location in headers');\n }\n if (serverback.status < 300) {\n let body = serverback.data;\n this.contrustCommonMsg(opt, obj, headers, signatureContext);\n let respMsg = 'Status: ' + opt.CommonMsg.Status + ', headers: ' + headersStr;\n if (body) {\n respMsg += 'body length: ' + body.length;\n log.runLog('debug', methodName, 'response body length:' + body.length);\n }\n log.runLog('debug', methodName, respMsg);\n if (body && 'data' in model) {\n if (params.CallbackUrl && model.CallbackResponse) {\n opt.InterfaceResult[model.CallbackResponse.sentAs] = body;\n doLog();\n return;\n }\n if (model.data.type === 'xml') {\n let that = this;\n return makeObjFromXml(body, function (err, result) {\n if (err) {\n log.runLog('error', methodName, 'change xml to json err [' + headerTostring(err) + ']');\n return bc(err, null);\n }\n let tempResult = result;\n if (model.data.xmlRoot && model.data.xmlRoot in tempResult) {\n tempResult = result[model.data.xmlRoot];\n }\n let ifRootXMlDecode = tempResult.EncodingType ? true : false;\n if (isObject(tempResult)) {\n for (let key in obj) {\n if (obj[key].location === 'xml') {\n opt.InterfaceResult[key] = that.jsonToObject(obj, tempResult, key, ifRootXMlDecode)[key];\n }\n }\n }\n doLog();\n });\n }\n if (model.data.type === 'body') {\n for (let key in obj) {\n if (obj[key].location === 'body') {\n opt.InterfaceResult[key] = body;\n break;\n }\n }\n }\n }\n return doLog();\n }\n let body = serverback.data;\n let respMsg = 'Status: ' + opt.CommonMsg.Status + ', headers: ' + headersStr;\n if (body !== '') {\n respMsg += 'body: ' + body;\n log.runLog('debug', methodName, 'response body :' + body);\n }\n opt.CommonMsg.RequestId = headers[signatureContext.headerPrefix + 'request-id'];\n opt.CommonMsg.Id2 = headers[signatureContext.headerPrefix + 'id2'];\n opt.CommonMsg.Indicator = headers['x-reserved-indicator'];\n log.runLog('info', methodName, 'request finished with request id:' + opt.CommonMsg.RequestId);\n log.runLog('debug', methodName, respMsg);\n if (!body) {\n return doLog();\n }\n return makeObjFromXml(body, function (err, re) {\n if (err) {\n log.runLog('error', methodName, 'change xml to json err [' + headerTostring(err) + ']');\n opt.CommonMsg.Message = err.message;\n } else if (re) {\n if ('Error' in re) {\n let errMsg = re.Error;\n for (let param in errMsg) {\n if (errMsg[param] && errMsg[param]['#text']) {\n opt.CommonMsg[param] = errMsg[param]['#text'];\n }\n }\n } else {\n let errMsg = re;\n if ('code' in errMsg) {\n opt.CommonMsg.Code = errMsg.code;\n }\n if ('message' in errMsg) {\n opt.CommonMsg.Message = errMsg.message;\n }\n if ('hostId' in errMsg) {\n opt.CommonMsg.HostId = errMsg.hostId;\n }\n if ('request_id' in errMsg && errMsg.request_id) {\n opt.CommonMsg.RequestId = errMsg.request_id;\n }\n }\n log.runLog('error', methodName, 'request error with error code:' + opt.CommonMsg.Code + ', error message:' + opt.CommonMsg.Message + ', request id:' + opt.CommonMsg.RequestId);\n }\n doLog();\n });\n};\nUtils.prototype.makeRequest = function (methodName, opt, retryCount, bc) {\n let log = this.log;\n let body = opt.xml || null;\n let signatureContext = opt.signatureContext || this.signatureContext;\n delete opt.headers.Authorization; // retry bug fix\n\n if (opt.dstFile === 'file') {\n let queryParams = {};\n if (opt.urlPath) {\n let path = opt.urlPath.slice(1);\n let arrPath = path.split('&');\n for (let i = 0; i < arrPath.length; i++) {\n if (arrPath[i].indexOf('=') === -1) {\n queryParams[arrPath[i]] = '';\n } else {\n let temp = arrPath[i].split('=');\n queryParams[temp[0]] = temp[1];\n }\n }\n }\n let rawUri = opt.rawUri.split('/');\n let bucketName = rawUri[1];\n let objectKey = opt.rawUri.slice(('/' + bucketName + '/').length);\n if (this.isCname) {\n objectKey = opt.rawUri.slice(1);\n bucketName = '';\n }\n let ret = {};\n ret.CommonMsg = {\n Status: 0,\n Code: '',\n Message: '',\n HostId: ''\n };\n ret.InterfaceResult = {};\n let model = signatureContext.signature === 'obs' ? obsModel[methodName + 'Output'] : v2Model[methodName + 'Output'];\n let obj = model.parameters;\n for (let key in obj) {\n if (obj[key].location === 'body') {\n ret.InterfaceResult[key] = this.createSignedUrlSync({\n Method: opt.method,\n Bucket: bucketName,\n Key: objectKey,\n Expires: 3600,\n Headers: opt.headers,\n QueryParams: queryParams,\n signatureContext: signatureContext\n });\n break;\n }\n }\n return bc(null, ret);\n }\n let requestDate = opt.$requestParam.RequestDate;\n let nowDate;\n let requestDateType = Object.prototype.toString.call(requestDate);\n if (requestDateType === '[object Date]') {\n nowDate = requestDate;\n } else if (requestDateType === '[object String]') {\n try {\n nowDate = new Date();\n nowDate.setTime(Date.parse(requestDate));\n } catch (e) {\n // ignore\n }\n }\n if (!nowDate) {\n nowDate = new Date();\n }\n let utcDateStr = nowDate.toUTCString();\n let isV4 = signatureContext.signature.toLowerCase() === 'v4';\n opt.headers[signatureContext.headerPrefix + 'date'] = isV4 ? getDates(utcDateStr)[1] : utcDateStr;\n let path = (opt.requestUri ? opt.requestUri : opt.uri) + opt.urlPath;\n if (this.ak && this.sk && methodName !== negotiateMethod) {\n if (this.securityToken) {\n opt.headers[signatureContext.headerPrefix + 'security-token'] = this.securityToken;\n }\n if (isV4) {\n this.v4Auth(opt, methodName, signatureContext);\n } else {\n this.doAuth(opt, methodName, signatureContext);\n }\n }\n let ex = opt.headers;\n if (isFunction(this.setRequestHeaderHook)) {\n this.setRequestHeaderHook(ex, opt.$requestParam, methodName);\n }\n let host = ex.Host;\n let method = opt.method;\n let header_msg = {};\n for (let key in ex) {\n if ({}.hasOwnProperty.call(ex, key)) {\n header_msg[key] = ex[key];\n }\n }\n header_msg.Authorization = '****';\n let msg = 'method:' + method + ', path:' + path + 'headers:' + headerTostring(header_msg);\n if (body) {\n msg += 'body:' + body;\n }\n log.runLog('info', methodName, 'prepare request parameters ok,then Send request to service start');\n log.runLog('debug', methodName, 'request msg:' + msg);\n let _isSecure = opt.protocol ? opt.protocol.toLowerCase().indexOf('https') === 0 : this.isSecure;\n let port = opt.port || this.port;\n\n // avoid to set unsafe headers\n delete ex.Host;\n delete ex['Content-Length'];\n let responseType = 'text';\n if (opt.dstFile && opt.dstFile !== 'file' && (opt.dstFile === 'arraybuffer' || opt.dstFile === 'blob')) {\n responseType = String(opt.dstFile);\n }\n let start = nowDate.getTime();\n let that = this;\n let dealingError = function (err) {\n // with angular, headerTostring may lead to exception.\n try {\n let headerStr = headerTostring(err);\n log.runLog('error', methodName, 'Send request to service error [' + headerStr + ']');\n } catch (e) {\n if (err.toString) {\n log.runLog('error', methodName, 'Send request to service error [' + err.toString() + ']');\n }\n }\n log.runLog('info', methodName, 'http cost ' + (new Date().getTime() - start) + ' ms');\n bc(err, null);\n };\n if (!this.useRawXhr) {\n let onUploadProgress = null;\n let onDownloadProgress = null;\n if (isFunction(opt.ProgressCallback)) {\n let progressListener = function (event) {\n if (event.lengthComputable) {\n opt.ProgressCallback(event.loaded, event.total, (new Date().getTime() - start) / 1000);\n }\n };\n if (method === 'GET') {\n onDownloadProgress = progressListener;\n } else if (method === 'PUT' || method === 'POST') {\n onUploadProgress = progressListener;\n }\n }\n let portInfo = ':' + port;\n if (host.indexOf(':') >= 0) {\n portInfo = '';\n }\n // 适配cf2,在请求中增加通配符\n let baseUrl = '';\n let httpPrefix = _isSecure ? 'https://' : 'http://';\n if (this.urlPrefix && isFunction(this.setRequestHeaderHook) && methodName !== 'UploadPart') {\n let defaultRegion = true;\n if (opt.$requestParam['hasRegion'] || opt.$requestParam['redirectRegion']) {\n defaultRegion = false;\n }\n let portFlag = '';\n if (port === 5443) {\n portFlag = '-5443';\n }\n if (defaultRegion) {\n if (opt.$requestParam['Bucket']) {\n if (opt.$requestParam['Bucket'].indexOf('.') !== -1) {\n baseUrl = httpPrefix + this.urlPrefix + '/bucket' + portFlag;\n }\n baseUrl = httpPrefix + this.urlPrefix + '/bucket' + portFlag;\n } else {\n if (path.split('?')[0] === '/') {\n baseUrl = httpPrefix + this.urlPrefix + portFlag;\n } else {\n baseUrl = httpPrefix + this.urlPrefix + '/place' + portFlag;\n }\n }\n } else {\n if (opt.$requestParam['Bucket']) {\n baseUrl = httpPrefix + this.urlPrefix + '/region-bucket' + portFlag;\n } else {\n baseUrl = httpPrefix + this.urlPrefix + '/region' + portFlag;\n }\n }\n } else {\n baseUrl = httpPrefix + host + portInfo;\n }\n let reopt = {\n method: method,\n // fix bug, axios will abandon the base url if the request url starts with '//', so use the completed url to avoid it\n url: baseUrl + path,\n withCredentials: false,\n headers: ex,\n validateStatus: function (status) {\n return status >= 200;\n },\n maxRedirects: 0,\n responseType: responseType,\n data: body,\n timeout: this.timeout * 1000,\n onUploadProgress: onUploadProgress,\n onDownloadProgress: onDownloadProgress,\n cancelToken: new axios.CancelToken(function (cancelHook) {\n opt.$requestParam.cancelHook = cancelHook;\n })\n };\n if (opt.srcFile) {\n if (!(opt.srcFile instanceof window.File) && !(opt.srcFile instanceof window.Blob)) {\n return bc(new Error('source file must be an instance of window.File or window.Blob'), null);\n }\n let srcFile = opt.srcFile;\n try {\n if (opt.Offset >= 0 && opt.PartSize > 0) {\n srcFile = this.sliceBlob(srcFile, opt.Offset, opt.Offset + opt.PartSize);\n } else if ('ContentLength' in opt) {\n let contentLength = parseInt(opt.ContentLength, 10);\n if (contentLength > 0) {\n srcFile = this.sliceBlob(srcFile, 0, contentLength);\n }\n }\n } catch (e) {\n return bc(e);\n }\n reopt.data = srcFile;\n }\n axios.request(reopt).then(function (response) {\n log.runLog('info', methodName, 'http cost ' + (new Date().getTime() - start) + ' ms');\n that.getRequest(methodName, response, signatureContext, retryCount, opt.$requestParam, bc);\n }).catch(function (err) {\n dealingError(err);\n });\n return;\n }\n let xhr = null;\n // Firefox, Opera 8.0+, Safari\n try {\n xhr = new XMLHttpRequest();\n } catch (e) {\n try {\n // InternetExplorer\n xhr = new ActiveXObject('Msxml2.XMLHTTP');\n } catch (e1) {\n try {\n xhr = new ActiveXObject('Microsoft.XMLHTTP');\n } catch (e2) {}\n }\n }\n if (xhr === null) {\n return bc(new Error('XHR is not available'), null);\n }\n if (opt.srcFile) {\n if (!(opt.srcFile instanceof window.File) && !(opt.srcFile instanceof window.Blob)) {\n return bc(new Error('source file must be an instance of window.File or window.Blob'), null);\n }\n try {\n let srcFile = opt.srcFile;\n if (opt.Offset >= 0 && opt.PartSize > 0) {\n srcFile = this.sliceBlob(srcFile, opt.Offset, opt.Offset + opt.PartSize);\n } else if ('ContentLength' in opt) {\n let contentLength = parseInt(opt.ContentLength, 10);\n if (contentLength > 0) {\n srcFile = this.sliceBlob(srcFile, 0, contentLength);\n }\n }\n body = srcFile;\n } catch (e) {\n return bc(e);\n }\n }\n xhr.open(method, (_isSecure ? 'https://' + this.urlPrefix + host : 'http://' + this.urlPrefix + host) + path);\n xhr.withCredentials = false;\n for (let key in ex) {\n if ({}.hasOwnProperty.call(ex, key)) {\n xhr.setRequestHeader(key, ex[key]);\n }\n }\n xhr.timeout = that.timeout * 1000;\n xhr.responseType = responseType;\n opt.$requestParam.cancelHook = function () {\n xhr.abort();\n };\n xhr.onreadystatechange = function () {\n if (xhr.readyState === 4 && xhr.status >= 200) {\n log.runLog('info', methodName, 'http cost ' + (new Date().getTime() - start) + ' ms');\n let headers = xhr.getAllResponseHeaders();\n let arr = headers.trim().split(/[\\r\\n]+/);\n let headerMap = {};\n for (let i = 0; i < arr.length; i++) {\n let line = arr[i];\n let parts = line.split(': ');\n let header = parts.shift();\n let value = parts.join(': ');\n headerMap[header.toLowerCase()] = value;\n }\n let data = xhr.response;\n if (!data && (responseType === '' || responseType === 'text')) {\n data = xhr.responseText;\n }\n let response = {\n status: xhr.status,\n headers: headerMap,\n data: data\n };\n that.getRequest(methodName, response, signatureContext, retryCount, opt.$requestParam, bc);\n }\n };\n let handled = false;\n let errHandler = function (err) {\n if (handled) {\n return;\n }\n handled = true;\n dealingError(err);\n };\n\n // For the compatibility with Axios\n xhr.ontimeout = function () {\n errHandler(new Error('timeout of ' + xhr.timeout + 'ms exceed'));\n };\n\n // For the compatibility with Axios\n xhr.onerror = function () {\n errHandler(new Error('Network Error'));\n };\n\n // For the compatibility with Axios\n xhr.onabort = function () {\n errHandler(new Error('Cancel'));\n };\n if (xhr.upload) {\n // For the compatibility with Axios\n xhr.upload.ontimeout = function () {\n errHandler(new Error('timeout of ' + xhr.timeout + 'ms exceed'));\n };\n\n // For the compatibility with Axios\n xhr.upload.onerror = function () {\n errHandler(new Error('Network Error'));\n };\n\n // For the compatibility with Axios\n xhr.upload.onabort = function (e) {\n errHandler(new Error('Cancel'));\n };\n }\n if (isFunction(opt.ProgressCallback)) {\n if (method === 'GET' || !xhr.upload) {\n xhr.onprogress = function (event) {\n if (event.lengthComputable) {\n opt.ProgressCallback(event.loaded, event.total, (new Date().getTime() - start) / 1000);\n }\n };\n } else if (method === 'PUT' || method === 'POST') {\n xhr.upload.onprogress = function (event) {\n if (event.lengthComputable) {\n opt.ProgressCallback(event.loaded, event.total, (new Date().getTime() - start) / 1000);\n }\n };\n }\n }\n xhr.send(body);\n};\nUtils.prototype.sendRequest = function (funcName, opt, backcall, retryCount) {\n if (retryCount === undefined) {\n retryCount = 1;\n }\n let uploadPartRetry = false;\n if (retryCount <= opt.$requestParam.maxPartRetryCount) {\n uploadPartRetry = true;\n }\n const host = opt.headers.Host;\n let that = this;\n that.makeRequest(funcName, opt, retryCount, function (err, msg) {\n if (err && err.message === 'redirect') {\n let uri = urlLib.parse(err.location);\n if (err.bucketLocation && uri.hostname.indexOf(opt.$requestParam['Bucket']) !== -1) {\n opt.$requestParam.redirectRegion = err.bucketLocation;\n }\n opt.headers.Host = uri.hostname;\n opt.protocol = uri.protocol;\n opt.port = uri.port || (opt.protocol && opt.protocol.toLowerCase().indexOf('https') === 0 ? 443 : 80);\n that.sendRequest(funcName, opt, backcall, retryCount + 1);\n } else if (funcName === 'UploadPart' && uploadPartRetry && (err || msg.CommonMsg.Status > 300)) {\n opt.headers.Host = host;\n that.sendRequest(funcName, opt, backcall, retryCount + 1);\n } else {\n backcall(err, msg);\n }\n });\n};\nUtils.prototype.doAuth = function (opt, methodName, signatureContext) {\n let interestHeader = ['Content-MD5', 'Content-Type'];\n let stringToSign = opt.method + '\\n';\n for (let i = 0; i < interestHeader.length; i++) {\n if (interestHeader[i] in opt.headers) {\n stringToSign += opt.headers[interestHeader[i]];\n }\n stringToSign += '\\n';\n }\n if (!(signatureContext.headerPrefix + 'date' in opt.headers)) {\n stringToSign += opt.headers.Date;\n }\n stringToSign += '\\n';\n let temp = [];\n for (let originKey in opt.headers) {\n if ({}.hasOwnProperty.call(opt.headers, originKey)) {\n let lowerKey = originKey.toLowerCase();\n if (lowerKey.indexOf(signatureContext.headerPrefix) === 0) {\n temp.push({\n key: lowerKey,\n value: opt.headers[originKey]\n });\n }\n }\n }\n temp = temp.sort(function (obj1, obj2) {\n if (obj1.key < obj2.key) {\n return -1;\n }\n if (obj1.key > obj2.key) {\n return 1;\n }\n return 0;\n });\n for (let i = 0; i < temp.length; i++) {\n let key = temp[i].key;\n let val = key.indexOf(signatureContext.headerMetaPrefix) === 0 ? temp[i].value.trim() : temp[i].value;\n stringToSign += key + ':' + val + '\\n';\n }\n let path = opt.uri;\n if (this.isCname) {\n if (path === '/') {\n path += opt.headers.Host + '/';\n } else if (path.indexOf('/') === 0) {\n path = '/' + opt.headers.Host + path;\n }\n }\n if (opt.urlPath) {\n let _path = opt.urlPath.slice(1);\n let arrPath = _path.split('&').sort();\n let urlPath = '';\n for (let i = 0; i < arrPath.length; i++) {\n let listvar = arrPath[i].split('=');\n let key = decodeURIComponent(listvar[0]);\n if (allowedResourceParameterNames.indexOf(key.toLowerCase()) >= 0) {\n urlPath += urlPath === '' ? '?' : '&';\n urlPath += key;\n if (listvar.length === 2 && listvar[1]) {\n urlPath += '=' + decodeURIComponent(listvar[1]);\n }\n }\n }\n path += urlPath;\n }\n stringToSign += path;\n this.log.runLog('debug', methodName, 'stringToSign:' + stringToSign);\n opt.headers.Authorization = signatureContext.authPrefix + ' ' + this.ak + ':' + crypto.createHmac('sha1', this.sk).update(stringToSign).digest('base64');\n};\nUtils.prototype.v4Auth = function (opt, methodName, signatureContext) {\n opt.headers[signatureContext.headerPrefix + 'content-sha256'] = CONTENT_SHA256;\n let header = opt.headers;\n let log = this.log;\n let shortDate = null;\n let longDate = null;\n if (signatureContext.headerPrefix + 'date' in header) {\n longDate = header[signatureContext.headerPrefix + 'date'];\n shortDate = longDate.slice(0, longDate.indexOf('T'));\n } else {\n let dates = getDates(header.Date);\n shortDate = dates[0];\n longDate = dates[1];\n }\n let credenttial = this.ak + '/' + shortDate + '/' + this.region + '/s3/aws4_request';\n let signedAndCanonicalHeaders = getSignedAndCanonicalHeaders(header);\n let signedHeaders = signedAndCanonicalHeaders[0];\n let canonicalHeaders = signedAndCanonicalHeaders[1];\n let canonicalQueryString = '';\n if (opt.urlPath) {\n let path = opt.urlPath.slice(1);\n let arrPath = path.split('&');\n arrPath = arrPath.sort();\n for (let i = 0; i < arrPath.length; i++) {\n canonicalQueryString += arrPath[i];\n if (arrPath[i].indexOf('=') === -1) {\n canonicalQueryString += '=';\n }\n if (i !== arrPath.length - 1) {\n canonicalQueryString += '&';\n }\n }\n }\n let canonicalRequest = opt.method + '\\n';\n canonicalRequest += opt.uri + '\\n';\n canonicalRequest += canonicalQueryString + '\\n';\n canonicalRequest += canonicalHeaders + '\\n';\n canonicalRequest += signedHeaders + '\\n';\n canonicalRequest += CONTENT_SHA256;\n log.runLog('debug', methodName, 'canonicalRequest:' + canonicalRequest);\n let signature = getV4Signature(shortDate, longDate, this.sk, this.region, canonicalRequest);\n opt.headers.Authorization = 'AWS4-HMAC-SHA256 Credential=' + credenttial + ',SignedHeaders=' + signedHeaders + ',Signature=' + signature;\n};\nUtils.prototype.bufMD5 = function (buf) {\n return crypto.createHash('md5').update(buf).digest('base64');\n};\nUtils.prototype.bufSHA256 = function (buf, type = 'base64') {\n return crypto.createHash('sha256').update(buf).digest(type);\n};\nUtils.prototype.rawBufMD5 = function (buf) {\n return crypto.createHash('md5').update(buf).digest('rawbase64');\n};\nUtils.prototype.createSignedUrl = function (param) {\n let signatureContext = param.signatureContext || this.signatureContext;\n return signatureContext.signature.toLowerCase() === 'v4' ? this.createV4SignedUrlSync(param) : this.createV2SignedUrl(param);\n};\nUtils.prototype.createSignedUrlSync = function (param) {\n let signatureContext = param.signatureContext || this.signatureContext;\n return signatureContext.signature.toLowerCase() === 'v4' ? this.createV4SignedUrlSync(param) : this.createV2SignedUrlSync(param);\n};\nUtils.prototype.getStringToSign = function (opt, param) {\n let {\n isShareFolder,\n queryParams,\n queryParamsKeys\n } = opt;\n let signatureContext = param.signatureContext || this.signatureContext;\n let method = param.Method ? String(param.Method) : 'GET';\n let bucketName = param.Bucket ? String(param.Bucket) : null;\n let objectKey = param.Key ? String(param.Key) : null;\n let policy = param.Policy ? String(param.Policy) : null;\n let expires = param.Expires ? parseInt(param.Expires, 10) : 300;\n if (expires < 0) {\n expires = 300;\n }\n expires = parseInt(new Date().getTime() / 1000, 10) + expires;\n let headers = {};\n if (param.Headers && param.Headers instanceof Object && !(param.Headers instanceof Array)) {\n for (let key in param.Headers) {\n if ({}.hasOwnProperty.call(param.Headers, key)) {\n headers[key] = param.Headers[key];\n }\n }\n }\n let interestHeaders = {};\n for (let name in headers) {\n if ({}.hasOwnProperty.call(headers, name)) {\n let key = String(name).toLowerCase();\n if (key === 'content-type' || key === 'content-md5' || key.length > signatureContext.headerPrefix.length && key.slice(0, signatureContext.headerPrefix.length) === signatureContext.headerPrefix) {\n interestHeaders[key] = headers[name];\n }\n }\n }\n let resource = '';\n let host = this.server;\n if (this.isCname) {\n resource += '/' + host + '/';\n } else if (bucketName) {\n resource += '/' + bucketName;\n if (!this.pathStyle) {\n host = bucketName + '.' + host;\n resource += '/';\n }\n }\n if (objectKey) {\n if (resource.lastIndexOf('/') !== resource.length - 1) {\n resource += '/';\n }\n objectKey = encodeURIWithSafe(objectKey, '/');\n resource += objectKey;\n }\n if (resource === '') {\n resource = '/';\n }\n\n // 拼接查询参数\n queryParamsKeys.sort();\n let flag = false;\n let _resource = [];\n let safeKey = isShareFolder ? '' : '/';\n for (let i = 0; i < queryParamsKeys.length; i++) {\n let key = queryParamsKeys[i];\n let val = queryParams[key];\n key = encodeURIWithSafe(key, safeKey);\n val = encodeURIWithSafe(val, safeKey);\n // 分享文件夹不需要query信息不需要增加 policy\n if ((!isShareFolder || key.toLowerCase() !== 'policy') && (allowedResourceParameterNames.indexOf(key.toLowerCase()) >= 0 || key.toLowerCase().indexOf(signatureContext.headerPrefix) === 0)) {\n flag = true;\n let _val = val ? key + '=' + decodeURIComponent(val) : key;\n _resource.push(_val);\n }\n }\n _resource = _resource.join('&');\n if (flag) {\n _resource = '?' + _resource;\n }\n resource += _resource;\n let stringToSign = [method];\n stringToSign.push('\\n');\n if ('content-md5' in interestHeaders) {\n stringToSign.push(interestHeaders['content-md5']);\n }\n stringToSign.push('\\n');\n if ('content-type' in interestHeaders) {\n stringToSign.push(interestHeaders['content-type']);\n }\n stringToSign.push('\\n');\n if (isShareFolder) {\n stringToSign.push(policy);\n } else {\n stringToSign.push(String(expires));\n }\n stringToSign.push('\\n');\n if (!isShareFolder) {\n let temp = [];\n let i = 0;\n for (let key in interestHeaders) {\n if (key.length > signatureContext.headerPrefix.length && key.slice(0, signatureContext.headerPrefix.length) === signatureContext.headerPrefix) {\n temp[i++] = key;\n }\n }\n temp = temp.sort();\n for (let j = 0; j < temp.length; j++) {\n stringToSign.push(temp[j]);\n stringToSign.push(':');\n stringToSign.push(interestHeaders[temp[j]]);\n stringToSign.push('\\n');\n }\n stringToSign.push(resource);\n } else {\n stringToSign.push(_resource);\n }\n return {\n stringToSign: stringToSign.join(''),\n headers,\n host\n };\n};\nfunction covertStorageClass(storageClass, signature) {\n if (!['storageClass', 'storagePolicy'].includes(storageClass)) {\n return;\n }\n if (signature === 'obs') {\n return 'storageClass';\n }\n if (signature === 'v2') {\n return 'storagePolicy';\n }\n}\n;\nUtils.prototype.getQueryParams = function (param) {\n let policy = param.Policy ? String(param.Policy) : null;\n let prefix = param.Prefix ? String(param.Prefix) : null;\n let expires = param.Expires ? parseInt(param.Expires, 10) : 300;\n // 循环获取参数中的queryParams\n let queryParams = {};\n if (param.QueryParams && param.QueryParams instanceof Object && !(param.QueryParams instanceof Array)) {\n for (let key of Object.keys(param.QueryParams)) {\n queryParams[key] = param.QueryParams[key];\n }\n }\n let specialParam = param.SpecialParam ? String(param.SpecialParam) : null;\n\n // 添加specialParam\n let signatureContext = param.signatureContext || this.signatureContext;\n let sc = covertStorageClass(specialParam, signatureContext.signature.toLowerCase());\n if (sc) {\n specialParam = sc;\n }\n if (specialParam) {\n queryParams[specialParam] = '';\n }\n if (param.AfterStringToSign) {\n const pre = '$';\n queryParams[signatureContext.headerPrefix + 'security-token'] = pre + '{hws:security-token}';\n } else if (this.securityToken && !queryParams[signatureContext.headerPrefix + 'security-token']) {\n queryParams[signatureContext.headerPrefix + 'security-token'] = this.securityToken;\n }\n if (expires < 0) {\n expires = 300;\n }\n expires = parseInt(new Date().getTime() / 1000, 10) + expires;\n let isShareFolder = policy && prefix;\n // 添加policy、prefix、expires\n if (isShareFolder) {\n queryParams.Policy = policy;\n queryParams.prefix = prefix;\n } else {\n queryParams.Expires = String(expires);\n }\n let queryParamsKeys = [];\n Object.keys(queryParams).forEach(e => {\n queryParamsKeys.push(e);\n });\n queryParamsKeys.sort();\n return {\n isShareFolder,\n queryParams,\n queryParamsKeys\n };\n};\nUtils.prototype.getSignResult = function (opt, ak, stsToken) {\n // 获取计算签名时的resulet\n let {\n bucketName,\n objectKey,\n signatureContext,\n isShareFolder,\n queryParams,\n queryParamsKeys\n } = opt;\n // 为queryParams添加钩子函数获取到的ak和token\n if (stsToken) {\n queryParams[signatureContext.headerPrefix + 'security-token'] = stsToken;\n }\n if (signatureContext.signature.toLowerCase() === 'v2') {\n queryParams.AWSAccessKeyId = ak;\n queryParamsKeys.push('AWSAccessKeyId');\n } else {\n queryParams.AccessKeyId = ak;\n queryParamsKeys.push('AccessKeyId');\n }\n let result = '';\n if (bucketName && this.pathStyle) {\n result += '/' + bucketName;\n }\n if (objectKey) {\n objectKey = encodeURIWithSafe(objectKey, '/');\n result += '/' + objectKey;\n }\n result += '?';\n queryParamsKeys.sort();\n let safeKey = isShareFolder ? '' : '/';\n for (let i = 0; i < queryParamsKeys.length; i++) {\n let key = queryParamsKeys[i];\n let val = queryParams[key];\n key = encodeURIWithSafe(key, safeKey);\n val = encodeURIWithSafe(val, safeKey);\n result += key;\n if (val) {\n result += '=' + val;\n }\n result += '&';\n }\n return result;\n};\nUtils.prototype.createV2SignedUrl = function (param) {\n const isSecure = this.isSecure;\n const port = this.port;\n let {\n isShareFolder,\n queryParams,\n queryParamsKeys\n } = this.getQueryParams(param);\n let {\n stringToSign,\n headers,\n host\n } = this.getStringToSign({\n isShareFolder,\n queryParams,\n queryParamsKeys\n }, param);\n let getSignResultOpt = {\n bucketName: param.Bucket ? String(param.Bucket) : null,\n objectKey: param.Key ? String(param.Key) : null,\n signatureContext: param.signatureContext || this.signatureContext,\n isShareFolder,\n queryParams,\n queryParamsKeys\n };\n if (isFunction(param.AfterStringToSign)) {\n return Promise.resolve(param.AfterStringToSign(stringToSign)).then(({\n signature,\n ak,\n stsToken\n }) => {\n let result = this.getSignResult(getSignResultOpt, ak, stsToken);\n return getSignedUrl(signature, result);\n });\n }\n function getSignedUrl(signature, result) {\n if (isShareFolder) {\n result += 'Signature=' + encodeURIWithSafe(signature);\n } else {\n result += 'Signature=' + encodeURIWithSafe(signature, '/');\n }\n return {\n ActualSignedRequestHeaders: headers,\n SignedUrl: (isSecure ? 'https' : 'http') + '://' + host + ':' + port + result\n };\n }\n};\nUtils.prototype.createV2SignedUrlSync = function (param) {\n let {\n isShareFolder,\n queryParams,\n queryParamsKeys\n } = this.getQueryParams(param);\n let {\n stringToSign,\n headers,\n host\n } = this.getStringToSign({\n isShareFolder,\n queryParams,\n queryParamsKeys\n }, param);\n let getSignResultOpt = {\n bucketName: param.Bucket ? String(param.Bucket) : null,\n objectKey: param.Key ? String(param.Key) : null,\n signatureContext: param.signatureContext || this.signatureContext,\n isShareFolder,\n queryParams,\n queryParamsKeys\n };\n let result = this.getSignResult(getSignResultOpt, this.ak, this.securityToken);\n let hmac = crypto.createHmac('sha1', this.sk);\n hmac.update(stringToSign);\n if (isShareFolder) {\n result += 'Signature=' + encodeURIWithSafe(hmac.digest('base64'));\n } else {\n result += 'Signature=' + encodeURIWithSafe(hmac.digest('base64'), '/');\n }\n return {\n ActualSignedRequestHeaders: headers,\n SignedUrl: (this.isSecure ? 'https' : 'http') + '://' + host + ':' + this.port + result\n };\n};\nUtils.prototype.createV4SignedUrlSync = function (param) {\n param = param || {};\n let signatureContext = param.signatureContext || this.signatureContext;\n let method = param.Method ? String(param.Method) : 'GET';\n let bucketName = param.Bucket ? String(param.Bucket) : null;\n let objectKey = param.Key ? String(param.Key) : null;\n let specialParam = param.SpecialParam ? String(param.SpecialParam) : null;\n if (specialParam === 'storageClass') {\n specialParam = 'storagePolicy';\n }\n let expires = param.Expires ? parseInt(param.Expires, 10) : 300;\n let headers = {};\n if (param.Headers && param.Headers instanceof Object && !(param.Headers instanceof Array)) {\n for (let key in param.Headers) {\n if ({}.hasOwnProperty.call(param.Headers, key)) {\n headers[key] = param.Headers[key];\n }\n }\n }\n let queryParams = {};\n if (param.QueryParams && param.QueryParams instanceof Object && !(param.QueryParams instanceof Array)) {\n for (let key in param.QueryParams) {\n if ({}.hasOwnProperty.call(param.QueryParams, key)) {\n queryParams[key] = param.QueryParams[key];\n }\n }\n }\n if (this.securityToken && !queryParams[signatureContext.headerPrefix + 'security-token']) {\n queryParams[signatureContext.headerPrefix + 'security-token'] = this.securityToken;\n }\n let result = '';\n let resource = '';\n let host = this.server;\n if (bucketName) {\n if (this.pathStyle) {\n result += '/' + bucketName;\n resource += '/' + bucketName;\n } else {\n host = bucketName + '.' + host;\n }\n }\n if (objectKey) {\n objectKey = encodeURIWithSafe(objectKey, '/');\n result += '/' + objectKey;\n resource += '/' + objectKey;\n }\n if (resource === '') {\n resource = '/';\n }\n result += '?';\n if (specialParam) {\n queryParams[specialParam] = '';\n }\n if (expires < 0) {\n expires = 300;\n }\n let utcDateStr = headers['date'] || headers['Date'] || new Date().toUTCString();\n let dates = getDates(utcDateStr);\n let shortDate = dates[0];\n let longDate = dates[1];\n headers.Host = host + (this.port === 80 || this.port === 443 ? '' : ':' + this.port);\n queryParams['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';\n queryParams['X-Amz-Credential'] = this.ak + '/' + shortDate + '/' + this.region + '/s3/aws4_request';\n queryParams['X-Amz-Date'] = longDate;\n queryParams['X-Amz-Expires'] = String(expires);\n let signedAndCanonicalHeaders = getSignedAndCanonicalHeaders(headers);\n queryParams['X-Amz-SignedHeaders'] = signedAndCanonicalHeaders[0];\n let _queryParams = {};\n let queryParamsKeys = [];\n for (let key in queryParams) {\n if ({}.hasOwnProperty.call(queryParams, key)) {\n let val = queryParams[key];\n key = encodeURIWithSafe(key, '/');\n val = encodeURIWithSafe(val);\n _queryParams[key] = val;\n queryParamsKeys.push(key);\n result += key;\n if (val) {\n result += '=' + val;\n }\n result += '&';\n }\n }\n let canonicalQueryString = '';\n queryParamsKeys.sort();\n for (let i = 0; i < queryParamsKeys.length;) {\n canonicalQueryString += queryParamsKeys[i] + '=' + _queryParams[queryParamsKeys[i]];\n if (++i !== queryParamsKeys.length) {\n canonicalQueryString += '&';\n }\n }\n let canonicalRequest = method + '\\n';\n canonicalRequest += resource + '\\n';\n canonicalRequest += canonicalQueryString + '\\n';\n canonicalRequest += signedAndCanonicalHeaders[1] + '\\n';\n canonicalRequest += signedAndCanonicalHeaders[0] + '\\n';\n canonicalRequest += 'UNSIGNED-PAYLOAD';\n let signature = getV4Signature(shortDate, longDate, this.sk, this.region, canonicalRequest);\n result += 'X-Amz-Signature=' + encodeURIWithSafe(signature);\n return {\n ActualSignedRequestHeaders: headers,\n SignedUrl: (this.isSecure ? 'https' : 'http') + '://' + host + ':' + this.port + result\n };\n};\nUtils.prototype.createPostSignatureSync = function (param) {\n let signatureContext = param.signatureContext || this.signatureContext;\n if (signatureContext.signature === 'v4') {\n return this.createV4PostSignatureSync(param);\n }\n param = param || {};\n let bucketName = param.Bucket ? String(param.Bucket) : null;\n let objectKey = param.Key ? String(param.Key) : null;\n let expires = param.Expires ? parseInt(param.Expires, 10) : 300;\n let formParams = {};\n if (param.FormParams && param.FormParams instanceof Object && !(param.FormParams instanceof Array)) {\n for (let key in param.FormParams) {\n if ({}.hasOwnProperty.call(param.FormParams, key)) {\n formParams[key] = param.FormParams[key];\n }\n }\n }\n if (this.securityToken && !formParams[signatureContext.headerPrefix + 'security-token']) {\n formParams[signatureContext.headerPrefix + 'security-token'] = this.securityToken;\n }\n let expireDate = new Date();\n expireDate.setTime(parseInt(new Date().getTime(), 10) + expires * 1000);\n expireDate = getExpireDate(expireDate.toUTCString());\n if (bucketName) {\n formParams.bucket = bucketName;\n }\n if (objectKey) {\n formParams.key = objectKey;\n }\n let policy = [];\n policy.push('{\"expiration\":\"');\n policy.push(expireDate);\n policy.push('\", \"conditions\":[');\n let matchAnyBucket = true;\n let matchAnyKey = true;\n let conditionAllowKeys = ['acl', 'bucket', 'key', 'success_action_redirect', 'redirect', 'success_action_status'];\n for (let key in formParams) {\n if (!key) {\n continue;\n }\n let val = formParams[key];\n key = String(key).toLowerCase();\n if (key === 'bucket') {\n matchAnyBucket = false;\n } else if (key === 'key') {\n matchAnyKey = false;\n }\n if (allowedResponseHttpHeaderMetadataNames.indexOf(key) < 0 && conditionAllowKeys.indexOf(key) < 0 && key.indexOf(signatureContext.headerPrefix) !== 0) {\n continue;\n }\n policy.push('{\"');\n policy.push(key);\n policy.push('\":\"');\n policy.push(val !== null ? String(val) : '');\n policy.push('\"},');\n }\n if (matchAnyBucket) {\n policy.push('[\"starts-with\", \"$bucket\", \"\"],');\n }\n if (matchAnyKey) {\n policy.push('[\"starts-with\", \"$key\", \"\"],');\n }\n policy.push(']}');\n let originPolicy = policy.join('');\n if (window.btoa) {\n policy = window.btoa(originPolicy);\n } else {\n policy = Base64.encode(originPolicy);\n }\n let signature = crypto.createHmac('sha1', this.sk).update(policy).digest('base64');\n return {\n OriginPolicy: originPolicy,\n Policy: policy,\n Signature: signature,\n Token: this.ak + ':' + signature + ':' + policy\n };\n};\nUtils.prototype.createV4PostSignatureSync = function (param) {\n param = param || {};\n let signatureContext = param.signatureContext || this.signatureContext;\n let bucketName = param.Bucket ? String(param.Bucket) : null;\n let objectKey = param.Key ? String(param.Key) : null;\n let expires = param.Expires ? parseInt(param.Expires, 10) : 300;\n let formParams = {};\n if (param.FormParams && param.FormParams instanceof Object && !(param.FormParams instanceof Array)) {\n for (let key in param.FormParams) {\n if ({}.hasOwnProperty.call(param.FormParams, key)) {\n formParams[key] = param.FormParams[key];\n }\n }\n }\n if (this.securityToken && !formParams[signatureContext.headerPrefix + 'security-token']) {\n formParams[signatureContext.headerPrefix + 'security-token'] = this.securityToken;\n }\n let utcDateStr = new Date().toUTCString();\n let dates = getDates(utcDateStr);\n let shortDate = dates[0];\n let longDate = dates[1];\n let credential = this.ak + '/' + shortDate + '/' + this.region + '/s3/aws4_request';\n let expireDate = new Date();\n expireDate.setTime(parseInt(new Date().getTime(), 10) + expires * 1000);\n expireDate = getExpireDate(expireDate.toUTCString());\n formParams['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';\n formParams['X-Amz-Date'] = longDate;\n formParams['X-Amz-Credential'] = credential;\n if (bucketName) {\n formParams.bucket = bucketName;\n }\n if (objectKey) {\n formParams.key = objectKey;\n }\n let policy = [];\n policy.push('{\"expiration\":\"');\n policy.push(expireDate);\n policy.push('\", \"conditions\":[');\n let matchAnyBucket = true;\n let matchAnyKey = true;\n let conditionAllowKeys = ['acl', 'bucket', 'key', 'success_action_redirect', 'redirect', 'success_action_status'];\n for (let key in formParams) {\n if (!key) {\n continue;\n }\n let val = formParams[key];\n key = String(key).toLowerCase();\n if (key === 'bucket') {\n matchAnyBucket = false;\n } else if (key === 'key') {\n matchAnyKey = false;\n }\n if (allowedResponseHttpHeaderMetadataNames.indexOf(key) < 0 && conditionAllowKeys.indexOf(key) < 0 && key.indexOf(signatureContext.headerPrefix) !== 0) {\n continue;\n }\n policy.push('{\"');\n policy.push(key);\n policy.push('\":\"');\n policy.push(val !== null ? String(val) : '');\n policy.push('\"},');\n }\n if (matchAnyBucket) {\n policy.push('[\"starts-with\", \"$bucket\", \"\"],');\n }\n if (matchAnyKey) {\n policy.push('[\"starts-with\", \"$key\", \"\"],');\n }\n policy.push(']}');\n let originPolicy = policy.join('');\n if (window.btoa) {\n policy = window.btoa(originPolicy);\n } else {\n policy = Base64.encode(originPolicy);\n }\n let signature = createV4Signature(shortDate, this.sk, this.region, policy);\n return {\n OriginPolicy: originPolicy,\n Policy: policy,\n Algorithm: formParams['X-Amz-Algorithm'],\n Credential: formParams['X-Amz-Credential'],\n Date: formParams['X-Amz-Date'],\n Signature: signature\n };\n};\nexport default Utils;","map":{"version":3,"names":["URI","axios","SHA","Base64","md5","xml2js","obsModel","v2Model","ContentMD5","ContentSHA256","crypto","createHmac","algorithm","key","algorithmKey","shaObj","setHMACKey","ArrayBuffer","update","message","digest","type","getHMAC","createHash","encodeFunc","window","btoa","encode","getHash","urlLib","parse","url","uri","hostname","port","host","protocol","query","path","pathname","search","CONTENT_SHA256","OBS_SDK_VERSION","mimeTypes","allowedResourceParameterNames","allowedResponseHttpHeaderMetadataNames","commonHeaders","obsAllowedStorageClass","v2AllowedStorageClass","obsAllowedAcl","v2AllowedAcl","obsAllowedUri","v2AllowedUri","obsAllowedEvent","v2AllowedEvent","ignoreNegotiationMethod","negotiateMethod","obsSignatureContext","signature","headerPrefix","headerMetaPrefix","authPrefix","v2SignatureContext","encodeURIWithSafe","str","safe","skipEncoding","String","length","ret","element","push","indexOf","encodeURIComponent","join","replace","headerTostring","obj","JSON","stringify","parseObjectFromHeaders","sentAs","headers","metadata","hasOwnProperty","call","k","toLowerCase","slice","isArray","Object","prototype","toString","isFunction","isObject","makeObjFromXml","xml","bc","parseString","err","getExpireDate","utcDateStr","date","Date","hour","getUTCHours","min","getUTCMinutes","sec","getUTCSeconds","day","getUTCDate","moth","getUTCMonth","year","getUTCFullYear","expireDate","getDates","shortDate","longDate","getSignedAndCanonicalHeaders","header","arrheadKey","arrhead","sort","signedHeaders","canonicalHeaders","i","createV4Signature","sk","region","stringToSign","dateKey","dateRegionKey","dateRegionServiceKey","signingKey","getV4Signature","canonicalRequest","scop","Utils","log_in","log","ak","securityToken","isSecure","server","pathStyle","signatureContext","isSignatureNegotiation","bucketSignatureCache","timeout","obsSdkVersion","isCname","bucketEventEmitters","useRawXhr","refresh","trim","initFactory","urlPrefix","regionDomains","setRequestHeaderHook","checksumAlgorithm","checkAlgorithm","Error","index","lastIndexOf","test","undefined","parseInt","SseKmsAdapter","value","SseModeAdapter","BucketAdapter","EventAdapter","substring","EventsAdapter","URIAdapter","StorageClassAdapter","toUpperCase","ACLAdapter","doExec","funcName","param","callback","opt","makeParam","sendRequest","doNegotiation","checkBucket","checkCache","setCache","o","that","Bucket","item","expireTime","getTime","s","n","e","shift","hasRegion","result","CommonMsg","Status","InterfaceResult","ApiVersion","Math","ceil","random","exec","_callback","Message","sliceBlob","blob","start","end","mozSlice","webkitSlice","toXml","mXml","xmlMeta","root","buildXml","_sentAs","items","parameters","data","xsiNamespace","xsiType","wrapper","_wrapper","jsonToObject","model","ifRootXMlDecode","buildObject","setValue","decode","decodeURIComponent","flag","arr","methodName","method","httpMethod","urlPath","exheaders","$requestParam","meta","_value","_key","keys","_meta","_keyValue","required","runLog","newKey","withPrefix","location","encodingSafe","pwdSentAs","rawBufMD5","Number","val","sep","mxml","isFile","dstFile","xmlAllowEmpty","xmlRoot","rawUri","Host","uriList","split","requestUri","bufSHA256","bufMD5","srcFile","File","Blob","fileSize","size","offset","Offset","partSize","PartSize","parseCommonHeaders","RequestId","Id2","contrustCommonMsg","getRequest","serverback","retryCount","params","status","Code","HostId","headersStr","doLog","logMsg","Location","redirectErr","bucketLocation","regionServer","body","respMsg","CallbackUrl","CallbackResponse","tempResult","EncodingType","Indicator","re","errMsg","code","hostId","request_id","makeRequest","Authorization","queryParams","arrPath","temp","bucketName","objectKey","createSignedUrlSync","Method","Key","Expires","Headers","QueryParams","requestDate","RequestDate","nowDate","requestDateType","setTime","toUTCString","isV4","v4Auth","doAuth","ex","header_msg","msg","_isSecure","responseType","dealingError","headerStr","onUploadProgress","onDownloadProgress","ProgressCallback","progressListener","event","lengthComputable","loaded","total","portInfo","baseUrl","httpPrefix","defaultRegion","portFlag","reopt","withCredentials","validateStatus","maxRedirects","cancelToken","CancelToken","cancelHook","contentLength","ContentLength","request","then","response","catch","xhr","XMLHttpRequest","ActiveXObject","e1","e2","open","setRequestHeader","abort","onreadystatechange","readyState","getAllResponseHeaders","headerMap","line","parts","responseText","handled","errHandler","ontimeout","onerror","onabort","upload","onprogress","send","backcall","uploadPartRetry","maxPartRetryCount","redirectRegion","interestHeader","originKey","lowerKey","obj1","obj2","_path","listvar","dates","credenttial","signedAndCanonicalHeaders","canonicalQueryString","buf","createSignedUrl","createV4SignedUrlSync","createV2SignedUrl","createV2SignedUrlSync","getStringToSign","isShareFolder","queryParamsKeys","policy","Policy","expires","Array","interestHeaders","name","resource","_resource","safeKey","_val","j","covertStorageClass","storageClass","includes","getQueryParams","prefix","Prefix","specialParam","SpecialParam","sc","AfterStringToSign","pre","forEach","getSignResult","stsToken","AWSAccessKeyId","AccessKeyId","getSignResultOpt","Promise","resolve","getSignedUrl","ActualSignedRequestHeaders","SignedUrl","hmac","_queryParams","createPostSignatureSync","createV4PostSignatureSync","formParams","FormParams","bucket","matchAnyBucket","matchAnyKey","conditionAllowKeys","originPolicy","OriginPolicy","Signature","Token","credential","Algorithm","Credential"],"sources":["F:/workspace/202226701027/huinongbao-app/node_modules/esdk-obs-browserjs/src/utils.js"],"sourcesContent":["/**\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\nimport URI from 'urijs';\nimport axios from 'axios';\nimport SHA from 'jssha';\nimport { Base64 } from 'js-base64';\nimport md5 from 'blueimp-md5';\nimport xml2js from './xml2js';\nimport obsModel from './obsModel';\nimport v2Model from './v2Model';\nimport { ContentMD5, ContentSHA256 } from './enums';\n\nconst crypto = {\n\t\tcreateHmac : function(algorithm, key){\n\t\t\tlet algorithmKey;\n\t\t\tif(algorithm === 'sha1'){\n\t\t\t\talgorithmKey = 'SHA-1';\n\t\t\t}else if(algorithm === 'sha512'){\n\t\t\t\talgorithmKey = 'SHA-512';\n\t\t\t}else{\n\t\t\t\talgorithmKey = 'SHA-256';\n\t\t\t}\n\t\t\tlet shaObj = new SHA(algorithmKey, 'TEXT');\n\t\t\tshaObj.setHMACKey(key, (key instanceof ArrayBuffer) ? 'ARRAYBUFFER' : 'TEXT');\n\t\t\treturn {\n\t\t\t\tupdate : function(message){\n\t\t\t\t\tshaObj.update(message);\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\tdigest : function(type){\n\t\t\t\t\tif(type === 'hex'){\n\t\t\t\t\t\treturn shaObj.getHMAC('HEX');\n\t\t\t\t\t}\n\t\t\t\t\tif(type === 'base64'){\n\t\t\t\t\t\treturn shaObj.getHMAC('B64');\n\t\t\t\t\t}\n\t\t\t\t\treturn shaObj.getHMAC('ARRAYBUFFER');\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\n\t\tcreateHash : function(algorithm){\n\t\t\tif(algorithm === 'md5'){\n\t\t\t\treturn {\n\t\t\t\t\tupdate : function(message){\n\t\t\t\t\t\tif(!this.message){\n\t\t\t\t\t\t\tthis.message = message;\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\tthis.message += message;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn this;\n\t\t\t\t\t},\n\n\t\t\t\t\tdigest : function(type){\n\t\t\t\t\t\tif(type === 'hex'){\n\t\t\t\t\t\t\treturn md5(this.message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(type === 'base64'){\n\t\t\t\t\t\t\tlet encodeFunc = window.btoa ? window.btoa : Base64.encode;\n\t\t\t\t\t\t\treturn encodeFunc(md5(this.message, false, true));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(type === 'rawbase64'){\n\t\t\t\t\t\t\tlet encodeFunc = window.btoa ? window.btoa : Base64.encode;\n\t\t\t\t\t\t\treturn encodeFunc(md5(this.message, false, true));\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn md5(this.message, false, true);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlet algorithmKey;\n\t\t\tif(algorithm === 'sha1'){\n\t\t\t\talgorithmKey = 'SHA-1';\n\t\t\t}else if(algorithm === 'sha512'){\n\t\t\t\talgorithmKey = 'SHA-512';\n\t\t\t}else{\n\t\t\t\talgorithmKey = 'SHA-256';\n\t\t\t}\n\t\t\tlet shaObj = new SHA(algorithmKey, 'TEXT');\n\n\t\t\treturn {\n\t\t\t\tupdate : function(message){\n\t\t\t\t\tshaObj.update(message);\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\tdigest : function(type){\n\t\t\t\t\tif(type === 'hex'){\n\t\t\t\t\t\treturn shaObj.getHash('HEX');\n\t\t\t\t\t}\n\t\t\t\t\tif(type === 'base64'){\n\t\t\t\t\t\treturn shaObj.getHash('B64');\n\t\t\t\t\t}\n\t\t\t\t\treturn shaObj.getHash('ARRAYBUFFER');\n\t\t\t\t}\n\t\t\t};\n\t\t}\n};\n\nconst urlLib = {\n\t\tparse : function(url){\n\t\t\tlet uri = URI.parse(url);\n\t\t\treturn {\n\t\t\t\thostname : uri.hostname,\n\n\t\t\t\tport : uri.port,\n\n\t\t\t\thost : uri.hostname,\n\n\t\t\t\tprotocol : uri.protocol ? uri.protocol + ':' : '',\n\n\t\t\t\tquery : uri.query,\n\n\t\t\t path : uri.path + (uri.query ? '?' + uri.query : ''),\n\n\t\t\t pathname :uri.path,\n\n\t\t\t search : uri.query ? '?' + uri.query : ''\n\t\t\t};\n\t\t}\n};\n\nconst CONTENT_SHA256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';\nconst OBS_SDK_VERSION = '3.22.3';\n\nconst mimeTypes = {\n '7z' : 'application/x-7z-compressed',\n 'aac' : 'audio/x-aac',\n 'ai' : 'application/postscript',\n 'aif' : 'audio/x-aiff',\n 'asc' : 'text/plain',\n 'asf' : 'video/x-ms-asf',\n 'atom' : 'application/atom+xml',\n 'avi' : 'video/x-msvideo',\n 'bmp' : 'image/bmp',\n 'bz2' : 'application/x-bzip2',\n 'cer' : 'application/pkix-cert',\n 'crl' : 'application/pkix-crl',\n 'crt' : 'application/x-x509-ca-cert',\n 'css' : 'text/css',\n 'csv' : 'text/csv',\n 'cu' : 'application/cu-seeme',\n 'deb' : 'application/x-debian-package',\n 'doc' : 'application/msword',\n 'docx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'dvi' : 'application/x-dvi',\n 'eot' : 'application/vnd.ms-fontobject',\n 'eps' : 'application/postscript',\n 'epub' : 'application/epub+zip',\n 'etx' : 'text/x-setext',\n 'flac' : 'audio/flac',\n 'flv' : 'video/x-flv',\n 'gif' : 'image/gif',\n 'gz' : 'application/gzip',\n 'htm' : 'text/html',\n 'html' : 'text/html',\n 'ico' : 'image/x-icon',\n 'ics' : 'text/calendar',\n 'ini' : 'text/plain',\n 'iso' : 'application/x-iso9660-image',\n 'jar' : 'application/java-archive',\n 'jpe' : 'image/jpeg',\n 'jpeg' : 'image/jpeg',\n 'jpg' : 'image/jpeg',\n 'js' : 'text/javascript',\n 'json' : 'application/json',\n 'latex' : 'application/x-latex',\n 'log' : 'text/plain',\n 'm4a' : 'audio/mp4',\n 'm4v' : 'video/mp4',\n 'mid' : 'audio/midi',\n 'midi' : 'audio/midi',\n 'mov' : 'video/quicktime',\n 'mp3' : 'audio/mpeg',\n 'mp4' : 'video/mp4',\n 'mp4a' : 'audio/mp4',\n 'mp4v' : 'video/mp4',\n 'mpe' : 'video/mpeg',\n 'mpeg' : 'video/mpeg',\n 'mpg' : 'video/mpeg',\n 'mpg4' : 'video/mp4',\n 'oga' : 'audio/ogg',\n 'ogg' : 'audio/ogg',\n 'ogv' : 'video/ogg',\n 'ogx' : 'application/ogg',\n 'pbm' : 'image/x-portable-bitmap',\n 'pdf' : 'application/pdf',\n 'pgm' : 'image/x-portable-graymap',\n 'png' : 'image/png',\n 'pnm' : 'image/x-portable-anymap',\n 'ppm' : 'image/x-portable-pixmap',\n 'ppt' : 'application/vnd.ms-powerpoint',\n 'pptx' : 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n 'ps' : 'application/postscript',\n 'qt' : 'video/quicktime',\n 'rar' : 'application/x-rar-compressed',\n 'ras' : 'image/x-cmu-raster',\n 'rss' : 'application/rss+xml',\n 'rtf' : 'application/rtf',\n 'sgm' : 'text/sgml',\n 'sgml' : 'text/sgml',\n 'svg' : 'image/svg+xml',\n 'swf' : 'application/x-shockwave-flash',\n 'tar' : 'application/x-tar',\n 'tif' : 'image/tiff',\n 'tiff' : 'image/tiff',\n 'torrent' : 'application/x-bittorrent',\n 'ttf' : 'application/x-font-ttf',\n 'txt' : 'text/plain',\n 'wav' : 'audio/x-wav',\n 'webm' : 'video/webm',\n 'wma' : 'audio/x-ms-wma',\n 'wmv' : 'video/x-ms-wmv',\n 'woff' : 'application/x-font-woff',\n 'wsdl' : 'application/wsdl+xml',\n 'xbm' : 'image/x-xbitmap',\n 'xls' : 'application/vnd.ms-excel',\n 'xlsx' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'xml' : 'application/xml',\n 'xpm' : 'image/x-xpixmap',\n 'xwd' : 'image/x-xwindowdump',\n 'yaml' : 'text/yaml',\n 'yml' : 'text/yaml',\n 'zip' : 'application/zip',\n};\n\n\nconst allowedResourceParameterNames = [\n\t'inventory',\n\t'acl',\n\t'backtosource',\n 'policy',\n 'torrent',\n 'logging',\n 'location',\n 'storageinfo',\n 'quota',\n 'storageclass',\n 'storagepolicy',\n 'mirrorbacktosource',\n 'requestpayment',\n 'versions',\n 'versioning',\n 'versionid',\n 'uploads',\n 'uploadid',\n 'partnumber',\n 'website',\n 'notification',\n 'replication',\n 'lifecycle',\n 'deletebucket',\n 'delete',\n 'cors',\n 'restore',\n 'tagging',\n 'append',\n 'position',\n 'response-content-type',\n 'response-content-language',\n 'response-expires',\n 'response-cache-control',\n 'response-content-disposition',\n 'response-content-encoding',\n 'x-image-process',\n\t'x-image-save-object',\n 'x-image-save-bucket',\n 'x-oss-process',\n\t'encryption',\n\t'obsworkflowtriggerpolicy',\n\t'x-workflow-limit',\n\t'x-workflow-prefix',\n\t'x-workflow-start',\n\t'x-workflow-template-name',\n\t'x-workflow-graph-name',\n\t'x-workflow-execution-state',\n\t'x-workflow-category',\n\t'x-workflow-prefix',\n\t'x-workflow-create',\n\t'directcoldaccess',\n\t'customdomain',\n\t'cdnnotifyconfiguration',\n\t'metadata',\n\t'dispolicy',\n\t'obscompresspolicy',\n\t'template_name',\n\t'template_name_prefix',\n\t'x-workflow-status',\n\t'x-workflow-type',\n\t'x-workflow-forbid',\n\t'sfsacl',\n\t'obsbucketalias',\n\t'obsalias',\n\t'rename',\n 'name',\n 'modify',\n\t'attname',\n\t'inventory',\n\t'truncate',\n\t'object-lock',\n\t\"retention\",\n\t'x-obs-security-token',\n];\n\n\nconst allowedResponseHttpHeaderMetadataNames = [\n 'content-type',\n 'content-md5',\n 'content-length',\n 'content-language',\n 'expires',\n 'origin',\n 'cache-control',\n 'content-disposition',\n 'content-encoding',\n 'x-default-storage-class',\n 'location',\n 'date',\n 'etag',\n 'host',\n 'last-modified',\n 'content-range',\n 'x-reserved',\n 'access-control-allow-origin',\n 'access-control-allow-headers',\n 'access-control-max-age',\n 'access-control-allow-methods',\n 'access-control-expose-headers',\n\t'connection',\n\t'x-obs-location-clustergroup-id'\n];\n\nconst commonHeaders = {\n\t'content-length' : 'ContentLength',\n\t'date' : 'Date',\n\t'x-reserved' : 'Reserved'\n};\n\nconst obsAllowedStorageClass = ['STANDARD', 'WARM', 'COLD', 'DEEP_ARCHIVE', 'INTELLIGENT_TIERING'];\n\nconst v2AllowedStorageClass = ['STANDARD', 'STANDARD_IA', 'GLACIER', 'DEEP_ARCHIVE', 'INTELLIGENT_TIERING'];\n\nconst obsAllowedAcl = ['private', 'public-read', 'public-read-write', 'public-read-delivered', 'public-read-write-delivered'];\n\nconst v2AllowedAcl = ['private', 'public-read', 'public-read-write', 'authenticated-read', 'bucket-owner-read', 'bucket-owner-full-control', 'log-delivery-write'];\n\nconst obsAllowedUri = ['Everyone', 'LogDelivery'];\n\nconst v2AllowedUri = ['http://acs.amazonaws.com/groups/global/AllUsers', 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers', 'http://acs.amazonaws.com/groups/s3/LogDelivery'];\n\nconst obsAllowedEvent = ['ObjectCreated', 'ObjectCreated:*', 'ObjectCreated:Put', 'ObjectCreated:Post', 'ObjectCreated:Copy', 'ObjectCreated:CompleteMultipartUpload', \n\t'ObjectRemoved', 'ObjectRemoved:*', 'ObjectRemoved:Delete', 'ObjectRemoved:DeleteMarkerCreated',\n\t'ObjectChanged:*', 'ObjectChanged:Rename', 'ObjectChanged:Truncate', 'ObjectChanged:Modify'];\nconst v2AllowedEvent = ['ObjectCreated', 's3:ObjectCreated:*', 's3:ObjectCreated:Put', 's3:ObjectCreated:Post', 's3:ObjectCreated:Copy','s3:ObjectCreated:CompleteMultipartUpload', \n\t'ObjectRemoved', 's3:ObjectRemoved:*', 's3:ObjectRemoved:Delete', 's3:ObjectRemoved:DeleteMarkerCreated', 'ObjectRemoved:*', 'ObjectRemoved:Delete', 'ObjectRemoved:DeleteMarkerCreated',\n 'ObjectChanged:*', 'ObjectChanged:Rename', 'ObjectChanged:Truncate', 'ObjectChanged:Modify'];\n\nconst ignoreNegotiationMethod =['CreateBucket','SetBucketAlias','BindBucketAlias','UnbindBucketAlias','DeleteBucketAlias','GetBucketAlias'];\nconst negotiateMethod = 'HeadApiVersion';\n\nconst obsSignatureContext = {\n\tsignature :\t'obs',\n\theaderPrefix : 'x-obs-',\n\theaderMetaPrefix : 'x-obs-meta-',\n\tauthPrefix : 'OBS'\n};\n\nconst v2SignatureContext = {\n\tsignature :\t'v2',\n\theaderPrefix : 'x-amz-',\n\theaderMetaPrefix : 'x-amz-meta-',\n\tauthPrefix : 'AWS'\n};\n\nfunction encodeURIWithSafe(str, safe, skipEncoding){\n\tstr = String(str);\n\tif(str.length === 0){\n\t\treturn '';\n\t}\n\tif(skipEncoding){\n\t\treturn str;\n\t}\n\tlet ret;\n\tif (safe) {\n\t\tret = [];\n\t\tfor (const element of str) {\n\t\t\tret.push(safe.indexOf(element) >= 0 ? element : encodeURIComponent(element));\n\t\t}\n\t\tret = ret.join('');\n\t}else{\n\t\tret = encodeURIComponent(str);\n\t}\n\treturn ret.replace(/!/g, '%21')\n\t\t\t .replace(/\\*/g, '%2A')\n\t\t\t .replace(/'/g, '%27')\n\t\t\t .replace(/\\(/g, '%28')\n\t\t\t .replace(/\\)/g, '%29');\n}\n\nfunction headerTostring(obj){\n\treturn JSON ? JSON.stringify(obj) : '';\n}\n\nfunction parseObjectFromHeaders(sentAs, headers){\n\tlet metadata = {};\n\tfor(let key in headers){\n\t\tif ({}.hasOwnProperty.call(headers, key)) {\n\t\t\tlet k = String(key).toLowerCase();\n\t\t\tif (k.indexOf(sentAs) === 0) {\n\t\t\t\tmetadata[k.slice(sentAs.length)] = headers[key];\n\t\t\t}\n\t\t}\n\t}\n\treturn metadata;\n}\n\nfunction isArray(obj){\n\treturn Object.prototype.toString.call(obj) === '[object Array]';\n}\n\nfunction isFunction(obj){\n\treturn Object.prototype.toString.call(obj) === '[object Function]';\n}\n\nfunction isObject(obj){\n\treturn Object.prototype.toString.call(obj) === '[object Object]';\n}\n\n\nfunction makeObjFromXml(xml, bc){\n\tif (typeof xml === 'object') {\n\t\treturn bc(null, xml);\n\t}\n\ttry{\n\t\treturn bc(null, xml2js.parseString(xml));\n\t}catch(err){\n\t\treturn bc(err, null);\n\t}\n}\n\nfunction getExpireDate(utcDateStr){\n\tlet date = new Date(Date.parse(utcDateStr));\n\tlet hour = date.getUTCHours();\n\tlet min = date.getUTCMinutes();\n\tlet sec = date.getUTCSeconds();\n\tlet day = date.getUTCDate();\n\tlet moth = date.getUTCMonth() + 1;\n\tlet year = date.getUTCFullYear();\n\tlet expireDate = '';\n\texpireDate += year + '-';\n\n\tif(moth < 10){\n\t\texpireDate += '0';\n\t}\n\texpireDate += moth + '-';\n\n\tif(day < 10){\n\t\texpireDate += '0';\n\t}\n\texpireDate += day + 'T';\n\n\tif(hour < 10){\n\t\texpireDate += '0';\n\t}\n\texpireDate += hour + ':';\n\n\tif(min < 10){\n\t\texpireDate += '0';\n\t}\n\texpireDate += min + ':';\n\n\tif(sec < 10){\n\t\texpireDate += '0';\n\t}\n\texpireDate += sec + 'Z';\n\treturn expireDate;\n}\n\nfunction getDates(utcDateStr){\n\tlet date = new Date(Date.parse(utcDateStr));\n\tlet hour = date.getUTCHours();\n\tlet min = date.getUTCMinutes();\n\tlet sec = date.getUTCSeconds();\n\tlet day = date.getUTCDate();\n\tlet moth = date.getUTCMonth() + 1;\n\tlet year = date.getUTCFullYear();\n\tlet shortDate = '';\n\tlet longDate = '';\n\tshortDate += year;\n\n\tif(moth < 10){\n\t\tshortDate += '0';\n\t}\n\tshortDate += moth;\n\n\tif(day < 10){\n\t\tshortDate += '0';\n\t}\n\tshortDate += day;\n\n\tlongDate += shortDate + 'T';\n\tif(hour < 10){\n\t\tlongDate += '0';\n\t}\n\tlongDate += hour;\n\n\tif(min < 10){\n\t\tlongDate += '0';\n\t}\n\tlongDate += min;\n\n\tif(sec < 10){\n\t\tlongDate += '0';\n\t}\n\tlongDate += sec + 'Z';\n\treturn [shortDate, longDate];\n}\n\nfunction getSignedAndCanonicalHeaders(header){\n\tlet arrheadKey = [];\n\tlet arrhead = {};\n\tfor(let key in header){\n\t\tif ({}.hasOwnProperty.call(header, key)) {\n\t\t\tarrheadKey.push(key.toLowerCase());\n\t\t\tarrhead[key.toLowerCase()] = header[key];\n\t\t}\n\t}\n\tarrheadKey = arrheadKey.sort();\n\tlet signedHeaders = '';\n\tlet canonicalHeaders = '';\n\tfor(let i = 0; i < arrheadKey.length; i++){\n\t\tif(i !== 0){\n\t\t\tsignedHeaders += ';';\n\t\t}\n\t\tsignedHeaders += arrheadKey[i];\n\t\tcanonicalHeaders += arrheadKey[i] + ':' + arrhead[arrheadKey[i]] + '\\n';\n\t}\n\treturn [signedHeaders, canonicalHeaders];\n}\n\nfunction createV4Signature(shortDate, sk, region, stringToSign){\n\tlet dateKey = crypto.createHmac('sha256', 'AWS4' + sk).update(shortDate).digest();\n\tlet dateRegionKey = crypto.createHmac('sha256', dateKey).update(region).digest();\n\tlet dateRegionServiceKey = crypto.createHmac('sha256', dateRegionKey).update('s3').digest();\n\tlet signingKey = crypto.createHmac('sha256', dateRegionServiceKey).update('aws4_request').digest();\n\tlet signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest('hex');\n\treturn signature;\n}\n\nfunction getV4Signature(shortDate,longDate, sk, region, canonicalRequest){\n\tlet scop = shortDate + '/' + region + '/s3/aws4_request';\n\tlet stringToSign = 'AWS4-HMAC-SHA256\\n';\n\tstringToSign += longDate + '\\n';\n\tstringToSign += scop + '\\n';\n\tstringToSign += crypto.createHash('sha256').update(canonicalRequest).digest('hex');\n\treturn createV4Signature(shortDate, sk, region, stringToSign);\n}\n\nfunction Utils(log_in) {\n\tthis.log = log_in;\n\tthis.ak = null;\n\tthis.sk = null;\n\tthis.securityToken = null;\n\tthis.isSecure = true;\n\tthis.server = null;\n\tthis.pathStyle = false;\n\tthis.signatureContext = null;\n\tthis.isSignatureNegotiation = true;\n\tthis.bucketSignatureCache = {};\n\tthis.region = 'region';\n\tthis.port = null;\n\tthis.timeout = 300;\n\tthis.obsSdkVersion = OBS_SDK_VERSION;\n\tthis.isCname = false;\n\tthis.bucketEventEmitters = {};\n\tthis.useRawXhr = false;\n}\n\nUtils.prototype.encodeURIWithSafe = encodeURIWithSafe;\n\nUtils.prototype.mimeTypes = mimeTypes;\n\nUtils.prototype.refresh = function(ak, sk, securityToken){\n\tthis.ak = ak ? String(ak).trim() : null;\n\tthis.sk = sk ? String(sk).trim(): null;\n\tthis.securityToken = securityToken ? String(securityToken).trim() : null;\n};\n\nUtils.prototype.initFactory = function(ak, sk, isSecure,\n\t\tserver, pathStyle, signature, region, port, timeout, securityToken, isSignatureNegotiation,\n\t\tisCname, urlPrefix, regionDomains, setRequestHeaderHook, useRawXhr, checksumAlgorithm){\n\n\tthis.refresh(ak, sk, securityToken);\n\n this.urlPrefix = urlPrefix || '';\n this.regionDomains = regionDomains || null;\n this.setRequestHeaderHook = setRequestHeaderHook || null;\n\tthis.checkAlgorithm = ContentMD5;\n\n\tif (typeof checksumAlgorithm === 'string' && checksumAlgorithm.toLowerCase() === 'sha256') {\n\t\tthis.checkAlgorithm = ContentSHA256;\n\t}\n\t\n\tif (!server) {\n\t\tthrow new Error('Server is not set');\n\t}\n\n\tserver = String(server).trim();\n\n\tif(server.indexOf('https://') === 0){\n\t\tserver = server.slice('https://'.length);\n\t\tisSecure = true;\n\t}else if(server.indexOf('http://') === 0){\n\t\tserver = server.slice('http://'.length);\n\t\tisSecure = false;\n\t}\n\n\tlet index = server.lastIndexOf('/');\n\twhile(index >= 0){\n\t\tserver = server.slice(0, index);\n\t\tindex = server.lastIndexOf('/');\n\t}\n\n\tindex = server.indexOf(':');\n\tif(index >= 0){\n\t\tport = server.slice(index + 1);\n\t\tserver = server.slice(0, index);\n\t}\n\tthis.server = server;\n\n\tif(/^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$/.test(this.server)){\n\t\tpathStyle = true;\n\t}\n\n\tif (isSecure !== undefined) {\n\t\tthis.isSecure = isSecure;\n\t}\n\tif (pathStyle !== undefined) {\n\t\tthis.pathStyle = pathStyle;\n\t}\n\n\tif (signature !== undefined) {\n\t\tsignature = String(signature).trim().toLowerCase();\n\t}else{\n\t\tsignature = 'obs';\n\t}\n\n\tif(isSignatureNegotiation !== undefined){\n\t\tthis.isSignatureNegotiation = isSignatureNegotiation;\n\t}\n\n\tthis.isCname = isCname;\n\n\tif(this.pathStyle || this.isCname){\n\t\tthis.isSignatureNegotiation = false;\n\t\tif(signature === 'obs'){\n\t\t\tsignature = 'v2';\n\t\t}\n\t}\n\n\tthis.signatureContext = signature === 'obs' ? obsSignatureContext : v2SignatureContext;\n\n\tif(region !== undefined){\n\t\tthis.region = String(region);\n\t}\n\n\tthis.port = port ? parseInt(port, 10) : (this.isSecure ? 443 : 80);\n\n\tif(timeout !== undefined){\n\t\tthis.timeout = parseInt(timeout, 10);\n\t}\n\n\tif(useRawXhr !== undefined){\n\t\tthis.useRawXhr = useRawXhr;\n\t}\n};\n\nUtils.prototype.SseKmsAdapter = function(value, signatureContext){\n\tvalue = value || '';\n\tvalue = String(value);\n\tlet index = value.indexOf('aws:');\n\tif(signatureContext.signature === 'obs'){\n\t\treturn index === 0 ? value.slice(4) : value;\n\t}\n\treturn index === 0 ? value : 'aws:' + value;\n};\n\nUtils.prototype.SseModeAdapter = function(value, signatureContext){\n\tvalue = value || '';\n\tvalue = String(value);\n\tlet index = value.indexOf('aws:');\n\tif(signatureContext.signature === 'obs'){\n\t\treturn index === 0 ? value.slice(4) : value;\n\t}\n\treturn index === 0 ? value : 'aws:' + value;\n};\n\nUtils.prototype.BucketAdapter = function(value, signatureContext){\n\tvalue = value || '';\n\tvalue = String(value);\n\tlet index = value.indexOf('arn:aws:s3:::');\n\tif(signatureContext.signature === 'obs'){\n\t\treturn index === 0 ? value.slice('arn:aws:s3:::'.length) : value;\n\t}\n\treturn index === 0 ? value : 'arn:aws:s3:::' + value;\n};\n\nUtils.prototype.EventAdapter = function(value, signatureContext){\n\tvalue = value || '';\n\tvalue = String(value);\n\tif(signatureContext.signature === 'obs'){\n\t\tif(obsAllowedEvent.indexOf(value) >= 0){\n\t\t\treturn value;\n\t\t}\n\t\tif(v2AllowedEvent.indexOf(value) >= 0){\n\t\t\treturn value.substring(3);\n\t\t}\n\t\treturn '';\n\t}\n\tif(v2AllowedEvent.indexOf(value) >= 0){\n\t\treturn value;\n\t}\n\tif(obsAllowedEvent.indexOf(value) >= 0){\n\t\treturn 's3:' + value;\n\t}\n\treturn '';\n};\n\nUtils.prototype.EventsAdapter = function(value, signatureContext){\n\treturn this.EventAdapter(value, signatureContext);\n};\n\n\nUtils.prototype.URIAdapter = function(value, signatureContext){\n\tvalue = value || '';\n\tvalue = String(value);\n\tif(signatureContext.signature === 'obs'){\n\t\tif(obsAllowedUri.indexOf(value) >= 0){\n\t\t\treturn value;\n\t\t}\n\t\tif(value === 'AllUsers' || value === 'http://acs.amazonaws.com/groups/global/AllUsers'){\n\t\t\treturn 'Everyone';\n\t\t}\n\t\treturn '';\n\t}\n\tif(v2AllowedUri.indexOf(value) >= 0){\n\t\treturn value;\n\t}\n\tif(value === 'Everyone' || value === 'AllUsers'){\n\t\treturn 'http://acs.amazonaws.com/groups/global/AllUsers';\n\t}\n\tif(value === 'AuthenticatedUsers'){\n\t\treturn 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers';\n\t}\n\tif(value === 'LogDelivery'){\n\t\treturn 'http://acs.amazonaws.com/groups/s3/LogDelivery';\n\t}\n\treturn '';\n};\n\n\nUtils.prototype.StorageClassAdapter = function(value, signatureContext){\n\tvalue = value || '';\n\tvalue = String(value).toUpperCase();\n\tif(signatureContext.signature === 'obs'){\n\t\tif(obsAllowedStorageClass.indexOf(value) >= 0){\n\t\t\treturn value;\n\t\t}\n\t\tif(value === 'STANDARD_IA'){\n\t\t\treturn 'WARM';\n\t\t}\n\t\tif(value === 'GLACIER'){\n\t\t\treturn 'COLD';\n\t\t}\n\t\treturn '';\n\t}\n\tif(v2AllowedStorageClass.indexOf(value) >= 0){\n\t\treturn value;\n\t}\n\tif(value === 'WARM'){\n\t\treturn 'STANDARD_IA';\n\t}\n\tif(value === 'COLD'){\n\t\treturn 'GLACIER';\n\t}\n\treturn '';\n};\n\nUtils.prototype.ACLAdapter = function(value, signatureContext){\n\tvalue = value || '';\n\tvalue = String(value).toLowerCase();\n\tif(signatureContext.signature === 'obs'){\n\t\tif(obsAllowedAcl.indexOf(value) >= 0){\n\t\t\treturn value;\n\t\t}\n\t\treturn '';\n\t}\n\tif(value === 'public-read-delivered'){\n\t\tvalue = 'public-read';\n\t}else if(value === 'public-read-write-delivered'){\n\t\tvalue = 'public-read-write';\n\t}\n\n\tif(v2AllowedAcl.indexOf(value) >= 0){\n\t\treturn value;\n\t}\n\treturn '';\n};\n\nUtils.prototype.doExec = function(funcName, param, callback){\n\tlet opt = this.makeParam(funcName, param);\n\tif('err' in opt){\n\t\treturn callback(opt.err, null);\n\t}\n\tthis.sendRequest(funcName, opt, callback);\n};\n\nUtils.prototype.doNegotiation = function(funcName, param, callback, checkBucket, checkCache, setCache){\n\tlet o = null;\n\tlet that = this;\n\tif(checkCache && param.Bucket){\n\t\tlet item = this.bucketSignatureCache[param.Bucket];\n\t\tif(item && item.signatureContext && item.expireTime > new Date().getTime()){\n\t\t\tparam.signatureContext = item.signatureContext;\n\t\t\tlet opt = this.makeParam(funcName, param);\n\t\t\tif('err' in opt){\n\t\t\t\treturn callback(opt.err, null);\n\t\t\t}\n\t\t\topt.signatureContext = item.signatureContext;\n\t\t\treturn this.sendRequest(funcName, opt, callback);\n\t\t}\n\n\t\to = this.bucketEventEmitters[param.Bucket];\n\t\tif(!o){\n\t\t\to = {\n\t\t\t\ts : 0,\n\t\t\t\tn : function(){\n\t\t\t\t\twhile(this.e && this.e.length > 0){\n\t\t\t\t\t\tthis.e.shift()();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.bucketEventEmitters[param.Bucket] = o;\n\t\t}\n\n\t\tif(o.s){\n\t\t\to.e.push(function(){\n\t\t\t\tthat.doNegotiation(funcName, param, callback, checkBucket, checkCache, setCache);\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\to.e = [];\n\t\to.s = 1;\n\t}\n\n\tthis.doExec(negotiateMethod, checkBucket ? {Bucket:param.Bucket, hasRegion: param.hasRegion} : {}, function(err, result){\n\t\tif(err){\n\t\t\tcallback(err, null);\n\t\t\tif(o){\n\t\t\t\to.s = 0;\n\t\t\t\to.n();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif((checkBucket && result.CommonMsg.Status === 404) || result.CommonMsg.Status >= 500){\n\t\t\tcallback(err, result);\n\t\t\tif(o){\n\t\t\t\to.s = 0;\n\t\t\t\to.n();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tlet signatureContext = v2SignatureContext;\n\t\tif(result.CommonMsg.Status < 300 && result.InterfaceResult && result.InterfaceResult.ApiVersion >= '3.0'){\n\t\t\tsignatureContext = obsSignatureContext;\n\t\t}\n\t\tif(setCache){\n\t\t\tthat.bucketSignatureCache[param.Bucket] = {\n\t\t\t\tsignatureContext : signatureContext,\n\t\t\t\texpireTime : new Date().getTime() + 15 + (Math.ceil(Math.random()*5)) * 60 * 1000\n\t\t\t};\n\t\t}\n\n\t\tif(o){\n\t\t\to.s = 0;\n\t\t\to.n();\n\t\t}\n\t\tparam.signatureContext = signatureContext;\n\t\tlet opt = that.makeParam(funcName, param);\n\t\tif('err' in opt){\n\t\t\treturn callback(opt.err, null);\n\t\t}\n\t\topt.signatureContext = signatureContext;\n\t\tthat.sendRequest(funcName, opt, callback);\n\t});\n};\n\nUtils.prototype.exec = function(funcName, param, callback){\n\tlet that = this;\n\tif(that.isSignatureNegotiation && funcName !== negotiateMethod){\n\t\tif (funcName === 'ListBuckets') {\n\t\t\tthat.doNegotiation(funcName, param, callback, false, false, false);\n\t\t} else if (ignoreNegotiationMethod.indexOf(funcName) > -1) {\n\t\t\tlet _callback = function(err, result){\n\t\t\t\tif(!err && result.CommonMsg.Status === 400 &&\n\t\t\t\t\t\tresult.CommonMsg.Message === 'Unsupported Authorization Type' &&\n\t\t\t\t\t\tparam.signatureContext &&\n\t\t\t\t\t\tparam.signatureContext.signature === 'v2'){\n\t\t\t\t\tparam.signatureContext = v2SignatureContext;\n\t\t\t\t\tlet opt = that.makeParam(funcName, param);\n\t\t\t\t\tif('err' in opt){\n\t\t\t\t\t\treturn callback(opt.err, null);\n\t\t\t\t\t}\n\t\t\t\t\topt.signatureContext = param.signatureContext;\n\t\t\t\t\tthat.sendRequest(funcName, opt, callback);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcallback(err, result);\n\t\t\t};\n\n\t\t\tthat.doNegotiation(funcName, param, _callback, false, true, false);\n\t\t}else{\n\t\t\tthat.doNegotiation(funcName, param, callback, true, true, true);\n\t\t}\n\t\treturn;\n\t}\n\tthat.doExec(funcName, param, callback);\n};\n\n\nUtils.prototype.sliceBlob = function (blob, start, end, type) {\n type = type || blob.type;\n if (blob.mozSlice) {\n return blob.mozSlice(start, end, type);\n }\n if (blob.webkitSlice) {\n return blob.webkitSlice(start, end, type);\n }\n return blob.slice(start, end, type);\n};\n\n\nUtils.prototype.toXml = function(mXml, xmlMeta, root, sentAs, signatureContext){\n\tlet xml = '';\n\tif(root !== null){\n\t\txml += this.buildXml(mXml, xmlMeta, root, sentAs, signatureContext);\n\t\treturn xml;\n\t}\n\tfor (let key in xmlMeta){\n\t\tif(key in mXml){\n\t\t\tlet _sentAs = xmlMeta[key].sentAs || key;\n\t\t\txml += this.buildXml(mXml, xmlMeta[key], key, _sentAs, signatureContext);\n\t\t}\n\t}\n\treturn xml;\n};\n\nUtils.prototype.buildXml = function(mXml, xmlMeta, key, sentAs, signatureContext){\n\tlet xml = '';\n\tlet type = xmlMeta.type;\n\tif(type === 'array'){\n\t\tfor(let i = 0; i < mXml[key].length; i++){\n\t\t\tif(xmlMeta.items.type === 'object'){\n\t\t\t\tif (!mXml[key][i]) {\n\t\t\t\t\treturn xml;\n\t\t\t\t}\n\t\t\t\tlet result = this.toXml(mXml[key][i], xmlMeta.items.parameters, null, null, signatureContext);\n\t\t\t\tif(result !== ''){\n\t\t\t\t\txml += '<'+sentAs +'>'+ result + '';\n\t\t\t\t}\n\t\t\t}else if(xmlMeta.items.type === 'adapter'){\n\t\t\t\txml += '<' + sentAs + '>' + String(this[key + 'Adapter'](mXml[key][i], signatureContext)).replace(/&/g, '&').replace(/'/g, ''').replace(/\"/g, '"') + '';\n\t\t\t}else if(xmlMeta.items.type !== 'array'){\n\t\t\t\txml += '<' + sentAs + '>'+ String(mXml[key][i]).replace(/&/g, '&').replace(/'/g, ''').replace(/\"/g, '"') + '';\n\t\t\t}\n\t\t}\n\t}else if(type === 'object'){\n\t\tif (!mXml[key]) {\n\t\t\treturn xml;\n\t\t}\n\t\tlet result = this.toXml(mXml[key], xmlMeta.parameters, null, null, signatureContext);\n\t\tif(result !== ''){\n\t\t\txml += '<'+sentAs;\n\t\t\tif('data' in xmlMeta){\n\t\t\t\tif('xsiNamespace' in xmlMeta.data){\n\t\t\t\t\txml += ' xmlns:xsi=\"' + xmlMeta.data.xsiNamespace + '\"';\n\t\t\t\t}\n\t\t\t\tif('xsiType' in xmlMeta.data){\n\t\t\t\t\txml += ' xsi:type=\"' + mXml[key][xmlMeta.data.xsiType] + '\"';\n\t\t\t\t}\n\t\t\t}\n\t\t\txml += '>';\n\t\t\txml += result + '';\n\t\t}\n\n\t}else if(type === 'adapter'){\n\t\txml += '<' + sentAs + '>' + String(this[key + 'Adapter'](mXml[key], signatureContext)).replace(/&/g, '&').replace(/'/g, ''').replace(/\"/g, '"') + '';\n\t}else if(type !== 'ignore'){\n\t\txml += '<'+ sentAs + '>' + String(mXml[key]).replace(/&/g, '&').replace(/'/g, ''').replace(/\"/g, '"') + '';\n\t}\n\tif(xml && xmlMeta.wrapper){\n\t\tlet _wrapper = xmlMeta.wrapper;\n\t\txml = '<' + _wrapper + '>' + xml + '';\n\t}\n\treturn xml;\n};\n\nUtils.prototype.jsonToObject = function(model, obj, root, ifRootXMlDecode){\n\tlet opt = {};\n\tif(root !== null){\n\t\tthis.buildObject(model, obj, root, opt, ifRootXMlDecode);\n\t}else{\n\t\tfor(let key in model){\n\t\t\tif ({}.hasOwnProperty.call(model, key)) {\n\t\t\t\tthis.buildObject(model, obj, key, opt, ifRootXMlDecode);\n\t\t\t}\n\t\t}\n\t}\n\treturn opt;\n};\n\nUtils.prototype.buildObject = function(model, obj, key, opt, ifRootXMlDecode){\n\n\tlet setValue = function (value) {\n\t\tif(value === undefined) {\n\t\t\treturn \"\";\n\t\t}\n\t\treturn value && model[key].decode && ifRootXMlDecode\n\t\t? decodeURIComponent(value.replace(/\\+/g, '%20'))\n\t\t: value;\n\t}\n\n\tif(isObject(obj)){\n\t\tlet flag = true;\n\t\tlet wrapper = model[key].wrapper;\n\t\tif(wrapper && wrapper in obj){\n\t\t\tobj = obj[wrapper];\n\t\t\tflag = isObject(obj);\n\t\t}\n\t\tif(flag){\n\t\t\tlet sentAs = model[key].sentAs || key;\n\t\t\tif(sentAs in obj){\n\t\t\t\tif(model[key].type === 'object'){\n\t\t\t\t\topt[key] = this.jsonToObject(model[key].parameters, obj[sentAs], null, ifRootXMlDecode);\n\t\t\t\t}else if(model[key].type === 'array'){\n\t\t\t\t\tlet arr = [];\n\t\t\t\t\tif(!isArray(obj[sentAs])){\n\t\t\t\t\t\tarr[0] = model[key].items.type === 'object' ? this.jsonToObject(model[key].items.parameters, obj[sentAs], null, ifRootXMlDecode) : setValue(obj[sentAs]['#text'] || '');\n\t\t\t\t\t}else{\n\t\t\t\t\t\tfor (let i = 0; i < obj[sentAs].length; i++ ){\n\t\t\t\t\t\t\tarr[i] = model[key].items.type === 'object' ? this.jsonToObject(model[key].items.parameters, obj[sentAs][i], null, ifRootXMlDecode) : setValue(obj[sentAs][i]['#text']);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\topt[key] = arr;\n\t\t\t\t}else{\n\t\t\t\t\topt[key] = setValue(obj[sentAs]['#text']);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif(opt[key] === undefined){\n\t\tif(model[key].type === 'object'){\n\t\t\topt[key] = model[key].parameters ? this.jsonToObject(model[key].parameters,null,null,ifRootXMlDecode) : {};\n\t\t}else if(model[key].type === 'array'){\n\t\t\topt[key] = [];\n\t\t}\n\t}\n\n};\n\nUtils.prototype.makeParam = function(methodName, param){\n\tlet signatureContext = param.signatureContext || this.signatureContext;\n\tlet model = signatureContext.signature === 'obs' ? obsModel[methodName] : v2Model[methodName];\n\tlet method = model.httpMethod;\n\tlet uri = '/';\n\tlet urlPath = '';\n\tlet xml = '';\n\tlet exheaders = {};\n\tlet opt = {};\n\topt.$requestParam = param;\n\n\tif ('urlPath' in model){\n\t\turlPath += '?';\n\t\turlPath += model.urlPath;\n\t}\n\tfor (let key in model.parameters){\n\t\tif ({}.hasOwnProperty.call(model.parameters, key)) {\n\t\t\tlet meta = model.parameters[key];\n\t\t\tif (key === 'Bucket' && this.isCname) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet _value = param[key];\n\n\t\t\tif (meta.type === 'callback' && _value === undefined && meta.parameters && (param['CallbackUrl'] !== undefined || param['CallbackBody'] !== undefined)) {\n\t\t\t\t_value = {};\n\t\t\t\tfor (let _key of Object.keys(meta.parameters)) {\n\t\t\t\t\tconst _meta = meta.parameters[_key];\n\t\t\t\t\tconst _keyValue = param[_key];\n\t\t\t\t\tif (_meta.required && (_keyValue === null || _keyValue === undefined || (Object.prototype.toString.call(_keyValue) === '[object String]' && _keyValue === ''))) {\n\t\t\t\t\t\topt.err = _key + ' is a required element!';\n\t\t\t\t\t\tthis.log.runLog('error', methodName, opt.err);\n\t\t\t\t\t\treturn opt;\n\t\t\t\t\t}\n\t\t\t\t\tconst newKey = _key.slice(0, 1).toLowerCase() + _key.slice(1); \n\t\t\t\t\t_value[newKey] = _keyValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (meta.required && (_value === null || _value === undefined || (Object.prototype.toString.call(_value) === '[object String]' && _value === ''))) {\n\t\t\t\topt.err = key + ' is a required element!';\n\t\t\t\tthis.log.runLog('error', methodName, opt.err);\n\t\t\t\treturn opt;\n\t\t\t}\n\n\t\t\tif (_value !== null && _value !== undefined) {\n\t\t\t\tif (meta.type === 'srcFile' || meta.type === 'dstFile') {\n\t\t\t\t\topt[meta.type] = _value;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (meta.type === 'plain') {\n\t\t\t\t\topt[key] = _value;\n\t\t\t\t}\n\n\t\t\t\tlet sentAs = meta.sentAs || key;\n\n\t\t\t\tif (meta.withPrefix) {\n\t\t\t\t\tsentAs = signatureContext.headerPrefix + sentAs;\n\t\t\t\t}\n\n\t\t\t\tif (meta.location === 'uri') {\n\t\t\t\t\tif (uri !== '/') {\n\t\t\t\t\t\turi += '/';\n\t\t\t\t\t}\n\t\t\t\t\turi += _value;\n\t\t\t\t} else if (meta.location === 'header') {\n\t\t\t\t\tlet safe = meta.encodingSafe || ' ;/?:@&=+$,';\n\t\t\t\t\tif (meta.type === 'object') {\n\t\t\t\t\t\tif (signatureContext.headerMetaPrefix === sentAs) {\n\t\t\t\t\t\t\tfor (let item in _value) {\n\t\t\t\t\t\t\t\tif ({}.hasOwnProperty.call(_value, item)) {\n\t\t\t\t\t\t\t\t\tlet value = _value[item];\n\t\t\t\t\t\t\t\t\titem = String(item).trim().toLowerCase();\n\t\t\t\t\t\t\t\t\texheaders[item.indexOf(sentAs) === 0 ? item : sentAs + item] = encodeURIWithSafe(value, safe);\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} else if (meta.type === 'array') {\n\t\t\t\t\t\tlet arr = [];\n\t\t\t\t\t\tfor (let item in _value) {\n\t\t\t\t\t\t\tif ({}.hasOwnProperty.call(_value, item)) {\n\t\t\t\t\t\t\t\tarr[item] = encodeURIWithSafe(_value[item], safe);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\texheaders[sentAs] = arr;\n\t\t\t\t\t} else if (meta.type === 'password') {\n\t\t\t\t\t\tlet encodeFunc = window.btoa ? window.btoa : Base64.encode;\n\t\t\t\t\t\texheaders[sentAs] = encodeFunc(_value);\n\t\t\t\t\t\tlet pwdSentAs = meta.pwdSentAs || (sentAs + '-MD5');\n\t\t\t\t\t\texheaders[pwdSentAs] = this.rawBufMD5(_value);\n\t\t\t\t\t} else if (meta.type === 'number' && Number(_value)) {\n\t\t\t\t\t\texheaders[sentAs] = encodeURIWithSafe(String(_value), safe);\n\t\t\t\t\t} else if (meta.type === 'boolean') {\n\t\t\t\t\t\texheaders[sentAs] = encodeURIWithSafe(_value ? 'true' : 'false', safe);\n\t\t\t\t\t} else if (meta.type === 'callback') {\n\t\t\t\t\t\texheaders[sentAs] = Base64.encode(JSON.stringify(_value))\n\t\t\t\t\t} else if (meta.type === 'adapter') {\n\t\t\t\t\t\tlet val = this[key + 'Adapter'](_value, signatureContext);\n\t\t\t\t\t\tif (val) {\n\t\t\t\t\t\t\texheaders[sentAs] = encodeURIWithSafe(String(val), safe);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\texheaders[sentAs] = encodeURIWithSafe(String(_value), safe, meta.skipEncoding);\n\t\t\t\t\t}\n\t\t\t\t} else if (meta.location === 'urlPath') {\n\t\t\t\t\tlet sep = urlPath === '' ? '?' : '&';\n\t\t\t\t\tlet value = _value;\n\t\t\t\t\tif (meta.type !== 'number' || (meta.type === 'number' && Number(value) >= 0)) {\n\t\t\t\t\t\turlPath += sep + encodeURIWithSafe(sentAs, '/') + '=' + encodeURIWithSafe(String(value), '/');\n\t\t\t\t\t}\n\t\t\t\t} else if (meta.location === 'xml') {\n\t\t\t\t\tlet mxml = this.toXml(param, meta, key, sentAs, signatureContext);\n\t\t\t\t\tif (mxml) {\n\t\t\t\t\t\txml += mxml;\n\t\t\t\t\t}\n\t\t\t\t} else if (meta['location'] === 'body') {\n\t\t\t\t\txml = _value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tlet isFile = opt.dstFile === 'file';\n\n\tif(!('Content-Type' in exheaders) && !isFile){\n\t\texheaders['Content-Type'] = 'binary/octet-stream';\n\t}\n\n\tif('data' in model && 'xmlRoot' in model.data){\n\t\tif(xml || model.data.xmlAllowEmpty){\n\t\t\tlet xmlRoot = model.data.xmlRoot;\n\t\t\txml = '<' + xmlRoot + '>' + xml + '';\n\t\t\texheaders['Content-Type'] = 'application/xml';\n\t\t}\n\t}\n\tif(isFile){\n\t\topt.rawUri = uri;\n\t}\n\n\texheaders.Host = this.server + ((this.port === 80 || this.port === 443) ? '' : ':' + this.port);\n\n\tif(!this.pathStyle && !this.isCname){\n\t\tlet uriList = uri.split('/');\n\t\tif(uriList.length >= 2 && uriList[1]){\n\t\t\texheaders.Host = uriList[1] + '.' + exheaders.Host;\n\t\t\tlet requestUri = uri.replace(uriList[1], '');\n\t\t\tif(requestUri.indexOf('//') === 0){\n\t\t\t\trequestUri = requestUri.slice(1);\n\t\t\t}\n\t\t\tif(signatureContext.signature === 'v4'){\n\t\t\t\turi = requestUri;\n\t\t\t}else if(requestUri === '/'){\n\t\t\t\turi += '/';\n\t\t\t}\n\t\t\topt.requestUri = encodeURIWithSafe(requestUri, '/');\n\t\t}\n\t}\n\topt.method = method;\n\topt.uri = encodeURIWithSafe(uri, '/');\n\topt.urlPath = urlPath;\n\tif(xml){\n\t\tif(model.data && model.data.md5){\n\t\t\tthis.checkAlgorithm === ContentSHA256 \n\t\t\t\t? exheaders[`${signatureContext.headerPrefix}${ContentSHA256.toLowerCase()}`] = this.bufSHA256(xml, 'hex')\n\t\t\t\t: exheaders[ContentMD5] = this.bufMD5(xml);\n\t\t\texheaders['Content-Length'] = xml.length === 0 ? '0' : String(xml.length);\n\t\t}\n\t\topt.xml = xml;\n\t\tthis.log.runLog('debug', methodName, 'request content:' + xml);\n\t}\n\n\topt.headers = exheaders;\n\n\tif('srcFile' in opt){\n\t\tif((opt.srcFile instanceof window.File) || (opt.srcFile instanceof window.Blob)){\n\t\t\tlet fileSize = opt.srcFile.size;\n\t\t\tif ('Content-Length' in opt.headers || 'PartSize' in opt || 'Offset' in opt) {\n\t\t\t\tlet offset = opt.Offset;\n\t\t\t\toffset = (offset && offset >= 0 && offset < fileSize) ? offset : 0;\n\t\t\t\tlet partSize;\n\t\t\t\tif('PartSize' in opt){\n\t\t\t\t\tpartSize = opt.PartSize;\n\t\t\t\t}else if('Content-Length' in opt.headers){\n\t\t\t\t\tpartSize = parseInt(opt.headers['Content-Length'], 10);\n\t\t\t\t}else{\n\t\t\t\t\tpartSize = fileSize;\n\t\t\t\t}\n\t\t\t\tpartSize = (partSize && partSize > 0 && partSize <= fileSize - offset) ? partSize : fileSize - offset;\n\t\t\t\topt.PartSize = partSize;\n\t\t\t\topt.Offset = offset;\n\t\t\t\topt.headers['Content-Length'] = String(opt.PartSize);\n\t\t\t}\n\t\t}\n\t}\n\treturn opt;\n};\n\nUtils.prototype.parseCommonHeaders = function(opt, headers, signatureContext){\n\tfor(let key in commonHeaders){\n\t\tif ({}.hasOwnProperty.call(commonHeaders, key)) {\n\t\t\topt.InterfaceResult[commonHeaders[key]] = headers[key];\n\t\t}\n\t}\n\topt.InterfaceResult.RequestId = headers[signatureContext.headerPrefix + 'request-id'];\n\topt.InterfaceResult.Id2 = headers[signatureContext.headerPrefix + 'id-2'];\n\topt.CommonMsg.RequestId = opt.InterfaceResult.RequestId;\n\topt.CommonMsg.Id2 = opt.InterfaceResult.Id2;\n};\n\nUtils.prototype.contrustCommonMsg = function(opt, obj, headers, signatureContext){\n\topt.InterfaceResult = {};\n\tthis.parseCommonHeaders(opt, headers, signatureContext);\n\tfor (let key in obj){\n\t\tif(obj[key].location !== 'header'){\n\t\t\tcontinue;\n\t\t}\n\t\tlet sentAs = obj[key].sentAs || key;\n\n\t\tif(obj[key].withPrefix){\n\t\t\tsentAs = signatureContext.headerPrefix + sentAs;\n\t\t}\n\n\t\tif(obj[key].type === 'object'){\n\t\t\topt.InterfaceResult[key] = parseObjectFromHeaders(sentAs, headers);\n\t\t}else{\n\t\t\tlet val = null;\n\t\t\tif(sentAs in headers){\n\t\t\t\tval = headers[sentAs];\n\t\t\t}else if(sentAs.toLowerCase() in headers){\n\t\t\t\tval = headers[sentAs.toLowerCase()];\n\t\t\t}\n\t\t\tif(val !== null){\n\t\t\t\topt.InterfaceResult[key] = val;\n\t\t\t}\n\t\t}\n\t}\n};\n\n\nUtils.prototype.getRequest = function(methodName, serverback, signatureContext, retryCount, params, bc){\n let regionDomains = this.regionDomains;\n\tlet opt = {};\n\tlet log = this.log;\n\tlet model = signatureContext.signature === 'obs' ? obsModel[methodName + 'Output'] : v2Model[methodName + 'Output'];\n\tmodel = model || {};\n\tlet obj = model.parameters || {};\n\topt.CommonMsg = {\n\t\tStatus : serverback.status,\n\t\tCode : '',\n\t\tMessage : '',\n\t\tHostId : '',\n\t\tRequestId : '',\n\t\tInterfaceResult : null\n\t};\n\n\tlet headers = serverback.headers;\n\tlet headersStr = headerTostring(headers);\n\n\tlog.runLog('info', methodName, 'get response start, statusCode:' + serverback.status);\n\tlog.runLog('debug', methodName, 'response msg :statusCode:' + serverback.status + ', headers:' + headersStr);\n\n\tlet doLog = function(){\n\t\tlet logMsg = 'Status:' + opt.CommonMsg.Status + ', Code:' + opt.CommonMsg.Code + ', Message:' + opt.CommonMsg.Message;\n\t\tlog.runLog('debug', methodName, 'exec interface ' + methodName + ' finish, ' + logMsg);\n\t\tbc(null, opt);\n\t};\n\n\tif(serverback.status >= 300 && serverback.status < 400 && serverback.status !== 304 && retryCount <= 5){\n let location = headers.location || headers.Location;\n\t\tif(location){\n\t\t\tlet err = 'http code is 3xx, need to redirect to ' + location;\n\t\t\tlog.runLog('warn', methodName, err);\n\t\t\tlet redirectErr = new Error('redirect');\n\t\t\tredirectErr.location = location;\n\t\t\tredirectErr.bucketLocation = headers['x-amz-bucket-region'] || headers['x-obs-bucket-region'];\n\t\t\treturn bc(redirectErr);\n\t\t}\n\t\tlet bucketLocation = headers['x-amz-bucket-region'] || headers['x-obs-bucket-location'];\n\t\tif (bucketLocation && regionDomains[bucketLocation]) {\n let regionServer = (this.isSecure ? 'https://' : 'http://') + regionDomains[bucketLocation];\n\t\t\tif (isFunction(this.setRequestHeaderHook)) {\n\t\t\t\tthis.setRequestHeaderHook(headers, params, methodName, regionDomains[bucketLocation]);\n\t\t\t}\n let err = 'get redirect code 3xx, need to redirect to' + regionServer;\n log.runLog('error', methodName, err);\n let redirectErr = new Error('redirect');\n\t\t\tredirectErr.location = regionServer;\n return bc(redirectErr);\n }\n\t\tlog.runLog('error', methodName, 'get redirect code 3xx, but no location in headers');\n\t}\n\n\tif(serverback.status < 300){\n\t\tlet body = serverback.data;\n\t\tthis.contrustCommonMsg(opt, obj, headers, signatureContext);\n\t\tlet respMsg = 'Status: ' + opt.CommonMsg.Status + ', headers: ' + headersStr;\n\t\tif(body){\n\t\t\trespMsg += 'body length: ' + body.length;\n\t\t\tlog.runLog('debug', methodName, 'response body length:' + body.length);\n\t\t}\n\t\tlog.runLog('debug', methodName, respMsg);\n\n\t\tif(body && ('data' in model)){\n\t\t\tif (params.CallbackUrl && model.CallbackResponse) {\n\t\t\t\topt.InterfaceResult[model.CallbackResponse.sentAs] = body;\n\t\t\t\tdoLog();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif(model.data.type === 'xml'){\n\t\t\t\tlet that = this;\n\t\t\t\treturn makeObjFromXml(body, function(err, result){\n\t\t\t\t\tif(err){\n\t\t\t\t\t\tlog.runLog('error', methodName, 'change xml to json err [' + headerTostring(err) + ']' );\n\t\t\t\t\t\treturn bc(err, null);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet tempResult = result;\n\t\t\t\t\tif(model.data.xmlRoot && (model.data.xmlRoot in tempResult)){\n\t\t\t\t\t\ttempResult = result[model.data.xmlRoot];\n\t\t\t\t\t}\n\t\t\t\t\tlet ifRootXMlDecode = tempResult.EncodingType ? true : false;\n\t\t\t\t\tif(isObject(tempResult)){\n\t\t\t\t\t\tfor (let key in obj){\n\t\t\t\t\t\t\tif(obj[key].location === 'xml'){\n\t\t\t\t\t\t\t\topt.InterfaceResult[key] = that.jsonToObject(obj,tempResult,key,ifRootXMlDecode)[key];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tdoLog();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif(model.data.type === 'body'){\n\t\t\t\tfor (let key in obj){\n\t\t\t\t\tif(obj[key].location === 'body'){\n\t\t\t\t\t\topt.InterfaceResult[key] = body;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn doLog();\n\t}\n\n\tlet body = serverback.data;\n\tlet respMsg = 'Status: ' + opt.CommonMsg.Status + ', headers: ' + headersStr;\n\tif(body !== ''){\n\t\trespMsg += 'body: ' + body;\n\t\tlog.runLog('debug', methodName, 'response body :' + body);\n\t}\n\topt.CommonMsg.RequestId = headers[signatureContext.headerPrefix + 'request-id'];\n\topt.CommonMsg.Id2 = headers[signatureContext.headerPrefix + 'id2'];\n\topt.CommonMsg.Indicator = headers['x-reserved-indicator'];\n\n\tlog.runLog('info', methodName, 'request finished with request id:' + opt.CommonMsg.RequestId);\n\tlog.runLog('debug', methodName, respMsg);\n\n\tif(!body){\n\t\treturn doLog();\n\t}\n\n\treturn makeObjFromXml(body, function(err, re){\n\t\tif(err){\n\t\t\tlog.runLog('error', methodName, 'change xml to json err [' + headerTostring(err) + ']' );\n\t\t\topt.CommonMsg.Message = err.message;\n\t\t}else if(re){\n\t\t\tif ('Error' in re) {\n\t\t\t\tlet errMsg = re.Error;\n\t\t\t\tfor(let param in errMsg) {\n\t\t\t\t\tif (errMsg[param] && errMsg[param]['#text']) {\n\t\t\t\t\t\topt.CommonMsg[param] = errMsg[param]['#text'];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlet errMsg = re;\n\t\t\t\tif('code' in errMsg){\n\t\t\t\t\topt.CommonMsg.Code = errMsg.code;\n\t\t\t\t}\n\t\t\t\tif('message' in errMsg){\n\t\t\t\t\topt.CommonMsg.Message = errMsg.message;\n\t\t\t\t}\n\t\t\t\tif('hostId' in errMsg){\n\t\t\t\t\topt.CommonMsg.HostId = errMsg.hostId;\n\t\t\t\t}\n\t\t\t\tif(('request_id' in errMsg) && errMsg.request_id){\n\t\t\t\t\topt.CommonMsg.RequestId = errMsg.request_id;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlog.runLog('error', methodName, 'request error with error code:' + opt.CommonMsg.Code + ', error message:' + opt.CommonMsg.Message + ', request id:' + opt.CommonMsg.RequestId);\n\t\t}\n\t\tdoLog();\n\t});\n};\n\nUtils.prototype.makeRequest = function(methodName, opt, retryCount, bc){\n\tlet log = this.log;\n\tlet body = opt.xml || null;\n\tlet signatureContext = opt.signatureContext || this.signatureContext;\n\tdelete opt.headers.Authorization; // retry bug fix\n\n\tif(opt.dstFile === 'file'){\n\t\tlet queryParams = {};\n\t\tif(opt.urlPath){\n\t\t\tlet path = opt.urlPath.slice(1);\n\t\t\tlet arrPath = path.split('&');\n\t\t\tfor(let i=0;i=0 ) {\n\t\t\tportInfo = '';\n\t\t}\n\t\t// 适配cf2,在请求中增加通配符\n\t\tlet baseUrl='';\n\t\tlet httpPrefix = _isSecure ? 'https://' : 'http://';\n\t\tif (this.urlPrefix && isFunction(this.setRequestHeaderHook) && methodName !== 'UploadPart') {\n\t\t\tlet defaultRegion = true;\n\t\t\tif(opt.$requestParam['hasRegion']||opt.$requestParam['redirectRegion']){\n\t\t\t\tdefaultRegion = false;\n\t\t\t}\n\n\t\t\tlet portFlag='';\n\t\t\tif(port === 5443){\n\t\t\t\tportFlag='-5443';\n\t\t\t}\n\n\t\t\tif (defaultRegion) {\n\t\t\t\tif (opt.$requestParam['Bucket']) {\n\t\t\t\t\tif(opt.$requestParam['Bucket'].indexOf('.') !== -1){\n\t\t\t\t\t\tbaseUrl = httpPrefix + this.urlPrefix + '/bucket'+ portFlag;\n\t\t\t\t\t}\n\t\t\t\t\tbaseUrl = httpPrefix + this.urlPrefix + '/bucket'+ portFlag;\n\t\t\t\t} else {\n\t\t\t\t\tif (path.split('?')[0] === '/') {\n\t\t\t\t\t\tbaseUrl = httpPrefix + this.urlPrefix + portFlag;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbaseUrl = httpPrefix + this.urlPrefix + '/place' + portFlag;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (opt.$requestParam['Bucket']) {\n\t\t\t\t\tbaseUrl = httpPrefix + this.urlPrefix + '/region-bucket'+ portFlag;\n\t\t\t\t} else {\n\t\t\t\t\tbaseUrl = httpPrefix + this.urlPrefix + '/region'+ portFlag;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tbaseUrl = httpPrefix + host + portInfo;\n\t\t}\n\n\t\tlet reopt = {\n\t\t\tmethod : method,\n\t\t\t// fix bug, axios will abandon the base url if the request url starts with '//', so use the completed url to avoid it\n\t\t\turl : baseUrl + path,\n\t\t\twithCredentials: false,\n\t\t\theaders : ex,\n\t\t\tvalidateStatus: function(status){\n\t\t\t\treturn status >= 200;\n\t\t\t},\n\t\t\tmaxRedirects : 0,\n\t\t\tresponseType : responseType,\n\t\t\tdata : body,\n\t\t\ttimeout : this.timeout * 1000,\n\t\t\tonUploadProgress : onUploadProgress,\n\t\t\tonDownloadProgress : onDownloadProgress,\n\t\t\tcancelToken : new axios.CancelToken(function(cancelHook){\n\t\t\t\topt.$requestParam.cancelHook = cancelHook;\n\t\t\t})\n\t\t};\n\t\tif(opt.srcFile){\n\t\t\tif(!(opt.srcFile instanceof window.File) && !(opt.srcFile instanceof window.Blob)){\n\t\t\t\treturn bc(new Error('source file must be an instance of window.File or window.Blob'), null);\n\t\t\t}\n\n\t\t\tlet srcFile = opt.srcFile;\n\t\t\ttry{\n\t\t\t\tif(opt.Offset >= 0 && opt.PartSize > 0){\n\t\t\t\t\tsrcFile = this.sliceBlob(srcFile, opt.Offset, opt.Offset + opt.PartSize);\n\t\t\t\t}else if('ContentLength' in opt){\n\t\t\t\t\tlet contentLength = parseInt(opt.ContentLength, 10);\n\t\t\t\t\tif(contentLength > 0){\n\t\t\t\t\t\tsrcFile = this.sliceBlob(srcFile, 0, contentLength);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}catch (e) {\n\t\t\t\treturn bc(e);\n\t\t\t}\n\n\t\t\treopt.data = srcFile;\n\t\t}\n\t\taxios.request(reopt).then(function (response) {\n\t\t\tlog.runLog('info', methodName, 'http cost ' + (new Date().getTime()-start) + ' ms');\n\t\t\tthat.getRequest(methodName, response, signatureContext, retryCount, opt.$requestParam, bc);\n\t\t}).catch(function (err) {\n\t\t\tdealingError(err);\n\t\t});\n\t\treturn;\n\t}\n\n\tlet xhr = null;\n\t// Firefox, Opera 8.0+, Safari\n\ttry {\n\t\txhr = new XMLHttpRequest();\n\t} catch (e) {\n\t\ttry { // InternetExplorer\n\t\t\txhr = new ActiveXObject('Msxml2.XMLHTTP');\n\t\t} catch (e1) {\n\t\t\ttry {\n\t\t\t\txhr = new ActiveXObject('Microsoft.XMLHTTP');\n\t\t\t} catch (e2) {\n\t\t\t}\n\t\t}\n\t}\n\n \tif(xhr === null){\n \t\treturn bc(new Error('XHR is not available'), null);\n \t}\n\n\tif(opt.srcFile){\n\t\tif(!(opt.srcFile instanceof window.File) && !(opt.srcFile instanceof window.Blob)){\n\t\t\treturn bc(new Error('source file must be an instance of window.File or window.Blob'), null);\n\t\t}\n\n\t\ttry{\n\t\t\tlet srcFile = opt.srcFile;\n\t\t\tif(opt.Offset >= 0 && opt.PartSize > 0){\n\t\t\t\tsrcFile = this.sliceBlob(srcFile, opt.Offset, opt.Offset + opt.PartSize);\n\t\t\t}else if('ContentLength' in opt){\n\t\t\t\tlet contentLength = parseInt(opt.ContentLength, 10);\n\t\t\t\tif(contentLength > 0){\n\t\t\t\t\tsrcFile = this.sliceBlob(srcFile, 0, contentLength);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbody = srcFile;\n\t\t}catch (e) {\n\t\t\treturn bc(e);\n\t\t}\n\t}\n\txhr.open(method, (_isSecure ? 'https://' + this.urlPrefix + host : 'http://' + this.urlPrefix + host) + path);\n\txhr.withCredentials = false;\n\tfor(let key in ex){\n\t\tif ({}.hasOwnProperty.call(ex, key)) {\n\t\t\txhr.setRequestHeader(key, ex[key]);\n\t\t}\n\t}\n\txhr.timeout = that.timeout * 1000;\n\txhr.responseType = responseType;\n\topt.$requestParam.cancelHook = function(){\n\t\txhr.abort();\n\t};\n\txhr.onreadystatechange = function(){\n\t\tif(xhr.readyState === 4 && xhr.status >= 200) {\n\t\t\tlog.runLog('info', methodName, 'http cost ' + (new Date().getTime()-start) + ' ms');\n\t\t\tlet headers = xhr.getAllResponseHeaders();\n\t\t let arr = headers.trim().split(/[\\r\\n]+/);\n\t\t let headerMap = {};\n\t\t for(let i=0;i 300)){\n\t\t\topt.headers.Host = host\n\t\t\tthat.sendRequest(funcName, opt, backcall, retryCount + 1);\n\t\t}else{\n\t\t\tbackcall(err, msg);\n\t\t}\n\t});\n};\n\n\nUtils.prototype.doAuth = function(opt, methodName, signatureContext) {\n\tlet interestHeader = ['Content-MD5', 'Content-Type'];\n\tlet stringToSign = opt.method + '\\n';\n\tfor(let i=0;i obj2.key) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t});\n\tfor(let i=0;i= 0){\n\t\t\t\turlPath += urlPath === '' ? '?' : '&';\n\t\t\t\turlPath += key;\n\t\t\t\tif(listvar.length === 2 && listvar[1]){\n\t\t\t\t\turlPath += '=' + decodeURIComponent(listvar[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tpath += urlPath;\n\t}\n\tstringToSign += path;\n\tthis.log.runLog('debug', methodName, 'stringToSign:' + stringToSign);\n\topt.headers.Authorization = signatureContext.authPrefix + ' ' + this.ak + ':' + crypto.createHmac('sha1', this.sk).update(stringToSign).digest('base64');\n};\n\nUtils.prototype.v4Auth = function(opt, methodName, signatureContext){\n\topt.headers[signatureContext.headerPrefix + 'content-sha256'] = CONTENT_SHA256;\n\tlet header = opt.headers;\n\tlet log = this.log;\n\tlet shortDate = null;\n\tlet longDate = null;\n\n\tif((signatureContext.headerPrefix + 'date') in header){\n\t\tlongDate = header[signatureContext.headerPrefix + 'date'];\n\t\tshortDate = longDate.slice(0, longDate.indexOf('T'));\n\t}else{\n\t\tlet dates = getDates(header.Date);\n\t\tshortDate = dates[0];\n\t\tlongDate = dates[1];\n\t}\n\n\tlet credenttial = this.ak + '/' + shortDate + '/' + this.region + '/s3/aws4_request';\n\n\tlet signedAndCanonicalHeaders = getSignedAndCanonicalHeaders(header);\n\n\tlet signedHeaders = signedAndCanonicalHeaders[0];\n\tlet canonicalHeaders = signedAndCanonicalHeaders[1];\n\n\tlet canonicalQueryString = '';\n\tif(opt.urlPath){\n\t\tlet path = opt.urlPath.slice(1);\n\t\tlet arrPath = path.split('&');\n\t\tarrPath = arrPath.sort();\n\t\tfor(let i=0;i signatureContext.headerPrefix.length && key.slice(0, signatureContext.headerPrefix.length) === signatureContext.headerPrefix) {\n\t\t\t\tinterestHeaders[key] = headers[name];\n\t\t\t}\n\t\t}\n\t}\n\n\tlet resource = '';\n\tlet host = this.server;\n\tif(this.isCname){\n\t\tresource += '/' + host + '/';\n\t}else if(bucketName){\n\t\tresource += '/' + bucketName;\n\t\tif(!this.pathStyle){\n\t\t\thost = bucketName + '.' + host;\n\t\t\tresource += '/';\n\t\t}\n\t}\n\n\tif(objectKey){\n\t\tif(resource.lastIndexOf('/') !== resource.length - 1){\n\t\t\tresource += '/';\n\t\t}\n\t\tobjectKey = encodeURIWithSafe(objectKey, '/');\n\t\tresource += objectKey;\n\t}\n\n\tif(resource === ''){\n\t\tresource = '/';\n\t}\n\n\t// 拼接查询参数\n\tqueryParamsKeys.sort();\n\tlet flag = false;\n\tlet _resource = [];\n\tlet safeKey = isShareFolder ? '': '/';\n\tfor(let i=0;i=0 || key.toLowerCase().indexOf(signatureContext.headerPrefix) === 0)){\n\t\t\tflag = true;\n\t\t\tlet _val = val ? key + '=' + decodeURIComponent(val) : key;\n\t\t\t_resource.push(_val);\n\t\t}\n\t}\n\t_resource = _resource.join('&');\n\tif(flag){\n\t\t_resource = '?' + _resource;\n\t}\n\tresource += _resource;\n\tlet stringToSign = [method];\n\tstringToSign.push('\\n');\n\n\tif('content-md5' in interestHeaders){\n\t\tstringToSign.push(interestHeaders['content-md5']);\n\t}\n\tstringToSign.push('\\n');\n\n\tif('content-type' in interestHeaders){\n\t\tstringToSign.push(interestHeaders['content-type']);\n\t}\n\tstringToSign.push('\\n');\n\tif(isShareFolder) {\n\t\tstringToSign.push(policy);\n\t} else {\n\t\tstringToSign.push(String(expires));\n\t}\n\n\tstringToSign.push('\\n');\n\n\tif(!isShareFolder){\n\t\tlet temp = [];\n\t\tlet i = 0;\n\t\tfor(let key in interestHeaders){\n\t\t\tif (key.length > signatureContext.headerPrefix.length && key.slice(0, signatureContext.headerPrefix.length) === signatureContext.headerPrefix){\n\t\t\t\ttemp[i++] = key;\n\t\t\t}\n\t\t}\n\t\ttemp = temp.sort();\n\t\tfor(let j=0;j {\n\t\tqueryParamsKeys.push(e);\n\t})\n\n\tqueryParamsKeys.sort();\n\n\treturn {isShareFolder, queryParams, queryParamsKeys}\n}\n\nUtils.prototype.getSignResult = function(opt, ak, stsToken) {\n\t// 获取计算签名时的resulet\n\tlet {bucketName, objectKey, signatureContext, isShareFolder, queryParams, queryParamsKeys} = opt\n\t// 为queryParams添加钩子函数获取到的ak和token\n\tif(stsToken){\n\t\tqueryParams[signatureContext.headerPrefix + 'security-token'] = stsToken;\n\t}\n\n\tif(signatureContext.signature.toLowerCase() === 'v2'){\n\t\tqueryParams.AWSAccessKeyId = ak;\n\t\tqueryParamsKeys.push('AWSAccessKeyId')\n\t}else{\n\t\tqueryParams.AccessKeyId = ak;\n\t\tqueryParamsKeys.push('AccessKeyId')\n\t}\n\n\tlet result = '';\n\tif(bucketName && this.pathStyle){\n\t\tresult += '/' + bucketName;\n\t}\n\tif(objectKey){\n\t\tobjectKey = encodeURIWithSafe(objectKey, '/');\n\t\tresult += '/' + objectKey;\n\t}\n\tresult += '?';\n\t\n\tqueryParamsKeys.sort();\n\tlet safeKey = isShareFolder ? '': '/';\n\tfor(let i=0;i {\n\t\t\t\tlet result = this.getSignResult(getSignResultOpt, ak, stsToken)\n\t\t\t\treturn getSignedUrl(signature, result)\n\t\t\t})\n\t}\n\n\tfunction getSignedUrl(signature, result){\n\t\tif(isShareFolder) {\n\t\t\tresult += 'Signature=' + encodeURIWithSafe(signature);\n\t\t} else {\n\t\t\tresult += 'Signature=' + encodeURIWithSafe(signature, '/');\n\t\t}\n\t\treturn {\n\t\t\tActualSignedRequestHeaders : headers,\n\t\t\tSignedUrl : (isSecure ? 'https' : 'http') + '://' + host + ':' + port + result\n\t\t};\n\t}\n\n};\n\nUtils.prototype.createV2SignedUrlSync = function(param){\n\tlet {isShareFolder, queryParams, queryParamsKeys} = this.getQueryParams(param)\n\n\tlet {stringToSign, headers, host} = this.getStringToSign({isShareFolder, queryParams, queryParamsKeys}, param)\n\tlet getSignResultOpt = {\n\t\tbucketName : param.Bucket ? String(param.Bucket) : null,\n\t\tobjectKey : param.Key ? String(param.Key) : null,\n\t\tsignatureContext : param.signatureContext || this.signatureContext,\n\t\tisShareFolder,\n\t\tqueryParams, \n\t\tqueryParamsKeys, \n\t}\n\t\n\tlet result = this.getSignResult(getSignResultOpt, this.ak, this.securityToken)\n\n\tlet hmac = crypto.createHmac('sha1', this.sk);\n\thmac.update(stringToSign);\n\tif(isShareFolder) {\n\t\tresult += 'Signature=' + encodeURIWithSafe(hmac.digest('base64'));\n\t} else {\n\t\tresult += 'Signature=' + encodeURIWithSafe(hmac.digest('base64'), '/');\n\t}\n\n\treturn {\n\t\tActualSignedRequestHeaders : headers,\n\t\tSignedUrl : (this.isSecure ? 'https' : 'http') + '://' + host + ':' + this.port + result\n\t};\n};\n\nUtils.prototype.createV4SignedUrlSync = function(param){\n\tparam = param || {};\n\tlet signatureContext = param.signatureContext || this.signatureContext;\n\tlet method = param.Method ? String(param.Method) : 'GET';\n\tlet bucketName = param.Bucket ? String(param.Bucket) : null;\n\tlet objectKey = param.Key ? String(param.Key) : null;\n\tlet specialParam = param.SpecialParam ? String(param.SpecialParam) : null;\n\n\tif(specialParam === 'storageClass'){\n\t\tspecialParam = 'storagePolicy';\n\t}\n\n\tlet expires = param.Expires ? parseInt(param.Expires, 10) : 300;\n\tlet headers = {};\n\tif(param.Headers && (param.Headers instanceof Object) && !(param.Headers instanceof Array)){\n\t\tfor(let key in param.Headers){\n\t\t\tif ({}.hasOwnProperty.call(param.Headers, key)) {\n\t\t\t\theaders[key] = param.Headers[key];\n\t\t\t}\n\t\t}\n\t}\n\n\tlet queryParams = {};\n\tif(param.QueryParams && (param.QueryParams instanceof Object) && !(param.QueryParams instanceof Array)){\n\t\tfor(let key in param.QueryParams){\n\t\t\tif ({}.hasOwnProperty.call(param.QueryParams, key)) {\n\t\t\t\tqueryParams[key] = param.QueryParams[key];\n\t\t\t}\n\t\t}\n\t}\n\n\tif(this.securityToken && !queryParams[signatureContext.headerPrefix + 'security-token']){\n\t\tqueryParams[signatureContext.headerPrefix + 'security-token'] = this.securityToken;\n\t}\n\n\tlet result = '';\n\tlet resource = '';\n\tlet host = this.server;\n\tif(bucketName){\n\t\tif(this.pathStyle){\n\t\t\tresult += '/' + bucketName;\n\t\t\tresource += '/' + bucketName;\n\t\t}else{\n\t\t\thost = bucketName + '.' + host;\n\t\t}\n\t}\n\n\tif(objectKey){\n\t\tobjectKey = encodeURIWithSafe(objectKey, '/');\n\t\tresult += '/' + objectKey;\n\t\tresource += '/' + objectKey;\n\t}\n\n\tif(resource === ''){\n\t\tresource = '/';\n\t}\n\n\tresult += '?';\n\n\tif(specialParam){\n\t\tqueryParams[specialParam] = '';\n\t}\n\n\tif(expires < 0){\n\t\texpires = 300;\n\t}\n\n\tlet utcDateStr = headers['date'] || headers['Date'] || new Date().toUTCString();\n\n\tlet dates = getDates(utcDateStr);\n\tlet shortDate = dates[0];\n\tlet longDate = dates[1];\n\n\theaders.Host = host + ((this.port === 80 || this.port === 443) ? '' : ':' + this.port);\n\n\tqueryParams['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';\n\tqueryParams['X-Amz-Credential'] = this.ak + '/' + shortDate + '/' + this.region + '/s3/aws4_request';\n\tqueryParams['X-Amz-Date'] = longDate;\n\tqueryParams['X-Amz-Expires'] = String(expires);\n\n let signedAndCanonicalHeaders = getSignedAndCanonicalHeaders(headers);\n\n\tqueryParams['X-Amz-SignedHeaders'] = signedAndCanonicalHeaders[0];\n\n\tlet _queryParams = {};\n\tlet queryParamsKeys = [];\n\tfor(let key in queryParams) {\n\t\tif ({}.hasOwnProperty.call(queryParams, key)) {\n\t\t\tlet val = queryParams[key];\n\t\t\tkey = encodeURIWithSafe(key, '/');\n\t\t\tval = encodeURIWithSafe(val);\n\t\t\t_queryParams[key] = val;\n\t\t\tqueryParamsKeys.push(key);\n\t\t\tresult += key;\n\t\t\tif (val) {\n\t\t\t\tresult += '=' + val;\n\t\t\t}\n\t\t\tresult += '&';\n\t\t}\n\t}\n\n\tlet canonicalQueryString = '';\n\n\tqueryParamsKeys.sort();\n\n\tfor(let i=0;i