json.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. var util = require('../util');
  2. var JsonBuilder = require('../json/builder');
  3. var JsonParser = require('../json/parser');
  4. var populateHostPrefix = require('./helpers').populateHostPrefix;
  5. function buildRequest(req) {
  6. var httpRequest = req.httpRequest;
  7. var api = req.service.api;
  8. var target = api.targetPrefix + '.' + api.operations[req.operation].name;
  9. var version = api.jsonVersion || '1.0';
  10. var input = api.operations[req.operation].input;
  11. var builder = new JsonBuilder();
  12. if (version === 1) version = '1.0';
  13. if (api.awsQueryCompatible) {
  14. if (!httpRequest.params) {
  15. httpRequest.params = {};
  16. }
  17. // because Query protocol does this.
  18. Object.assign(httpRequest.params, req.params);
  19. }
  20. httpRequest.body = builder.build(req.params || {}, input);
  21. httpRequest.headers['Content-Type'] = 'application/x-amz-json-' + version;
  22. httpRequest.headers['X-Amz-Target'] = target;
  23. populateHostPrefix(req);
  24. }
  25. function extractError(resp) {
  26. var error = {};
  27. var httpResponse = resp.httpResponse;
  28. error.code = httpResponse.headers['x-amzn-errortype'] || 'UnknownError';
  29. if (typeof error.code === 'string') {
  30. error.code = error.code.split(':')[0];
  31. }
  32. if (httpResponse.body.length > 0) {
  33. try {
  34. var e = JSON.parse(httpResponse.body.toString());
  35. var code = e.__type || e.code || e.Code;
  36. if (code) {
  37. error.code = code.split('#').pop();
  38. }
  39. if (error.code === 'RequestEntityTooLarge') {
  40. error.message = 'Request body must be less than 1 MB';
  41. } else {
  42. error.message = (e.message || e.Message || null);
  43. }
  44. // The minimized models do not have error shapes, so
  45. // without expanding the model size, it's not possible
  46. // to validate the response shape (members) or
  47. // check if any are sensitive to logging.
  48. // Assign the fields as non-enumerable, allowing specific access only.
  49. for (var key in e || {}) {
  50. if (key === 'code' || key === 'message') {
  51. continue;
  52. }
  53. error['[' + key + ']'] = 'See error.' + key + ' for details.';
  54. Object.defineProperty(error, key, {
  55. value: e[key],
  56. enumerable: false,
  57. writable: true
  58. });
  59. }
  60. } catch (e) {
  61. error.statusCode = httpResponse.statusCode;
  62. error.message = httpResponse.statusMessage;
  63. }
  64. } else {
  65. error.statusCode = httpResponse.statusCode;
  66. error.message = httpResponse.statusCode.toString();
  67. }
  68. resp.error = util.error(new Error(), error);
  69. }
  70. function extractData(resp) {
  71. var body = resp.httpResponse.body.toString() || '{}';
  72. if (resp.request.service.config.convertResponseTypes === false) {
  73. resp.data = JSON.parse(body);
  74. } else {
  75. var operation = resp.request.service.api.operations[resp.request.operation];
  76. var shape = operation.output || {};
  77. var parser = new JsonParser();
  78. resp.data = parser.parse(body, shape);
  79. }
  80. }
  81. /**
  82. * @api private
  83. */
  84. module.exports = {
  85. buildRequest: buildRequest,
  86. extractError: extractError,
  87. extractData: extractData
  88. };