tencentcloud-sdk-nodejs-intl-en
Version:
283 lines (257 loc) • 8.93 kB
JavaScript
const Credential = require("./credential");
const sdkVersion = require("./sdk_version");
const ClientProfile = require("./profile/client_profile");
const Sign = require("./sign");
const HttpConnection = require("./http/http_connection");
const TencentCloudSDKHttpException = require("./exception/tencent_cloud_sdk_exception");
const SSEResponseModel = require("./sse_response_model");
const uuidv4 = require("uuid").v4;
/**
* @inner
*/
class AbstractClient {
/**
* Initialize the client.
* @param {string} endpoint The service's domain name, such as [product].tencentcloudapi.com.
* @param {string} version The version of the service, such as 2017-03-12.
* @param {Credential} credential Credentials.
* @param {string} region Region of the service.
* @param {ClientProfile} profile Profile settings.
*/
constructor(endpoint, version, credential, region, profile) {
this.path = "/";
/**
* Credentials.
* @type {Credential || null}
*/
this.credential = credential || null;
/**
* Region of the service.
* @type {string || null}
*/
this.region = region || null;
this.sdkVersion = "SDK_NODEJS_INTL_EN" + sdkVersion;
this.apiVersion = version;
this.endpoint = endpoint;
/**
* Optional profile settings.
* @type {ClientProfile}
*/
this.profile = profile || new ClientProfile();
}
/**
* @inner
*/
getEndpoint() {
return this.profile.httpProfile.endpoint || this.endpoint;
}
/**
* @inner
*/
succRequest(resp, cb, data) {
if (data instanceof SSEResponseModel) {
cb(null, data);
return;
}
resp.deserialize(data);
cb(null, resp);
}
/**
* @inner
*/
failRequest(err, cb) {
cb(err, null);
}
/**
* @inner
*/
request(action, req, resp, options, cb) {
if (typeof options === 'function') {
cb = options
options = {}
}
if (this.profile.signMethod === 'TC3-HMAC-SHA256') {
this.doRequestWithSign3(action, req, options).then(data => this.succRequest(resp, cb, data), error => this.failRequest(error, cb));
} else {
this.doRequest(action, req, options).then(data => this.succRequest(resp, cb, data), error => this.failRequest(error, cb));
}
}
/**
* @inner
*/
requestOctetStream(action, req, resp, options, cb) {
if (typeof options === 'function') {
cb = options
options = {}
}
options = Object.assign({}, options, {
headers: {
"Content-Type": "application/octet-stream; charset=utf-8",
}
})
if (this.profile.signMethod === 'TC3-HMAC-SHA256') {
this.doRequestWithSign3(action, req, options).then(data => this.succRequest(resp, cb, data), error => this.failRequest(error, cb));
} else {
this.doRequest(action, req, options).then(data => this.succRequest(resp, cb, data), error => this.failRequest(error, cb));
}
}
/**
* @inner
*/
async doRequest(action, req, options) {
let params = this.mergeData(req);
params = this.formatRequestData(action, params);
const headers = Object.assign(
{},
this.profile.httpProfile.headers,
options.headers
)
let traceId = ""
for (let key in headers) {
if (key.toLowerCase() === "x-tc-traceid") {
traceId = headers[key]
break
}
}
if (!traceId) {
traceId = uuidv4()
headers["X-TC-TraceId"] = traceId
}
let res;
try {
res = await HttpConnection.doRequest({
method: this.profile.httpProfile.reqMethod,
url: this.profile.httpProfile.protocol + this.getEndpoint() + this.path,
data: params,
timeout: this.profile.httpProfile.reqTimeout * 1000,
headers,
});
} catch (error) {
throw new TencentCloudSDKHttpException(error.message, "", traceId);
}
return await this.parseResponse(res)
}
/**
* @inner
*/
async doRequestWithSign3(action, params, options) {
const headers = Object.assign(
{},
this.profile.httpProfile.headers,
options.headers
)
let traceId = ""
for (let key in headers) {
if (key.toLowerCase() === "x-tc-traceid") {
traceId = headers[key]
break
}
}
if (!traceId) {
traceId = uuidv4()
headers["X-TC-TraceId"] = traceId
}
let res;
try {
res = await HttpConnection.doRequestWithSign3({
method: this.profile.httpProfile.reqMethod,
url: this.profile.httpProfile.protocol + this.getEndpoint() + this.path,
secretId: this.credential.secretId,
secretKey: this.credential.secretKey,
region: this.region,
data: params,
service: this.getEndpoint().split('.')[0],
action: action,
version: this.apiVersion,
multipart: options.multipart,
timeout: this.profile.httpProfile.reqTimeout * 1000,
token: this.credential.token,
requestClient: this.sdkVersion,
headers,
})
} catch (e) {
throw new TencentCloudSDKHttpException(e.message, "", traceId)
}
return await this.parseResponse(res)
}
async parseResponse(res) {
const traceId = res.headers.get("x-tc-traceid")
if (res.status !== 200) {
const tcError = new TencentCloudSDKHttpException(res.statusText, "", traceId)
tcError.httpCode = res.status
throw tcError;
} else {
if (res.headers.get("content-type") === "text/event-stream") {
return new SSEResponseModel(res.body)
} else {
const data = await res.json();
if (data.Response.Error) {
const tcError = new TencentCloudSDKHttpException(data.Response.Error.Message, data.Response.RequestId, traceId)
tcError.code = data.Response.Error.Code
throw tcError;
} else {
return data.Response;
}
}
}
}
/**
* @inner
*/
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, this.mergeData(data[k], prefix + k + "."));
} else {
ret[prefix + k] = data[k];
}
}
return ret;
}
/**
* @inner
*/
formatRequestData(action, params) {
params.Action = action;
params.RequestClient = this.sdkVersion;
params.Nonce= Math.round(Math.random() * 65535);
params.Timestamp = Math.round(Date.now() / 1000);
params.Version = this.apiVersion;
params.Language = "en-US";
if (this.credential.secretId) {
params.SecretId = this.credential.secretId;
}
if (this.region) {
params.Region = this.region;
}
if (this.credential.token) {
params.Token = this.credential.token;
}
if (this.profile.signMethod) {
params.SignatureMethod = this.profile.signMethod;
}
let signStr = this.formatSignString(params);
params.Signature = Sign.sign(this.credential.secretKey, signStr, this.profile.signMethod);
return params;
}
/**
* @inner
*/
formatSignString (params) {
let strParam = "";
let keys = Object.keys(params);
keys.sort();
for (let k in keys) {
//k = k.replace(/_/g, '.');
strParam += ("&" + keys[k] + "=" + params[keys[k]]);
}
let strSign = this.profile.httpProfile.reqMethod.toLocaleUpperCase() + this.getEndpoint() +
this.path + "?" + strParam.slice(1);
return strSign;
}
}
module.exports = AbstractClient;