Version 3.18.1
Show:

File: io/js/io-nodejs.js

  1. /*global Y: false, Buffer: false, clearInterval: false, clearTimeout: false, console: false, exports: false, global: false, module: false, process: false, querystring: false, require: false, setInterval: false, setTimeout: false, __filename: false, __dirname: false */
  2. /**
  3. * Node.js override for IO, methods are mixed into `Y.IO`
  4. * @module io-nodejs
  5. * @main io-nodejs
  6. */
  7. /**
  8. * Passthru to the NodeJS <a href="https://github.com/mikeal/request">request</a> module.
  9. * This method is return of `require('request')` so you can use it inside NodeJS without
  10. * the IO abstraction.
  11. * @method request
  12. * @static
  13. * @for IO
  14. */
  15. if (!Y.IO.request) {
  16. // Default Request's cookie jar to `false`. This way cookies will not be
  17. // maintained across requests.
  18. Y.IO.request = require('request').defaults({jar: false});
  19. }
  20. var codes = require('http').STATUS_CODES;
  21. /**
  22. Flatten headers object
  23. @method flatten
  24. @protected
  25. @for IO
  26. @param {Object} o The headers object
  27. @return {String} The flattened headers object
  28. */
  29. var flatten = function(o) {
  30. var str = [];
  31. Object.keys(o).forEach(function(name) {
  32. str.push(name + ': ' + o[name]);
  33. });
  34. return str.join('\n');
  35. };
  36. Y.log('Loading NodeJS Request Transport', 'info', 'io');
  37. /**
  38. NodeJS IO transport, uses the NodeJS <a href="https://github.com/mikeal/request">request</a>
  39. module under the hood to perform all network IO.
  40. @method transports.nodejs
  41. @for IO
  42. @static
  43. @return {Object} This object contains only a `send` method that accepts a
  44. `transaction object`, `uri` and the `config object`.
  45. @example
  46. Y.io('https://somedomain.com/url', {
  47. method: 'PUT',
  48. data: '?foo=bar',
  49. //Extra request module config options.
  50. request: {
  51. maxRedirects: 100,
  52. strictSSL: true,
  53. multipart: [
  54. {
  55. 'content-type': 'application/json',
  56. body: JSON.stringify({
  57. foo: 'bar',
  58. _attachments: {
  59. 'message.txt': {
  60. follows: true,
  61. length: 18,
  62. 'content_type': 'text/plain'
  63. }
  64. }
  65. })
  66. },
  67. {
  68. body: 'I am an attachment'
  69. }
  70. ]
  71. },
  72. on: {
  73. success: function(id, e) {
  74. Y.log(e.responseText);
  75. }
  76. }
  77. });
  78. */
  79. Y.IO.transports.nodejs = function() {
  80. return {
  81. send: function (transaction, uri, config) {
  82. Y.log('Starting Request Transaction', 'info', 'io');
  83. config.notify('start', transaction, config);
  84. config.method = config.method || 'GET';
  85. config.method = config.method.toUpperCase();
  86. var rconf = {
  87. method: config.method,
  88. uri: uri
  89. };
  90. if (config.data) {
  91. if (Y.Lang.isString(config.data)) {
  92. rconf.body = config.data;
  93. }
  94. if (rconf.body && rconf.method === 'GET') {
  95. rconf.uri += (rconf.uri.indexOf('?') > -1 ? '&' : '?') + rconf.body;
  96. rconf.body = '';
  97. }
  98. }
  99. if (config.headers) {
  100. rconf.headers = config.headers;
  101. }
  102. if (config.timeout) {
  103. rconf.timeout = config.timeout;
  104. }
  105. if (config.request) {
  106. Y.mix(rconf, config.request);
  107. }
  108. Y.log('Initiating ' + rconf.method + ' request to: ' + rconf.uri, 'info', 'io');
  109. Y.IO.request(rconf, function(err, data) {
  110. Y.log('Request Transaction Complete', 'info', 'io');
  111. if (err) {
  112. Y.log('An IO error occurred', 'warn', 'io');
  113. transaction.c = err;
  114. config.notify(((err.code === 'ETIMEDOUT') ? 'timeout' : 'failure'), transaction, config);
  115. return;
  116. }
  117. if (data) {
  118. transaction.c = {
  119. status: data.statusCode,
  120. statusCode: data.statusCode,
  121. statusText: codes[data.statusCode],
  122. headers: data.headers,
  123. responseText: data.body || '',
  124. responseXML: null,
  125. getResponseHeader: function(name) {
  126. return this.headers[name];
  127. },
  128. getAllResponseHeaders: function() {
  129. return flatten(this.headers);
  130. }
  131. };
  132. }
  133. Y.log('Request Transaction Complete', 'info', 'io');
  134. config.notify('complete', transaction, config);
  135. config.notify(((data && (data.statusCode >= 200 && data.statusCode <= 299)) ? 'success' : 'failure'), transaction, config);
  136. });
  137. var ret = {
  138. io: transaction
  139. };
  140. return ret;
  141. }
  142. };
  143. };
  144. Y.IO.defaultTransport('nodejs');