Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

healthchecks

Package Overview
Dependencies
Maintainers
2
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

healthchecks - npm Package Compare versions

Comparing version 1.7.2 to 1.7.3

.eslintrc.json

5

CHANGELOG.md

@@ -0,1 +1,6 @@

## Version 1.7.3 2016-06-21
CHANGED code cleanups and linting
## Version 1.7.2 2015-12-15

@@ -2,0 +7,0 @@

1

example/index.js

@@ -0,1 +1,2 @@

/*eslint-disable */
// To run this example:

@@ -2,0 +3,0 @@ //

212

lib/healthchecks.js

@@ -0,1 +1,2 @@

'use strict';
// Exports an Express middleware factory.

@@ -41,22 +42,28 @@ //

// Represents a check outcome with the properties url, reason, etc.
function Outcome(url, expected, error, statusCode, body, elapsed) {
this.url = url;
this.elapsed = hrTime(elapsed);
if (error && error.code === 'ETIMEDOUT') {
//
// url - Checked URL
// elapsed - In milliseconds
// error - Protocol error
// statusCode - HTTP status code
// body - Response body
// expected - Expected response body (array)
function Outcome(args) {
this.url = args.url;
this.elapsed = hrTime(args.elapsed);
if (args.error && args.error.code === 'ETIMEDOUT') {
this.reason = 'timeout';
this.timeout = true;
} else if (error) {
} else if (args.error) {
this.reason = 'error';
this.error = error;
this.error = args.error;
} else {
this.statusCode = statusCode;
this.body = body;
if (statusCode < 200 || statusCode >= 400)
this.statusCode = args.statusCode;
this.body = args.body;
if (this.statusCode < 200 || this.statusCode >= 400)
this.reason = 'statusCode';
else {
const allMatching = expected.every(function(text) {
return ~body.indexOf(text);
});
const expected = args.expected;
const allMatching = expected.every(text => ~args.body.indexOf(text));
if (!allMatching)

@@ -89,2 +96,3 @@ this.reason = 'body';

}
// no default
}

@@ -98,6 +106,6 @@ };

case 'error': {
return this.url + ' => ' + this.error.message;
return `${this.url} => ${this.error.message}`;
}
case 'statusCode': {
return this.url + ' => ' + this.statusCode;
return `${this.url} => ${this.statusCode}`;
}

@@ -109,3 +117,3 @@ case undefined: {

default: {
return this.url + ' => ' + this.reason;
return `${this.url} => ${this.reason}`;
}

@@ -123,3 +131,9 @@ }

// the resolver function.
function runCheck(url, headers, resolver, timeout, redirects) {
function runCheck(args) {
const url = args.url;
const headers = args.headers;
const resolver = args.resolver;
const timeout = args.timeout;
const redirects = args.redirects || 0;
const loopbackURL = resolver(url);

@@ -136,21 +150,22 @@ const request = {

return new Promise(function(resolve, reject) {
redirects = redirects || 0;
get(request, timeout)
.then(function(res) {
if (~REDIRECT_STATUSES.indexOf(res.statusCode)) {
if (redirects < MAX_REDIRECT_COUNT) {
const redirectURL = resolver(res.headers.location);
if (withinSameDomain(redirectURL, loopbackURL))
runCheck(res.headers.location, headers, resolver, timeout, redirects + 1)
.then(resolve, reject);
else
resolve(res);
} else
reject(new Error('too many redirects'));
} else
resolve(res);
})
.catch(reject);
});
return get(request, timeout)
.then(function(response) {
const isRedirect = ~REDIRECT_STATUSES.indexOf(response.statusCode);
if (isRedirect) {
const redirectLoop = redirects >= MAX_REDIRECT_COUNT;
if (redirectLoop)
throw new Error('too many redirects');
else {
const redirectURL = response.headers.location;
const sameDomain = withinSameDomain(resolver(redirectURL), loopbackURL);
if (sameDomain)
return runCheck({ url: redirectURL, headers, resolver, timeout, redirects: redirects + 1 });
else
return response;
}
} else
return response;
});
}

@@ -205,3 +220,7 @@

// failed - A list of all check URLs that failed
function checkFunction(protocol, hostname, port, requestID, strictSSL) {
function checkFunction(url, requestID) {
const protocol = URL.parse(url).protocol;
const hostname = URL.parse(url).hostname;
const port = URL.parse(url).port;
const checks = this.checks;

@@ -214,3 +233,3 @@ const timeout = this.timeout;

function loopbackResolve(relativeURL) {
const absoluteURL = URL.parse(URL.resolve(protocol + '://localhost/', relativeURL));
const absoluteURL = URL.parse(URL.resolve(`${protocol}//localhost/`, relativeURL));
const loopbackURL = Object.assign({}, absoluteURL, {

@@ -228,22 +247,22 @@ hostname: absoluteURL.hostname,

return new Promise(function(resolve) {
// We need to make an HTTP/S request to the current server,
// based on the hostname/port passed to us,
// so the HTTP check would go to http://localhost:80/ or some such URL.
const headers = {
'User-Agent': 'Mozilla/5.0 (compatible) Healthchecks http://broadly.com',
'X-Request-Id': requestID || ''
};
// We need to make an HTTP/S request to the current server,
// based on the hostname/port passed to us,
// so the HTTP check would go to http://localhost:80/ or some such URL.
const headers = {
'User-Agent': 'Mozilla/5.0 (compatible) Healthchecks http://broadly.com',
'X-Request-Id': requestID || ''
};
const start = process.hrtime();
runCheck(checkURL, headers, loopbackResolve, timeout)
.then(function(res) {
const elapsed = process.hrtime(start);
resolve(new Outcome(checkURL, expected, null, res.statusCode, res.body, elapsed));
})
.catch(function(error) {
const elapsed = process.hrtime(start);
resolve(new Outcome(checkURL, expected, error, null, null, elapsed));
});
});
const start = process.hrtime();
return runCheck({ url: checkURL, headers, resolver: loopbackResolve, timeout })
.then(function(response) {
const elapsed = process.hrtime(start);
const outcome = new Outcome({ url: checkURL, expected, statusCode: response.statusCode, body: response.body, elapsed });
return outcome;
})
.catch(function(error) {
const elapsed = process.hrtime(start);
const outcome = new Outcome({ url: checkURL, expected, error, elapsed });
return outcome;
});
});

@@ -259,4 +278,4 @@

return {
passed: outcomes.filter(function(outcome) { return !outcome.reason; }),
failed: outcomes.filter(function(outcome) { return outcome.reason; })
passed: outcomes.filter(outcome => !outcome.reason ),
failed: outcomes.filter(outcome => outcome.reason )
};

@@ -273,18 +292,9 @@ });

const checks = File.readFileSync(filename, 'utf-8')
.split(/[\n\r]+/) // Split into lines
.map(function(line) { // Ignore leading/trailing spaces
return line.trim();
})
.filter(function(line) { // Ignore empty lines
return line.length;
})
.filter(function(line) { // Ignore comments
return line[0] !== '#';
})
.filter(function(line) { // Ignore name = value pairs
return !/^\w+=/.test(line);
})
.split(/[\n\r]+/) // Split into lines
.map(line => line.trim()) // Ignore leading/trailing spaces
.filter(line => line.length) // Ignore empty lines
.filter(line => line[0] !== '#') // Ignore comments
.filter(line => !/^\w+=/.test(line)) // Ignore name = value pairs
.map(function(line) { // Split line to URL + expected value
const match = line.match(/^(\S+)\s*(.*)/);
//debug('Added check %s %s', match[1], match[2]);
return {

@@ -303,4 +313,4 @@ url: match[1],

.reduce(function(memo, check) {
const url = check.url;
memo[url] = memo[url] || [];
const url = check.url;
memo[url] = memo[url] || []; // eslint-disable-line
if (check.expected)

@@ -321,4 +331,5 @@ memo[url].push(check.expected);

// Returns a comparer function suitable for Array.sort().
function compare(propName) {
function compareProperty(propName) {
return function(a, b) {

@@ -333,2 +344,18 @@ if (a[propName] < b[propName])

// Respond with 200 only if all checks passed
// Respond with 500 if any check fail
// Respond with 404 if there are no checks to run
function statusCodeFromOutcomes(passed, failed) {
const anyFailed = failed.length > 0;
const anyPassed = passed.length > 0;
if (anyFailed)
return 500;
else if (anyPassed)
return 200;
else
return 404;
}
// Call this function to configure and return the middleware.

@@ -339,12 +366,11 @@ module.exports = function healthchecks(options) {

// Pass filename as first argument or named option
const filename = typeof(options) === 'string' ? options : options.filename;
const filename = typeof (options) === 'string' ? options : options.filename;
assert(filename, 'Missing checks filename');
// Pass timeout as named option, or use default
const timeoutArg = (typeof(options) === 'object' && options.timeout) || DEFAULT_TIMEOUT;
const timeoutArg = (typeof (options) === 'object' && options.timeout) || DEFAULT_TIMEOUT;
// If timeout argument is a string (e.g. "3d"), convert to milliseconds
const timeout = (typeof(timeoutArg) === 'string') ? ms(timeoutArg) : + timeoutArg;
const timeout = (typeof (timeoutArg) === 'string') ? ms(timeoutArg) : parseInt(timeoutArg, 10);
const onFailed = options.onFailed || function() {};
const strictSSL = options.strictSSL === false ? false : true;

@@ -358,2 +384,3 @@ // Read all checks form the file and returns a checking function

// Return the Express middleware

@@ -367,23 +394,18 @@ return function(req, res) {

// 127.0.0.1:5000
const protocol = req.socket.encrypted ? 'https' : 'http';
const protocol = req.socket.encrypted ? 'https:' : 'http:';
const hostname = req.socket.localAddress;
const port = req.socket.localPort;
const url = URL.format({ protocol, hostname, port });
// Run all checks
debug('Running against %s://%s:%d with request-ID %s', protocol, hostname, port, requestID);
runChecks(protocol, hostname, port, requestID, strictSSL)
runChecks(url, requestID)
.then(function(outcomes) {
debug('%d passed and %d failed', outcomes.passed.length, outcomes.failed.length);
// Respond with 200 only if all checks passed
// Respond with 500 if any check fail
// Respond with 404 if there are no checks to run
const statusCode =
outcomes.failed.length ? 500 :
outcomes.passed.length ? 200 : 404;
// Render template
const html = render({
passed: outcomes.passed.sort(compare('url')),
failed: outcomes.failed.sort(compare('url'))
});
const passed = outcomes.passed.sort(compareProperty('url'));
const failed = outcomes.failed.sort(compareProperty('url'));
const statusCode = statusCodeFromOutcomes(passed, failed);
const html = render({ passed, failed });
res.writeHeader(statusCode);

@@ -393,4 +415,4 @@ res.write(html);

if (outcomes.failed.length)
onFailed(outcomes.failed);
if (failed.length > 0)
onFailed(failed);
});

@@ -400,1 +422,3 @@ };

};
{
"name": "healthchecks",
"version": "1.7.2",
"version": "1.7.3",
"engines": {

@@ -8,3 +8,4 @@ "node": ">=4.0.0"

"scripts": {
"test": "mocha"
"lint": "eslint .",
"test": "mocha && npm run lint"
},

@@ -14,10 +15,10 @@ "main": "lib/healthchecks",

"debug": "^2.2.0",
"handlebars": "^3.0",
"handlebars": "^4.0.5",
"ms": "^0.7.1",
"pretty-hrtime": "^1.0.0"
"pretty-hrtime": "^1.0.2"
},
"devDependencies": {
"eslint": "^0.21",
"eslint": "^1.10.3",
"express": "^4.12",
"mocha": "^2.2",
"mocha": "^2.3.4",
"request": "^2.67.0",

@@ -24,0 +25,0 @@ "zombie": "^4.0"

@@ -0,1 +1,2 @@

'use strict';
const assert = require('assert');

@@ -20,3 +21,3 @@ const healthchecks = require('..');

assert.equal(response.statusCode, 404);
done();
done(error);
});

@@ -23,0 +24,0 @@ });

@@ -0,1 +1,2 @@

'use strict';
const express = require('express');

@@ -15,7 +16,7 @@ const healthchecks = require('../..');

// server is ready to receive requests. Server only started once.
var listening = false;
let listening = false;
server.ready = function(callback) {
if (listening)
setImmediate(callback);
else
else {
server.listen(3000, function() {

@@ -25,2 +26,3 @@ listening = true;

});
}
};

@@ -27,0 +29,0 @@

@@ -0,1 +1,2 @@

'use strict';
const assert = require('assert');

@@ -2,0 +3,0 @@ const ms = require('ms');

@@ -0,1 +1,2 @@

'use strict';
const assert = require('assert');

@@ -22,3 +23,3 @@ const ms = require('ms');

assert.equal(response.statusCode, 200);
done();
done(error);
});

@@ -37,3 +38,3 @@ });

assert.equal(response.statusCode, 500);
done();
done(error);
});

@@ -58,3 +59,3 @@ });

assert.equal(response.statusCode, 500);
done();
done(error);
});

@@ -77,3 +78,3 @@ });

assert.equal(response.statusCode, 500);
done();
done(error);
});

@@ -96,3 +97,3 @@ });

assert.equal(response.statusCode, 500);
done();
done(error);
});

@@ -115,3 +116,3 @@ });

assert.equal(response.statusCode, 500);
done();
done(error);
});

@@ -118,0 +119,0 @@ });

@@ -0,1 +1,2 @@

'use strict';
const Browser = require('zombie');

@@ -2,0 +3,0 @@ const ms = require('ms');

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc