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.6.1 to 1.7.0

11

CHANGELOG.md

@@ -0,1 +1,12 @@

## Version 1.7.0 2015-12-09
FIXED always run checks against `localAddress` and `localPort`
FIXED checking subdomains works again
CHANGED dropped short-lived support for SSL
CHANGED follow up to 10 redirects
## Version 1.6.1 2015-11-09

@@ -2,0 +13,0 @@

125

lib/healthchecks.js

@@ -23,3 +23,3 @@ // Exports an Express middleware factory.

const Handlebars = require('handlebars');
const Request = require('request');
const HTTP = require('http');
const ms = require('ms');

@@ -111,2 +111,54 @@ const Path = require('path');

// Makes a request to the given relative URL by crafting the request
// using the resolver function.
// Redirects will be resolved using the resolver function as well.
function get(url, headers, resolver, timeout) {
const loopbackURL = resolver(url);
const request = {
host: loopbackURL.host,
port: loopbackURL.port,
path: loopbackURL.path,
headers: Object.assign({}, headers, {
'Host': loopbackURL.hostname
})
};
return new Promise(function(resolve, reject) {
const start = process.hrtime();
HTTP.get(request)
.on('error', function(error) {
const elapsed = process.hrtime(start);
reject({ error: error, elapsed: elapsed });
})
.on('response', function(response) {
const elapsed = process.hrtime(start);
if (response.statusCode < 200 || response.statusCode >= 400)
resolve({ statusCode: response.statusCode, body: null, elapsed: elapsed });
else if (response.statusCode > 300 && response.statusCode < 400) {
get(response.headers.location, headers, resolver, timeout)
.then(resolve, reject);
}
else {
const buffers = [];
response.on('data', function(buffer) {
buffers.push(buffer);
});
response.on('end', function() {
const body = Buffer.concat(buffers).toString();
resolve({ statusCode: response.statusCode, body: body, elapsed: elapsed });
});
}
});
setTimeout(function() {
const elapsed = process.hrtime(start);
const error = new Error('ETIMEDOUT');
error.code = 'ETIMEDOUT';
reject({ error: error, elapsed: elapsed });
}, timeout);
});
}
// The check function will run all checks in parallel, and resolve to an object

@@ -120,52 +172,34 @@ // with the properties:

// Given a relative URL in string form, returns a parsed URL
// which points to the local server's IP address and port
// and has the right hostname property to use in the Host header.
function loopbackResolve(relativeURL) {
const absoluteURL = URL.parse(URL.resolve(protocol + '://localhost/', relativeURL));
const loopbackURL = Object.assign({}, absoluteURL, {
hostname: absoluteURL.hostname,
host: hostname,
port: port
});
return loopbackURL;
}
// Each check resolves into an outcome object
const allChecks = Object.keys(checks).map(function(checkURL) {
const expected = checks[checkURL];
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,
// 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.
// Checks have relative URLs, resolve them to absolute URLs
if(typeof(port) === 'string')
hostname = hostname + ":" + port;
const baseURL = protocol + "://" + hostname + '/';
const absCheckURL = URL.resolve(baseURL, checkURL);
const reqOpts = {
url: absCheckURL,
strictSSL: strictSSL,
headers: {
'Host': hostname,
'User-Agent': 'Mozilla/5.0 (compatible) Healthchecks http://broadly.com',
'X-Request-Id': requestID || ''
}
const headers = {
'User-Agent': 'Mozilla/5.0 (compatible) Healthchecks http://broadly.com',
'X-Request-Id': requestID || ''
};
const start = process.hrtime();
Request.get(reqOpts)
.on('error', function(error) {
const elapsed = process.hrtime(start);
resolve(new Outcome(checkURL, expected, error, null, null, elapsed));
get(checkURL, headers, loopbackResolve, timeout)
.then(function(res) {
resolve(new Outcome(checkURL, expected, null, res.statusCode, res.body, res.elapsed));
})
.on('response', function(response) {
const elapsed = process.hrtime(start);
if (response.statusCode < 200 || response.statusCode >= 400)
resolve(new Outcome(checkURL, expected, null, response.statusCode, null, elapsed));
else {
const buffers = [];
response.on('data', function(buffer) {
buffers.push(buffer);
});
response.on('end', function() {
const body = Buffer.concat(buffers).toString();
resolve(new Outcome(checkURL, expected, null, response.statusCode, body, elapsed));
});
}
.catch(function(error) {
resolve(new Outcome(checkURL, expected, error.error, null, null, error.elapsed));
});
setTimeout(function() {
const elapsed = process.hrtime(start);
const error = new Error('ETIMEDOUT');
error.code = 'ETIMEDOUT';
resolve(new Outcome(checkURL, expected, error, null, null, elapsed));
}, timeout);
});

@@ -284,5 +318,4 @@ });

const protocol = req.socket.encrypted ? 'https' : 'http';
const fullHost = req.header("Host").split(':');
const hostname = fullHost[0];
const port = fullHost[1];
const hostname = req.socket.localAddress;
const port = req.socket.localPort;

@@ -289,0 +322,0 @@ // Run all checks

{
"name": "healthchecks",
"version": "1.6.1",
"version": "1.7.0",
"engines": {

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

"ms": "^0.7.1",
"pretty-hrtime": "^1.0.0",
"request": "^2.0"
"pretty-hrtime": "^1.0.0"
},

@@ -23,2 +22,3 @@ "devDependencies": {

"mocha": "^2.2",
"request": "^2.67.0",
"zombie": "^4.0"

@@ -25,0 +25,0 @@ },

@@ -109,6 +109,5 @@ # Healthchecks

`filename` -- The name of the checks file
`onFailed` -- Called with array of failed checks
`timeout` -- Timeout slow responses
`strictSSL` -- Defaults to true, false allows use of self-signed certificates for development
* `filename` -- The name of the checks file
* `onFailed` -- Called with array of failed checks
* `timeout` -- Timeout slow responses

@@ -121,12 +120,12 @@ You can specify the timeout in milliseconds or as a string, e.g. "3s" for 3

`url` -- The absolute URL
`reason` -- One of 'error', 'timeout', 'statusCode' or 'body'
`error` -- Connection or timeout error
`timeout` -- True if failed due to timeout
`statusCode` -- HTTP status code (if no error)
`body` -- Response body
* `url` -- The absolute URL
* `reason` -- One of `'error'`, `'timeout'`, `'statusCode'` or `'body'`
* `error` -- Connection or timeout error
* `timeout` -- True if failed due to timeout
* `statusCode` -- HTTP status code (if no error)
* `body` -- Response body
For convenience, the value of the `reason` property is the name of one of the
other properties. Also, when you call `toString()` you get a URL with the
reason, e.g. "http://example.com => statusCode".
reason, e.g. `"http://example.com => statusCode"`.

@@ -139,3 +138,2 @@ For example:

timeout: '5s', // 5 seconds, can also pass duration in milliseconds
strictSSL: (process.env.NODE_ENV === 'production') ? true : false,
onFailed: function(checks) {

@@ -142,0 +140,0 @@ checks.forEach(function(check) {

@@ -70,1 +70,12 @@ const express = require('express');

});
// Test subdomains
server.locals.subdomain = 'admin';
server.get('/subdomain', function(req, res) {
const subdomain = req.headers.host.split('.')[0];
if (subdomain === server.locals.subdomain)
res.status(200).send('');
else
res.status(404).send('');
});

@@ -153,4 +153,30 @@ const assert = require('assert');

describe('subdomain not accessible', function() {
before(function() {
server.locals.subdomain = '';
});
it('should be notified of a failed test', function(done) {
server.once('failed', function(failed) {
assert.equal(failed[0].url, '//admin.localhost/subdomain');
assert.equal(failed[0].reason, 'statusCode');
assert(!failed[0].error);
assert(!failed[0].timeout);
assert.equal(failed[0].statusCode, 404);
assert.equal(failed[0].toString(), '//admin.localhost/subdomain => 404');
done();
});
request(checksURL);
});
after(function() {
server.locals.subdomain = 'admin';
});
});
});

@@ -102,2 +102,20 @@ const assert = require('assert');

describe('subdomain not accessible', function() {
before(function() {
server.locals.subdomain = '';
});
it('should receive response with status 500', function(done) {
request(checksURL, function(error, response) {
assert.equal(response.statusCode, 500);
done();
});
});
after(function() {
server.locals.subdomain = 'admin';
});
});
});

@@ -22,7 +22,8 @@ const Browser = require('zombie');

browser.assert.text('h1', 'Passed');
browser.assert.text('.passed li:nth-of-type(1)', /error \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(2)', /expected \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(3)', /redirect \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(4)', /status \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(5)', /timeout \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(1)', /\/\/admin.localhost\/subdomain \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(2)', /error \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(3)', /expected \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(4)', /redirect \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(5)', /status \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(6)', /timeout \d[.\d]* ms/);
done();

@@ -42,7 +43,8 @@ });

