Initial commit

This commit is contained in:
2021-08-26 21:47:42 +02:00
commit fe941c6433
1432 changed files with 161130 additions and 0 deletions

203
node_modules/ping/lib/parser/base.js generated vendored Normal file
View File

@ -0,0 +1,203 @@
'use strict';
/* eslint no-unused-vars: 0 */
var __ = require('underscore');
/**
* Parsed response
* @typedef {object} PingResponse
* @param {string} inputHost - The input IP address or HOST
* @param {string} host - The input IP address or HOST
* @param {string} numeric_host - Target IP address
* @param {boolean} alive - True for existed host
* @param {string} output - Raw stdout from system ping
* @param {number} time - Time (float) in ms for first successful ping response
* @param {string} min - Minimum time for collection records
* @param {string} max - Maximum time for collection records
* @param {string} avg - Average time for collection records
* @param {number} packetLoss - Packet Losses in percent (number)
* @param {string} stddev - Standard deviation time for collected records
*/
/**
* @constructor
*
* @param {string} addr - Hostname or ip addres
* @param {PingConfig} config - Config object in probe()
*/
function parser(addr, config) {
// Initial state is 0
this._state = 0;
// Initial cache value
this._response = {
inputHost: addr,
host: 'unknown',
alive: false,
output: 'unknown',
time: 'unknown',
times: [],
min: 'unknown',
max: 'unknown',
avg: 'unknown',
stddev: 'unknown',
packetLoss: 'unknown',
};
// Initial times storage for ping time
this._times = [];
// Initial lines storage for ping output
this._lines = [];
// strip string regexp
this._stripRegex = /[ ]*\r?\n?$/g;
// Ping Config
this._pingConfig = config || {};
}
/**
* Enum for parser states
* @readonly
* @enum {number}
*/
parser.prototype.STATES = {
INIT: 0,
HEADER: 1,
BODY: 2,
FOOTER: 3,
END: 4,
};
/**
* Change state of this parser
* @param {number} state - parser.STATES
* @return {this} - This instance
*/
parser.prototype._changeState = function (state) {
var states = __.values(this.STATES);
if (states.indexOf(state) < 0) {
throw new Error('Unknown state');
}
this._state = state;
return this;
};
/**
* Process output's header
* @param {string} line - A line from system ping
*/
parser.prototype._processHeader = function (line) {
throw new Error('Subclass should implement this method');
};
/**
* Process output's body
* @param {string} line - A line from system ping
*/
parser.prototype._processBody = function (line) {
throw new Error('Subclass should implement this method');
};
/**
* Process output's footer
* @param {string} line - A line from system ping
*/
parser.prototype._processFooter = function (line) {
throw new Error('Subclass should implement this method');
};
/**
* Process a line from system ping
* @param {string} line - A line from system ping
* @return {this} - This instance
*/
parser.prototype.eat = function (line) {
var headerStates = [
this.STATES.INIT,
this.STATES.HEADER,
];
// Store lines
this._lines.push(line);
// Strip all space \r\n at the end
var _line = line.replace(this._stripRegex, '');
if (_line.length === 0) {
// Do nothing if this is an empty line
} else if (headerStates.indexOf(this._state) >= 0) {
this._processHeader(_line);
} else if (this._state === this.STATES.BODY) {
this._processBody(_line);
} else if (this._state === this.STATES.FOOTER) {
this._processFooter(_line);
} else if (this._state === this.STATES.END) {
// Do nothing
} else {
throw new Error('Unknown state');
}
return this;
};
/**
* Get results after parsing certain lines from system ping
* @return {PingResponse} - Response from parsing ping output
*/
parser.prototype.getResult = function () {
var ret = __.extend({}, this._response);
// Concat output
ret.output = this._lines.join('\n');
// Determine alive
ret.alive = this._times.length > 0;
// Update time at first successful line
if (ret.alive) {
this._response.time = this._times[0];
ret.time = this._response.time;
this._response.times = this._times;
ret.times = this._response.times;
}
// Get stddev
if (
ret.stddev === 'unknown' && ret.alive
) {
var numberOfSamples = this._times.length;
var sumOfAllSquareDifferences = __.reduce(
this._times,
function (memory, time) {
var differenceFromMean = time - ret.avg;
var squaredDifference =
differenceFromMean * differenceFromMean;
return memory + squaredDifference;
},
0
);
var variances = sumOfAllSquareDifferences / numberOfSamples;
ret.stddev = Math.round(
Math.sqrt(variances) * 1000
) / 1000;
}
// Fix min, avg, max, stddev up to 3 decimal points
__.each(['min', 'avg', 'max', 'stddev', 'packetLoss'], function (key) {
var v = ret[key];
if (__.isNumber(v)) {
ret[key] = v.toFixed(3);
}
});
return ret;
};
module.exports = parser;

44
node_modules/ping/lib/parser/factory.js generated vendored Normal file
View File

