amt-wsman-duk.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. Copyright 2018-2021 Intel Corporation
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. /**
  14. * @description WSMAN communication using duktape http
  15. * @author Ylian Saint-Hilaire
  16. * @version v0.2.0c
  17. */
  18. // Construct a WSMAN communication object
  19. function CreateWsmanComm(/*host, port, user, pass, tls, extra*/) {
  20. var obj = {};
  21. obj.PendingAjax = []; // List of pending AJAX calls. When one frees up, another will start.
  22. obj.ActiveAjaxCount = 0; // Number of currently active AJAX calls
  23. obj.MaxActiveAjaxCount = 1; // Maximum number of activate AJAX calls at the same time.
  24. obj.FailAllError = 0; // Set this to non-zero to fail all AJAX calls with that error status, 999 causes responses to be silent.
  25. obj.digest = null;
  26. obj.RequestCount = 0;
  27. if (arguments.length == 1 && typeof (arguments[0] == 'object')) {
  28. obj.host = arguments[0].host;
  29. obj.port = arguments[0].port;
  30. obj.authToken = arguments[0].authToken;
  31. obj.tls = arguments[0].tls;
  32. }
  33. else {
  34. obj.host = arguments[0];
  35. obj.port = arguments[1];
  36. obj.user = arguments[2];
  37. obj.pass = arguments[3];
  38. obj.tls = arguments[4];
  39. }
  40. // Private method
  41. // pri = priority, if set to 1, the call is high priority and put on top of the stack.
  42. obj.PerformAjax = function (postdata, callback, tag, pri, url, action) {
  43. if ((obj.ActiveAjaxCount == 0 || ((obj.ActiveAjaxCount < obj.MaxActiveAjaxCount) && (obj.challengeParams != null))) && obj.PendingAjax.length == 0) {
  44. // There are no pending AJAX calls, perform the call now.
  45. obj.PerformAjaxEx(postdata, callback, tag, url, action);
  46. } else {
  47. // If this is a high priority call, put this call in front of the array, otherwise put it in the back.
  48. if (pri == 1) { obj.PendingAjax.unshift([postdata, callback, tag, url, action]); } else { obj.PendingAjax.push([postdata, callback, tag, url, action]); }
  49. }
  50. }
  51. // Private method
  52. obj.PerformNextAjax = function () {
  53. if (obj.ActiveAjaxCount >= obj.MaxActiveAjaxCount || obj.PendingAjax.length == 0) return;
  54. var x = obj.PendingAjax.shift();
  55. obj.PerformAjaxEx(x[0], x[1], x[2], x[3], x[4]);
  56. obj.PerformNextAjax();
  57. }
  58. // Private method
  59. obj.PerformAjaxEx = function (postdata, callback, tag, url, action)
  60. {
  61. if (obj.FailAllError != 0) { if (obj.FailAllError != 999) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag]); } return; }
  62. if (!postdata) postdata = "";
  63. if (globalDebugFlags & 1) { console.log("SEND: " + postdata + "\r\n\r\n"); } // DEBUG
  64. // We are in a DukTape environement
  65. if (obj.digest == null) {
  66. if (obj.authToken) {
  67. obj.digest = require('http-digest').create({ authToken: obj.authToken });
  68. } else {
  69. obj.digest = require('http-digest').create(obj.user, obj.pass);
  70. }
  71. obj.digest.http = require('http');
  72. }
  73. var request = { delayWrite: true, protocol: (obj.tls == 1 ? 'https:' : 'http:'), method: 'POST', host: obj.host, path: '/wsman', port: obj.port, rejectUnauthorized: false, checkServerIdentity: function (cert) { /*console.log('checkServerIdentity', JSON.stringify(cert));*/ } };
  74. var req = obj.digest.request(request);
  75. //console.log('Request ' + (obj.RequestCount++));
  76. if (globalDebugFlags & 1) { console.log('Request ' + (obj.RequestCount++)); } // DEBUG
  77. req.on('error', function (err) { obj.gotNextMessagesError({ status: 600, error: '' + err }, 'error', null, [postdata, callback, tag]); });
  78. req.on('response', function (response) {
  79. //console.log(JSON.stringify(response, null, 2));
  80. if (globalDebugFlags & 1) { console.log('Response: ' + response.statusCode); }
  81. if (response.statusCode != 200) {
  82. if (globalDebugFlags & 1) { console.log('ERR:' + JSON.stringify(response)); }
  83. obj.gotNextMessagesError({ status: response.statusCode }, 'error', null, [postdata, callback, tag]);
  84. } else {
  85. response.acc = '';
  86. response.on('data', function (data2) { this.acc += data2; });
  87. response.on('end', function () { obj.gotNextMessages(response.acc, 'success', { status: response.statusCode }, [postdata, callback, tag]); });
  88. }
  89. });
  90. // Send POST body, this work with binary.
  91. req.end(postdata);
  92. obj.ActiveAjaxCount++;
  93. return req;
  94. }
  95. // AJAX specific private method
  96. obj.pendingAjaxCall = [];
  97. // Private method
  98. obj.gotNextMessages = function (data, status, request, callArgs) {
  99. obj.ActiveAjaxCount--;
  100. if (obj.FailAllError == 999) return;
  101. if (globalDebugFlags & 1) { console.log("RECV: " + data + "\r\n\r\n"); } // DEBUG
  102. if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
  103. if (request.status != 200) { callArgs[1](null, request.status, callArgs[2]); return; }
  104. callArgs[1](data, 200, callArgs[2]);
  105. obj.PerformNextAjax();
  106. }
  107. // Private method
  108. obj.gotNextMessagesError = function (request, status, errorThrown, callArgs) {
  109. obj.ActiveAjaxCount--;
  110. if (obj.FailAllError == 999) return;
  111. if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
  112. //if (status != 200) { console.log("ERROR, status=" + status + "\r\n\r\nreq=" + callArgs[0]); } // Debug: Display the request & response if something did not work.
  113. if (obj.FailAllError != 999) { callArgs[1]({ Header: { HttpError: request.status, error: request.error } }, request.status, callArgs[2]); }
  114. obj.PerformNextAjax();
  115. }
  116. // Cancel all pending queries with given status
  117. obj.CancelAllQueries = function (s) {
  118. while (obj.PendingAjax.length > 0) { var x = obj.PendingAjax.shift(); x[1](null, s, x[2]); }
  119. }
  120. return obj;
  121. }
  122. module.exports = CreateWsmanComm;