API Docs for: 1.0.8
Show:

File: client/lib/request.js

  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. define(['./hawk', './errors'], function (hawk, ERRORS) {
  5. 'use strict';
  6. /* global XMLHttpRequest */
  7.  
  8. /**
  9. * @class Request
  10. * @constructor
  11. * @param {String} baseUri Base URI
  12. * @param {Object} xhr XMLHttpRequest constructor
  13. * @param {Object} [options={}] Options
  14. * @param {Number} [options.localtimeOffsetMsec]
  15. * Local time offset with the remote auth server's clock
  16. */
  17. function Request (baseUri, xhr, options) {
  18. if (!options) {
  19. options = {};
  20. }
  21. this.baseUri = baseUri;
  22. this._localtimeOffsetMsec = options.localtimeOffsetMsec;
  23. this.xhr = xhr || XMLHttpRequest;
  24. this.timeout = options.timeout || 30 * 1000;
  25. }
  26.  
  27. /**
  28. * @method send
  29. * @param {String} path Request path
  30. * @param {String} method HTTP Method
  31. * @param {Object} credentials HAWK Headers
  32. * @param {Object} jsonPayload JSON Payload
  33. * @param {Object} [options={}] Options
  34. * @param {String} [options.retrying]
  35. * Flag indicating if the request is a retry
  36. * @param {Array} [options.headers]
  37. * A set of extra headers to add to the request
  38. * @return {Promise} A promise that will be fulfilled with JSON `xhr.responseText` of the request
  39. */
  40. Request.prototype.send = function request(path, method, credentials, jsonPayload, options) {
  41. /*eslint complexity: [2, 8] */
  42. var xhr = new this.xhr();
  43. var uri = this.baseUri + path;
  44. var payload = null;
  45. var self = this;
  46. options = options || {};
  47.  
  48. if (jsonPayload) {
  49. payload = JSON.stringify(jsonPayload);
  50. }
  51.  
  52. try {
  53. xhr.open(method, uri);
  54. } catch (e) {
  55. return Promise.reject({ error: 'Unknown error', message: e.toString(), errno: 999 });
  56. }
  57.  
  58. return new Promise(function (resolve, reject) {
  59. xhr.timeout = self.timeout;
  60.  
  61. xhr.onreadystatechange = function() {
  62. if (xhr.readyState === 4) {
  63. var result = xhr.responseText;
  64. try {
  65. result = JSON.parse(xhr.responseText);
  66. } catch (e) { }
  67.  
  68. if (result.errno) {
  69. // Try to recover from a timeskew error and not already tried
  70. if (result.errno === ERRORS.INVALID_TIMESTAMP && !options.retrying) {
  71. var serverTime = result.serverTime;
  72. self._localtimeOffsetMsec = (serverTime * 1000) - new Date().getTime();
  73.  
  74. // add to options that the request is retrying
  75. options.retrying = true;
  76.  
  77. return self.send(path, method, credentials, jsonPayload, options)
  78. .then(resolve, reject);
  79.  
  80. } else {
  81. return reject(result);
  82. }
  83. }
  84.  
  85. if (typeof xhr.status === 'undefined' || xhr.status !== 200) {
  86. if (result.length === 0) {
  87. return reject({ error: 'Timeout error', errno: 999 });
  88. } else {
  89. return reject({ error: 'Unknown error', message: result, errno: 999, code: xhr.status });
  90. }
  91. }
  92.  
  93. resolve(result);
  94. }
  95. };
  96.  
  97. // calculate Hawk header if credentials are supplied
  98. if (credentials) {
  99. var hawkHeader = hawk.client.header(uri, method, {
  100. credentials: credentials,
  101. payload: payload,
  102. contentType: 'application/json',
  103. localtimeOffsetMsec: self._localtimeOffsetMsec || 0
  104. });
  105. xhr.setRequestHeader('authorization', hawkHeader.field);
  106. }
  107.  
  108. xhr.setRequestHeader('Content-Type', 'application/json');
  109.  
  110. if (options && options.headers) {
  111. // set extra headers for this request
  112. for (var header in options.headers) {
  113. xhr.setRequestHeader(header, options.headers[header]);
  114. }
  115. }
  116.  
  117. xhr.send(payload);
  118. });
  119. };
  120.  
  121. return Request;
  122.  
  123. });
  124.