@ -0,0 +1,44 @@
'use strict';
var util = require('util');
var builderFactory = require('../builder/factory');
var WinParser = require('./win');
var MacParser = require('./mac');
var LinuxParser = require('./linux');
/**
* A factory creates a parser for parsing output from system ping
* @constructor
*/
function factory() {}
/**
* Create a parser for a given platform
* @param {string} addr - Hostname or ip addres
* @param {string} platform - Name of the platform
* @param {PingConfig} [config] - Config object in probe()
* @return {object} - Parser
* @throw if given platform is not supported
*/
factory.createParser = function (addr, platform, config) {
// Avoid function reassignment
var _config = config || {};
if (!builderFactory.isPlatformSupport(platform)) {
throw new Error(util.format('Platform |%s| is not support', platform));
}
var ret = null;
if (builderFactory.isWindow(platform)) {
ret = new WinParser(addr, _config);
} else if (builderFactory.isMacOS(platform)) {
ret = new MacParser(addr, _config);
} else if (builderFactory.isLinux(platform)) {
ret = new LinuxParser(addr, _config);
}
return ret;
};
module.exports = factory;

59
node_modules/ping/lib/parser/linux.js generated vendored Normal file
View File

@ -0,0 +1,59 @@
'use strict';
var util = require('util');
var base = require('./base');
var MacParser = require('./mac');
/**
* @constructor
*
* @param {string} addr - Hostname or ip addres
* @param {PingConfig} config - Config object in probe()
*/
function LinuxParser(addr, config) {
base.call(this, addr, config);
}
util.inherits(LinuxParser, base);
/**
* Process output's body
* @param {string} line - A line from system ping
*/
LinuxParser.prototype._processHeader = function (line) {
// Get host and numeric_host
var tokens = line.split(' ');
var isProbablyIPv4 = tokens[1].indexOf('(') === -1;
if (isProbablyIPv4) {
this._response.host = tokens[1];
this._response.numeric_host = tokens[2].slice(1, -1);
} else {
// Normalise into either a 2 or 3 element array
var foundAddresses = tokens.slice(1, -3).join('').match(/([^\s()]+)/g);
this._response.host = foundAddresses.shift();
this._response.numeric_host = foundAddresses.pop();
}
this._changeState(this.STATES.BODY);
};
/**
* Process output's body
* @param {string} line - A line from system ping
*/
LinuxParser.prototype._processBody = function (line) {
// Reuse mac parser implementation
MacParser.prototype._processBody.call(this, line);
};
/**
* Process output's footer
* @param {string} line - A line from system ping
*/
LinuxParser.prototype._processFooter = function (line) {
// Reuse mac parser implementation
MacParser.prototype._processFooter.call(this, line);
};
module.exports = LinuxParser;

85
node_modules/ping/lib/parser/mac.js generated vendored Normal file
View File

@ -0,0 +1,85 @@
'use strict';
var util = require('util');
var __ = require('underscore');
var base = require('./base');
/**
* @constructor
*
* @param {string} addr - Hostname or ip addres
* @param {PingConfig} config - Config object in probe()
*/
function MacParser(addr, config) {
base.call(this, addr, config);
}
util.inherits(MacParser, base);
/**
* Process output's header
* @param {string} line - A line from system ping
*/
MacParser.prototype._processHeader = function (line) {
// Get host and numeric_host
var tokens = line.split(' ');
this._response.host = tokens[1];
this._response.numeric_host = tokens[2].slice(1, -2);
this._changeState(this.STATES.BODY);
};
/**
* Process output's body
* @param {string} line - A line from system ping
*/
MacParser.prototype._processBody = function (line) {
// XXX: Assume there is at least 3 '=' can be found
var count = (line.match(/=/g) || []).length;
if (count >= 3) {
var regExp = /([0-9.]+)[ ]*ms/;
var match = regExp.exec(line);
this._times.push(parseFloat(match[1], 10));
}
// Change state if it see a '---'
if (line.indexOf('---') >= 0) {
this._changeState(this.STATES.FOOTER);
}
};
/**
* Process output's footer
* @param {string} line - A line from system ping
*/
MacParser.prototype._processFooter = function (line) {
var packetLoss = line.match(/ ([\d.]+)%/);
if (packetLoss) {
this._response.packetLoss = parseFloat(packetLoss[1], 10);
}
// XXX: Assume number of keywords '/' more than 3
var count = (line.match(/[/]/g) || []).length;
if (count >= 3) {
var regExp = /([0-9.]+)/g;
// XXX: Assume min avg max stddev
var m1 = regExp.exec(line);
var m2 = regExp.exec(line);
var m3 = regExp.exec(line);
var m4 = regExp.exec(line);
if (__.all([m1, m2, m3, m4])) {
this._response.min = parseFloat(m1[1], 10);
this._response.avg = parseFloat(m2[1], 10);
this._response.max = parseFloat(m3[1], 10);
this._response.stddev = parseFloat(m4[1], 10);
this._changeState(this.STATES.END);
}
this._changeState(this.STATES.END);
}
};
module.exports = MacParser;

179
node_modules/ping/lib/parser/win.js generated vendored Normal file
View File

