forked from mendhak/docker-http-https-echo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
163 lines (138 loc) · 4.62 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
var express = require('express')
const morgan = require('morgan');
var http = require('http')
var https = require('https')
var app = express()
const os = require('os');
const jwt = require('jsonwebtoken');
var concat = require('concat-stream');
const { promisify } = require('util');
const sleep = promisify(setTimeout);
app.set('json spaces', 2);
app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']);
if(process.env.DISABLE_REQUEST_LOGS !== 'true'){
app.use(morgan('combined'));
}
app.use(function(req, res, next){
req.pipe(concat(function(data){
req.body = data.toString('utf8');
next();
}));
});
//Handle all paths
app.all('*', (req, res) => {
const echo = {
path: req.path,
headers: req.headers,
method: req.method,
body: req.body,
cookies: req.cookies,
fresh: req.fresh,
hostname: req.hostname,
ip: req.ip,
ips: req.ips,
protocol: req.protocol,
query: req.query,
subdomains: req.subdomains,
xhr: req.xhr,
os: {
hostname: os.hostname()
},
connection: {
servername: req.connection.servername
}
};
//Add client certificate details to the output, if present
//This only works if `requestCert` is true when starting the server.
if(req.socket.getPeerCertificate){
echo.clientCertificate = req.socket.getPeerCertificate();
}
//Include visible environment variables
if(process.env.ECHO_INCLUDE_ENV_VARS){
echo.env = process.env;
}
//If the Content-Type of the incoming body `is` JSON, it can be parsed and returned in the body
if(req.is('application/json')){
echo.json = JSON.parse(req.body)
}
//If there's a JWT header, parse it and decode and put it in the response
if (process.env.JWT_HEADER) {
let token = req.headers[process.env.JWT_HEADER.toLowerCase()];
if (!token) {
echo.jwt = token;
} else {
token = token.split(" ").pop();
const decoded = jwt.decode(token, {complete: true});
echo.jwt = decoded;
}
}
//Set the status code to what the user wants
const setResponseStatusCode = parseInt(req.headers["x-set-response-status-code"] || req.query["x-set-response-status-code"], 10)
if (100 <= setResponseStatusCode && setResponseStatusCode < 600) {
res.status(setResponseStatusCode)
}
//Delay the response for a user defined time
const sleepTime = parseInt(req.headers["x-set-response-delay-ms"] || req.query["x-set-response-delay-ms"], 0)
sleep(sleepTime).then(() => {
//Set the response content type to what the user wants
const setResponseContentType = req.headers["x-set-response-content-type"] || req.query["x-set-response-content-type"];
if(setResponseContentType){
res.contentType(setResponseContentType);
}
//Ability to send an empty response back
if (process.env.ECHO_BACK_TO_CLIENT != undefined && process.env.ECHO_BACK_TO_CLIENT == "false"){
res.end();
}
//Ability to send just the request body in the response, nothing else
else if ("response_body_only" in req.query && req.query["response_body_only"] == "true") {
res.send(req.body);
}
//Normal behavior, send everything back
else {
res.json(echo);
}
//Certain paths can be ignored in the container logs, useful to reduce noise from healthchecks
if (process.env.LOG_IGNORE_PATH != req.path) {
let spacer = 4;
if(process.env.LOG_WITHOUT_NEWLINE){
spacer = null;
}
console.log(JSON.stringify(echo, null, spacer));
}
});
});
let sslOpts = {
key: require('fs').readFileSync('privkey.pem'),
cert: require('fs').readFileSync('fullchain.pem')
};
//Whether to enable the client certificate feature
if(process.env.MTLS_ENABLE){
sslOpts = {
requestCert: true,
rejectUnauthorized: false,
...sslOpts
}
}
var httpServer = http.createServer(app).listen(process.env.HTTP_PORT || 8080);
var httpsServer = https.createServer(sslOpts,app).listen(process.env.HTTPS_PORT || 8443);
console.log(`Listening on ports ${process.env.HTTP_PORT || 8080} for http, and ${process.env.HTTPS_PORT || 8443} for https.`);
let calledClose = false;
process.on('exit', function () {
if (calledClose) return;
console.log('Got exit event. Trying to stop Express server.');
server.close(function() {
console.log("Express server closed");
});
});
process.on('SIGINT', shutDown);
process.on('SIGTERM', shutDown);
function shutDown(){
console.log('Got a kill signal. Trying to exit gracefully.');
calledClose = true;
httpServer.close(function() {
httpsServer.close(function() {
console.log("HTTP and HTTPS servers closed. Asking process to exit.");
process.exit()
});
});
}