uptime-kuma/server/ping-lite.js

137 lines
3.5 KiB
JavaScript
Raw Normal View History

2021-07-01 10:00:23 +01:00
// https://github.com/ben-bradley/ping-lite/blob/master/ping-lite.js
// Fixed on Windows
2021-08-10 13:39:58 +01:00
const net = require("net");
const spawn = require("child_process").spawn,
2021-07-27 18:47:13 +01:00
events = require("events"),
fs = require("fs"),
2021-07-01 10:00:23 +01:00
WIN = /^win/.test(process.platform),
LIN = /^linux/.test(process.platform),
MAC = /^darwin/.test(process.platform);
module.exports = Ping;
function Ping(host, options) {
2021-07-27 18:47:13 +01:00
if (!host) {
throw new Error("You must specify a host to ping!");
}
2021-07-01 10:00:23 +01:00
this._host = host;
this._options = options = (options || {});
events.EventEmitter.call(this);
if (WIN) {
2021-07-27 18:47:13 +01:00
this._bin = "c:/windows/system32/ping.exe";
this._args = (options.args) ? options.args : [ "-n", "1", "-w", "5000", host ];
2021-07-01 10:00:23 +01:00
this._regmatch = /[><=]([0-9.]+?)ms/;
2021-08-10 13:39:58 +01:00
2021-07-27 18:47:13 +01:00
} else if (LIN) {
this._bin = "/bin/ping";
2021-08-10 13:39:58 +01:00
const defaultArgs = [ "-n", "-w", "2", "-c", "1", host ];
if (net.isIPv6(host) || options.ipv6) {
2021-08-10 13:39:58 +01:00
defaultArgs.unshift("-6");
}
this._args = (options.args) ? options.args : defaultArgs;
this._regmatch = /=([0-9.]+?) ms/;
2021-07-27 18:47:13 +01:00
} else if (MAC) {
this._bin = "/sbin/ping";
this._args = (options.args) ? options.args : [ "-n", "-t", "2", "-c", "1", host ];
2021-07-01 10:00:23 +01:00
this._regmatch = /=([0-9.]+?) ms/;
2021-08-10 13:39:58 +01:00
2021-07-27 18:47:13 +01:00
} else {
throw new Error("Could not detect your ping binary.");
2021-07-01 10:00:23 +01:00
}
2021-07-27 18:47:13 +01:00
if (!fs.existsSync(this._bin)) {
throw new Error("Could not detect " + this._bin + " on your system");
}
2021-07-01 10:00:23 +01:00
this._i = 0;
return this;
}
Ping.prototype.__proto__ = events.EventEmitter.prototype;
// SEND A PING
// ===========
Ping.prototype.send = function(callback) {
2021-07-27 18:47:13 +01:00
let self = this;
2021-07-01 10:00:23 +01:00
callback = callback || function(err, ms) {
2021-07-27 18:47:13 +01:00
if (err) {
return self.emit("error", err);
}
return self.emit("result", ms);
2021-07-01 10:00:23 +01:00
};
2021-07-27 18:47:13 +01:00
let _ended, _exited, _errored;
2021-07-01 10:00:23 +01:00
this._ping = spawn(this._bin, this._args); // spawn the binary
2021-07-27 18:47:13 +01:00
this._ping.on("error", function(err) { // handle binary errors
2021-07-01 10:00:23 +01:00
_errored = true;
callback(err);
});
2021-07-27 18:47:13 +01:00
this._ping.stdout.on("data", function(data) { // log stdout
this._stdout = (this._stdout || "") + data;
2021-07-01 10:00:23 +01:00
});
2021-07-27 18:47:13 +01:00
this._ping.stdout.on("end", function() {
2021-07-01 10:00:23 +01:00
_ended = true;
2021-07-27 18:47:13 +01:00
if (_exited && !_errored) {
onEnd.call(self._ping);
}
2021-07-01 10:00:23 +01:00
});
2021-07-27 18:47:13 +01:00
this._ping.stderr.on("data", function(data) { // log stderr
this._stderr = (this._stderr || "") + data;
2021-07-01 10:00:23 +01:00
});
2021-07-27 18:47:13 +01:00
this._ping.on("exit", function(code) { // handle complete
2021-07-01 10:00:23 +01:00
_exited = true;
2021-07-27 18:47:13 +01:00
if (_ended && !_errored) {
onEnd.call(self._ping);
}
2021-07-01 10:00:23 +01:00
});
function onEnd() {
2021-07-27 18:47:13 +01:00
let stdout = this.stdout._stdout,
2021-07-01 10:00:23 +01:00
stderr = this.stderr._stderr,
ms;
2021-07-27 18:47:13 +01:00
if (stderr) {
2021-07-01 10:00:23 +01:00
return callback(new Error(stderr));
2021-07-27 18:47:13 +01:00
}
2021-07-27 19:02:20 +01:00
2021-07-27 18:47:13 +01:00
if (!stdout) {
return callback(new Error("No stdout detected"));
}
2021-07-01 10:00:23 +01:00
ms = stdout.match(self._regmatch); // parse out the ##ms response
ms = (ms && ms[1]) ? Number(ms[1]) : ms;
callback(null, ms, stdout);
2021-07-01 10:00:23 +01:00
}
};
// CALL Ping#send(callback) ON A TIMER
// ===================================
Ping.prototype.start = function(callback) {
2021-07-27 18:47:13 +01:00
let self = this;
2021-07-01 10:00:23 +01:00
this._i = setInterval(function() {
self.send(callback);
}, (self._options.interval || 5000));
self.send(callback);
};
// STOP SENDING PINGS
// ==================
Ping.prototype.stop = function() {
clearInterval(this._i);
};