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