specialpages: New `/health` endpoint for health checking
This endpoint is intended to conform with: https://www.ietf.org/archive/id/draft-inadarei-api-health-check-06.htmlpull/5336/head
parent
2e4c546c7f
commit
696f9c3367
|
@ -19,6 +19,8 @@
|
|||
* Fixed race conditions in the `setText`, `appendText`, and `restoreRevision`
|
||||
functions (HTTP API).
|
||||
* Fixed a crash if the database is busy enough to cause a query timeout.
|
||||
* New `/health` endpoint for getting information about Etherpad's health (see
|
||||
[draft-inadarei-api-health-check-06](https://www.ietf.org/archive/id/draft-inadarei-api-health-check-06.html)).
|
||||
|
||||
#### For plugin authors
|
||||
|
||||
|
|
|
@ -11,6 +11,16 @@ const util = require('util');
|
|||
const webaccess = require('./webaccess');
|
||||
|
||||
exports.expressPreSession = async (hookName, {app}) => {
|
||||
// This endpoint is intended to conform to:
|
||||
// https://www.ietf.org/archive/id/draft-inadarei-api-health-check-06.html
|
||||
app.get('/health', (req, res) => {
|
||||
res.set('Content-Type', 'application/health+json');
|
||||
res.json({
|
||||
status: 'pass',
|
||||
releaseId: settings.getEpVersion(),
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/stats', (req, res) => {
|
||||
res.json(require('../../stats').toJSON());
|
||||
});
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert').strict;
|
||||
const common = require('../common');
|
||||
const settings = require('../../../node/utils/Settings');
|
||||
const superagent = require('superagent');
|
||||
|
||||
describe(__filename, function () {
|
||||
let agent;
|
||||
const backup = {};
|
||||
|
||||
const getHealth = () => agent.get('/health')
|
||||
.accept('application/health+json')
|
||||
.buffer(true)
|
||||
.parse(superagent.parse['application/json'])
|
||||
.expect(200)
|
||||
.expect((res) => assert.equal(res.type, 'application/health+json'));
|
||||
|
||||
before(async function () {
|
||||
agent = await common.init();
|
||||
});
|
||||
|
||||
beforeEach(async function () {
|
||||
backup.settings = {};
|
||||
for (const setting of ['requireAuthentication', 'requireAuthorization']) {
|
||||
backup.settings[setting] = settings[setting];
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async function () {
|
||||
Object.assign(settings, backup.settings);
|
||||
});
|
||||
|
||||
it('/health works', async function () {
|
||||
const res = await getHealth();
|
||||
assert.equal(res.body.status, 'pass');
|
||||
assert.equal(res.body.releaseId, settings.getEpVersion());
|
||||
});
|
||||
|
||||
it('auth is not required', async function () {
|
||||
settings.requireAuthentication = true;
|
||||
settings.requireAuthorization = true;
|
||||
const res = await getHealth();
|
||||
assert.equal(res.body.status, 'pass');
|
||||
});
|
||||
|
||||
// We actually want to test that no express-session state is created, but that is difficult to do
|
||||
// without intrusive changes or unpleasant ueberdb digging. Instead, we assume that the lack of a
|
||||
// cookie means that no express-session state was created (how would express-session look up the
|
||||
// session state if no ID was returned to the client?).
|
||||
it('no cookie is returned', async function () {
|
||||
const res = await getHealth();
|
||||
const cookie = res.headers['set-cookie'];
|
||||
assert(cookie == null, `unexpected Set-Cookie: ${cookie}`);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue