Skip to content

Commit 845734e

Browse files
feat(server): custom header support (#198)
* Added support for writing headers * Updated ReadMe * Made headers apart of options * Removed res.status * Added test coverage
1 parent 0c5c291 commit 845734e

File tree

3 files changed

+84
-11
lines changed

3 files changed

+84
-11
lines changed

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,40 @@ createTerminus(server, {
105105
});
106106
```
107107

108+
### With custom headers
109+
```js
110+
const http = require("http");
111+
const express = require("express");
112+
const { createTerminus, HealthCheckError } = require('@godaddy/terminus');
113+
const app = express();
114+
115+
app.get("/", (req, res) => {
116+
res.send("ok");
117+
});
118+
119+
const server = http.createServer(app);
120+
121+
function healthCheck({ state }) {
122+
return Promise.resolve();
123+
}
124+
125+
const options = {
126+
healthChecks: {
127+
"/healthcheck": healthCheck,
128+
verbatim: true,
129+
__unsafeExposeStackTraces: true,
130+
},
131+
headers: {
132+
"Access-Control-Allow-Origin": "*",
133+
"Access-Control-Allow-Methods": "OPTIONS, POST, GET",
134+
},
135+
};
136+
137+
terminus.createTerminus(server, options);
138+
139+
server.listen(3000);
140+
```
141+
108142
### With express
109143

110144
```javascript

lib/terminus.js

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ function noopResolves () {
1515
return Promise.resolve()
1616
}
1717

18-
async function sendSuccess (res, { info, verbatim, statusOk }) {
19-
res.statusCode = statusOk
18+
async function sendSuccess (res, { info, verbatim, statusOk, headers }) {
2019
res.setHeader('Content-Type', 'application/json')
20+
res.writeHead(statusOk, headers)
2121
if (info) {
2222
return res.end(
2323
JSON.stringify(
@@ -34,7 +34,7 @@ async function sendSuccess (res, { info, verbatim, statusOk }) {
3434
}
3535

3636
async function sendFailure (res, options) {
37-
const { error, onSendFailureDuringShutdown, exposeStackTraces, statusCode, statusError } = options
37+
const { error, headers, onSendFailureDuringShutdown, exposeStackTraces, statusCode, statusError } = options
3838

3939
function replaceErrors (_, value) {
4040
if (value instanceof Error) {
@@ -54,8 +54,8 @@ async function sendFailure (res, options) {
5454
if (onSendFailureDuringShutdown) {
5555
await onSendFailureDuringShutdown()
5656
}
57-
res.statusCode = statusCode || statusError
5857
res.setHeader('Content-Type', 'application/json')
58+
res.writeHead(statusCode || statusError, headers)
5959
if (error) {
6060
return res.end(JSON.stringify({
6161
status: 'error',
@@ -73,7 +73,7 @@ const intialState = {
7373
function noop () {}
7474

7575
function decorateWithHealthCheck (server, state, options) {
76-
const { healthChecks, logger, onSendFailureDuringShutdown, sendFailuresDuringShutdown, caseInsensitive, statusOk, statusError } = options
76+
const { healthChecks, logger, headers, onSendFailureDuringShutdown, sendFailuresDuringShutdown, caseInsensitive, statusOk, statusError } = options
7777

7878
let hasSetHandler = false
7979
const createHandler = (listener) => {
@@ -88,16 +88,29 @@ function decorateWithHealthCheck (server, state, options) {
8888
info = await healthCheck({ state })
8989
} catch (error) {
9090
logger('healthcheck failed', error)
91-
return sendFailure(res, { error: error.causes, exposeStackTraces: healthChecks.__unsafeExposeStackTraces, statusCode: error.statusCode, statusError })
91+
return sendFailure(
92+
res,
93+
{
94+
error: error.causes,
95+
headers,
96+
exposeStackTraces: healthChecks.__unsafeExposeStackTraces,
97+
statusCode: error.statusCode,
98+
statusError
99+
}
100+
)
92101
}
93-
return sendSuccess(res, { info, verbatim: healthChecks.verbatim, statusOk })
102+
return sendSuccess(
103+
res,
104+
{ info, verbatim: healthChecks.verbatim, statusOk, headers }
105+
)
94106
}
95107

96108
hasSetHandler = true
97109

98110
return async (req, res) => {
99111
const url = caseInsensitive ? req.url.toLowerCase() : req.url
100112
const healthCheck = healthChecks[url]
113+
101114
if (healthCheck) {
102115
return check(healthCheck, res)
103116
} else {
@@ -164,7 +177,8 @@ function terminus (server, options = {}) {
164177
logger = noop,
165178
caseInsensitive = false,
166179
statusOk = 200,
167-
statusError = 503
180+
statusError = 503,
181+
headers = options.headers || {}
168182
} = options
169183
const onSignal = options.onSignal || options.onSigterm || noopResolves
170184
const state = Object.assign({}, intialState)
@@ -177,7 +191,8 @@ function terminus (server, options = {}) {
177191
onSendFailureDuringShutdown,
178192
caseInsensitive,
179193
statusOk,
180-
statusError
194+
statusError,
195+
headers
181196
})
182197
}
183198

@@ -190,7 +205,8 @@ function terminus (server, options = {}) {
190205
beforeShutdown,
191206
onShutdown,
192207
timeout,
193-
logger
208+
logger,
209+
headers
194210
})
195211

196212
return server

lib/terminus.spec.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,4 +656,27 @@ describe('Terminus', () => {
656656
'server3:onSignal'
657657
].join('\n'))
658658
})
659-
})
659+
660+
it('accepts custom headers', async () => {
661+
662+
createTerminus(server, {
663+
healthChecks: {
664+
'/health': () => {
665+
return Promise.resolve()
666+
}
667+
},
668+
headers: {
669+
"Access-Control-Allow-Origin": "*",
670+
"Access-Control-Allow-Methods": "OPTIONS, POST, GET",
671+
},
672+
})
673+
server.listen(8000)
674+
675+
const res = await fetch('http://localhost:8000/health')
676+
expect(res.status).to.eql(200)
677+
expect(res.headers.has('Access-Control-Allow-Methods')).to.eql(true)
678+
expect(res.headers.get('Access-Control-Allow-Methods')).to.eql('OPTIONS, POST, GET')
679+
expect(res.headers.has('Access-Control-Allow-Origin')).to.eql(true)
680+
expect(res.headers.get('Access-Control-Allow-Origin')).to.eql('*')
681+
})
682+
})

0 commit comments

Comments
 (0)