async request()

in lib/roa.js [180:281]


  async request(method, uriPattern, query = {}, body = '', headers = {}, opts = {}) {
    const credentials = await this.credentialsProvider.getCredentials();

    const now = new Date();
    var defaultHeaders = {
      accept: 'application/json',
      date: now.toGMTString(),
      host: this.host,
      'x-acs-signature-nonce': kitx.makeNonce(),
      'x-acs-version': this.apiVersion,
      'user-agent': helper.DEFAULT_UA,
      'x-sdk-client': helper.DEFAULT_CLIENT
    };
    if (credentials && credentials.accessKeyId && credentials.accessKeySecret) {
      defaultHeaders['x-acs-signature-method'] = 'HMAC-SHA1';
      defaultHeaders['x-acs-signature-version'] = '1.0';
      if (credentials.securityToken) {
        defaultHeaders['x-acs-accesskey-id'] = credentials.accessKeyId;
        defaultHeaders['x-acs-security-token'] = credentials.securityToken;
      }
    }

    var mixHeaders = Object.assign(defaultHeaders, keyLowerify(headers));

    var postBody = null;

    postBody = Buffer.from(body, 'utf8');
    mixHeaders['content-md5'] = kitx.md5(postBody, 'base64');
    mixHeaders['content-length'] = postBody.length;

    var url = `${this.endpoint}${uriPattern}`;
    if (Object.keys(query).length) {
      url += `?${querystring.stringify(query)}`;
    }

    if (credentials && credentials.accessKeyId && credentials.accessKeySecret) {
      const stringToSign = buildStringToSign(method, uriPattern, mixHeaders, query);
      debug('stringToSign: %s', stringToSign);
      const utf8Buff = Buffer.from(stringToSign, 'utf8');
      const signature = kitx.sha1(utf8Buff, credentials.accessKeySecret, 'base64');
      mixHeaders['authorization'] = `acs ${credentials.accessKeyId}:${signature}`;
    }

    const options = Object.assign({
      method,
      agent: this.keepAliveAgent,
      headers: mixHeaders,
      data: postBody
    }, this.opts, opts);

    const response = await httpx.request(url, options);
    const responseBody = await httpx.read(response, 'utf8');

    // Retrun raw body
    if (opts.rawBody) {
      return responseBody;
    }

    const contentType = response.headers['content-type'] || '';
    // JSON
    if (contentType.startsWith('application/json')) {
      const statusCode = response.statusCode;
      if (statusCode === 204) {
        return responseBody;
      }

      var result;
      try {
        result = JSON.parse(responseBody);
      } catch (err) {
        err.name = 'FormatError';
        err.message = 'parse response to json error';
        err.body = responseBody;
        throw err;
      }

      if (statusCode >= 400) {
        const errorMessage = result.Message || result.errorMsg || '';
        const errorCode = result.Code || result.errorCode || '';
        const requestId = result.RequestId || '';
        var err = new Error(`code: ${statusCode}, ${errorMessage}, requestid: ${requestId}`);
        err.name = `${errorCode}Error`;
        err.statusCode = statusCode;
        err.result = result;
        err.code = errorCode;
        throw err;
      }

      return result;
    }

    if (contentType.startsWith('text/xml')) {
      const result = await parseXML(responseBody);
      if (result.Error) {
        throw new ACSError(result.Error);
      }

      return result;
    }

    return responseBody;
  }