@ -0,0 +1,179 @@
'use strict';
var util = require('util');
var __ = require('underscore');
var base = require('./base');
/**
* @constructor
*
* @param {string} addr - Hostname or ip addres
* @param {PingConfig} config - Config object in probe()
*/
function WinParser(addr, config) {
base.call(this, addr, config);
this._ipv4Regex = /^([0-9]{1,3}\.){3}[0-9]{1,3}$/;
}
util.inherits(WinParser, base);
/**
* Process output's header
* @param {string} line - A line from system ping
*/
WinParser.prototype._processHeader = function (line) {
// XXX: Expect to find [****] when pinging domain like google.com
// Read fixture/win/**/* for the detail
var isPingNumeric = line.indexOf('[') === -1;
// Get host and numeric_host
var tokens = line.split(' ');
if (isPingNumeric) {
// For those missing [***], get the first token which match IPV4 regex
this._response.host = __.find(tokens, function (t) {
return this._ipv4Regex.test(t);
}, this);
this._response.numeric_host = this._response.host;
} else {
// For those has [***], anchor with such token
var numericHost = __.find(tokens, function (t) {
return t.indexOf('[') !== -1;
}, this);
var numericHostIndex = tokens.indexOf(numericHost);
var match = /\[(.*)\]/.exec(numericHost);
if (match) {
// Capture IP inside [] only. refs #71
this._response.numeric_host = match[1];
} else {
// Otherwise, just mark as NA to indicate an error
this._response.numeric_host = 'NA';
}
this._response.host = tokens[numericHostIndex - 1];
}
this._changeState(this.STATES.BODY);
};
/**
* Process ipv6 output's body
* @param {string} line - A line from system ping
*/
WinParser.prototype._processIPV6Body = function (line) {
var tokens = line.split(' ');
var dataFields = __.filter(tokens, function (token) {
var isDataField = token.indexOf('=') >= 0 || token.indexOf('<') >= 0;
return isDataField;
});
// refs #65: Support system like french which has an extra space
dataFields = __.map(dataFields, function (dataField) {
var ret = dataField;
var dataFieldIndex = tokens.indexOf(dataField);
var nextIndex = dataFieldIndex + 1;
// Append the missing *ms*
if (nextIndex < tokens.length) {
if (tokens[nextIndex] === 'ms') {
ret += 'ms';
}
}
return ret;
});
var expectDataFieldInReplyLine = 1;
if (dataFields.length >= expectDataFieldInReplyLine) {
// XXX: Assume time will alaways get keyword ms for all language
var timeKVP = __.find(dataFields, function (dataField) {
return dataField.search(/(ms|мс)/i) >= 0;
});
var regExp = /([0-9.]+)/;
var match = regExp.exec(timeKVP);
this._times.push(parseFloat(match[1], 10));
}
};
/**
* Process ipv4 output's body
* @param {string} line - A line from system ping
*/
WinParser.prototype._processIPV4Body = function (line) {
var tokens = line.split(' ');
var byteTimeTTLFields = __.filter(tokens, function (token) {
var isDataField = token.indexOf('=') >= 0 || token.indexOf('<') >= 0;
return isDataField;
});
var expectDataFieldInReplyLine = 3;
var isReplyLine = byteTimeTTLFields.length >= expectDataFieldInReplyLine;
if (isReplyLine) {
var packetSize = this._pingConfig.packetSize;
var byteField = __.find(byteTimeTTLFields, function (dataField) {
var packetSizeToken = util.format('=%d', packetSize);
var isByteField = dataField.indexOf(packetSizeToken) >= 0;
return isByteField;
});
// XXX: Assume time field will always be next of byte field
var byteFieldIndex = byteTimeTTLFields.indexOf(byteField);
var timeFieldIndex = byteFieldIndex + 1;
var timeKVP = byteTimeTTLFields[timeFieldIndex];
var regExp = /([0-9.]+)/;
var match = regExp.exec(timeKVP);
this._times.push(parseFloat(match[1], 10));
}
};
/**
* Process output's body
* @param {string} line - A line from system ping
*/
WinParser.prototype._processBody = function (line) {
var isPingSummaryLineShown = line.slice(-1) === ':';
if (isPingSummaryLineShown) {
this._changeState(this.STATES.FOOTER);
return;
}
var isIPV6 = this._pingConfig.v6;
if (isIPV6) {
this._processIPV6Body(line);
} else {
this._processIPV4Body(line);
}
};
/**
* Process output's footer
* @param {string} line - A line from system ping
*/
WinParser.prototype._processFooter = function (line) {
var packetLoss = line.match(/([\d.]+)%/);
if (packetLoss) {
this._response.packetLoss = parseFloat(packetLoss[1], 10);
}
// XXX: Assume there is a keyword ms
if (line.search(/(ms|мсек)/i) >= 0) {
// XXX: Assume the ordering is Min Max Avg
var regExp = /([0-9.]+)/g;
var m1 = regExp.exec(line);
var m2 = regExp.exec(line);
var m3 = regExp.exec(line);
if (__.all([m1, m2, m3])) {
this._response.min = parseFloat(m1[1], 10);
this._response.max = parseFloat(m2[1], 10);
this._response.avg = parseFloat(m3[1], 10);
this._changeState(this.STATES.END);
}
}
};
module.exports = WinParser;