UNPKG

tencentcloud-sdk-nodejs-intl-en

Version:
175 lines (155 loc) 4.75 kB
const QueryString = require("querystring"); const { URL } = require('url'); const isStream = require('is-stream'); const getStream = require('get-stream'); const FormData = require('form-data'); const Sign = require('../sign'); const fetch = require('./fetch'); /** * @inner */ class HttpConnection { static async doRequest({ method, url, data, timeout, headers }) { let config = { method: method, headers, timeout }; if (method === "GET") { url += "?" + QueryString.stringify(data); } else { config.headers['Content-Type'] = 'application/x-www-form-urlencoded' config.body = QueryString.stringify(data); } return await fetch(url, config) } static async doRequestWithSign3({ method, url, data, service, action, region, version, secretId, secretKey, multipart = false, timeout = 60000, token, requestClient, headers = {} }) { // data 中可能带有 readStream,由于需要计算整个 body 的 hash, // 所以这里把 readStream 转为 Buffer await convertReadStreamToBuffer(data) data = deepRemoveNull(data) const timestamp = parseInt(new Date().getTime() / 1000) method = method.toUpperCase() let payload = '' if (method === 'GET') { data = mergeData(data) url += '?' + QueryString.stringify(data) } if (method === 'POST') { payload = data } const config = { method, timeout, headers: Object.assign({}, headers, { 'Host': new URL(url).host, 'X-TC-Action': action, 'X-TC-Region': region, 'X-TC-Timestamp': timestamp, 'X-TC-Version': version, 'X-TC-Token': token, 'X-TC-RequestClient': requestClient, }) } if (token === null) { delete config.headers["X-TC-Token"] } let form if (method === 'GET') { config.headers['Content-Type'] = 'application/x-www-form-urlencoded' } if (method === 'POST' && !multipart) { config.body = data const contentType = config.headers["Content-Type"] || "application/json" if (!isBuffer(data)) config.body = JSON.stringify(data) config.headers["Content-Type"] = contentType } if (method === 'POST' && multipart) { form = new FormData(); for (var key in data) { form.append(key, data[key]) } config.body = form config.headers = Object.assign({}, config.headers, form.getHeaders()) } const signature = Sign.sign3({ method, url, payload, timestamp, service, secretId, secretKey, multipart, boundary: form ? form.getBoundary() : undefined, headers: config.headers, }) config.headers['Authorization'] = signature return await fetch(url, config) } } async function convertReadStreamToBuffer(data) { for (let key in data) { if (isStream(data[key])) { data[key] = await getStream.buffer(data[key]) } } } function mergeData(data, prefix = "") { let ret = {}; for (let k in data) { if (data[k] === null) { continue; } if (data[k] instanceof Array || data[k] instanceof Object) { Object.assign(ret, mergeData(data[k], prefix + k + ".")); } else { ret[prefix + k] = data[k]; } } return ret; } function deepRemoveNull(obj) { if (isArray(obj)) { return obj.map(deepRemoveNull) } else if (isObject(obj)) { let result = {} for (let key in obj) { const value = obj[key] if (!isNull(value)) { result[key] = deepRemoveNull(value) } } return result } else { return obj } } function isBuffer(x) { return Buffer.isBuffer(x) } function isArray(x) { return Array.isArray(x) } function isObject(x) { return typeof x === 'object' && !isArray(x) && !isStream(x) && !isBuffer(x) && x !== null } function isNull(x) { return x === null } module.exports = HttpConnection;