async request()

in lib/rpc.js [164:260]


  async request(action, params = {}, opts = {}) {
    const credentials = await this.credentialsProvider.getCredentials();
    // 1. compose params and opts
    opts = Object.assign({
      headers: {
        'x-sdk-client': helper.DEFAULT_CLIENT,
        'user-agent': helper.DEFAULT_UA,
        'x-acs-action': action,
        'x-acs-version': this.apiVersion
      }
    }, this.opts, opts);

    // format action until formatAction is false
    if (opts.formatAction !== false) {
      action = firstLetterUpper(action);
    }

    // format params until formatParams is false
    if (opts.formatParams !== false) {
      params = formatParams(params);
    }
    const defaultParams = {
      Format: 'JSON',
      Timestamp: timestamp(),
      Version: this.apiVersion,
    };
    if (credentials && credentials.accessKeyId && credentials.accessKeySecret) {
      defaultParams.SignatureMethod = 'HMAC-SHA1';
      defaultParams.SignatureVersion = '1.0';
      defaultParams.SignatureNonce = kitx.makeNonce();
      defaultParams.AccessKeyId = credentials.accessKeyId;
      if (credentials.securityToken) {
        defaultParams.SecurityToken = credentials.securityToken;
      }
    }
    params = Object.assign({ Action: action }, defaultParams, params);

    const method = (opts.method || 'GET').toUpperCase();
    const normalized = normalize(params);
    // 2. caculate signature
    if (credentials && credentials.accessKeyId && credentials.accessKeySecret) {
      const canonicalized = canonicalize(normalized);
      // 2.1 get string to sign
      const stringToSign = `${method}&${encode('/')}&${encode(canonicalized)}`;
      // 2.2 get signature
      const key = credentials.accessKeySecret + '&';
      const signature = kitx.sha1(stringToSign, key, 'base64');
      // add signature
      normalized.push(['Signature', encode(signature)]);
    }

    // 3. generate final url
    const url = opts.method === 'POST' ? `${this.endpoint}/` : `${this.endpoint}/?${canonicalize(normalized)}`;
    // 4. send request
    const entry = {
      url: url,
      request: null,
      response: null
    };

    if (opts && !opts.agent) {
      opts.agent = this.keepAliveAgent;
    }

    if (opts.method === 'POST') {
      opts.headers = opts.headers || {};
      opts.headers['content-type'] = 'application/x-www-form-urlencoded';
      opts.data = canonicalize(normalized);
    }

    const response = await httpx.request(url, opts);
    entry.request = {
      headers: response.req.getHeaders ? response.req.getHeaders() : response.req._headers
    };
    entry.response = {
      statusCode: response.statusCode,
      headers: response.headers
    };

    const buffer = await httpx.read(response);
    const json = JSON.parse(buffer);
    if (json.Code && !this.codes.has(json.Code)) {
      const err = new Error(`${json.Message}, URL: ${url}`);
      err.name = json.Code + 'Error';
      err.data = json;
      err.code = json.Code;
      err.url = url;
      err.entry = entry;
      throw err;
    }

    if (this.verbose) {
      return [json, entry];
    }

    return json;
  }