browser.assert.text('h1', 'Passed');
browser.assert.text('.passed li:nth-of-type(1)', /error \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(2)', /expected \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(3)', /redirect \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(4)', /status \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(5)', /timeout \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(1)', /\/\/admin.localhost\/subdomain \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(2)', /error \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(3)', /expected \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(4)', /redirect \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(5)', /status \d[.\d]* ms/);
browser.assert.text('.passed li:nth-of-type(6)', /timeout \d[.\d]* ms/);
done();

@@ -68,3 +70,3 @@ });

browser.assert.text('.failed li:nth-of-type(2)', /redirect => socket hang up \d[.\d]* ms/);
browser.assert.elements('.passed li', 3);
browser.assert.elements('.passed li', 4);
done();

@@ -92,3 +94,3 @@ });

browser.assert.text('.failed li:nth-of-type(1)', /error => socket hang up \d[.\d]* ms/);
browser.assert.elements('.passed li', 4);
browser.assert.elements('.passed li', 5);
done();

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

browser.assert.text('.failed li:nth-of-type(1)', /timeout => timeout \d[.\d]* s/);
browser.assert.elements('.passed li', 4);
browser.assert.elements('.passed li', 5);
done();

@@ -138,3 +140,3 @@ });

browser.assert.text('.failed li:nth-of-type(1)', /status => 400 \d[.\d]* ms/);
browser.assert.elements('.passed li', 4);
browser.assert.elements('.passed li', 5);
done();

@@ -160,3 +162,3 @@ });

browser.assert.text('.failed li:nth-of-type(1)', /expected => body \d[.\d]* ms/);
browser.assert.elements('.passed li', 4);
browser.assert.elements('.passed li', 5);
done();

@@ -172,3 +174,23 @@ });

describe('subdomain not accessible', function() {
before(function() {
server.locals.subdomain = '';
});
it('should see a failed test', function(done) {
browser.visit(checksURL, function() {
browser.assert.text('h1', 'FailedPassed');
browser.assert.elements('.failed li', 1);
browser.assert.text('.failed li:nth-of-type(1)', /\/\/admin.localhost\/subdomain => 404 \d[.\d]* ms/);
browser.assert.elements('.passed li', 5);
done();
});
});
after(function() {
server.locals.subdomain = 'admin';
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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