-
Notifications
You must be signed in to change notification settings - Fork 70
Expand file tree
/
Copy pathexpress-http-server.js
More file actions
120 lines (96 loc) · 2.94 KB
/
express-http-server.js
File metadata and controls
120 lines (96 loc) · 2.94 KB
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
"use strict";
const express = require('express');
const basicAuth = require('./basic-auth');
function noop() {}
class ExpressHTTPServer {
constructor(options) {
options = options || {};
this.ui = options.ui;
this.distPath = options.distPath;
this.username = options.username;
this.password = options.password;
this.cache = options.cache;
this.gzip = options.gzip || false;
this.beforeMiddleware = options.beforeMiddleware || noop;
this.afterMiddleware = options.afterMiddleware || noop;
this.forbiddenAssets = [
'/fastbootAssetMap.json',
'/package.json',
'/node_modules/*',
'/fastboot/*'
];
this.app = express();
}
serve(fastbootMiddleware) {
let app = this.app;
let username = this.username;
let password = this.password;
this.beforeMiddleware(app);
if (this.gzip) {
this.app.use(require('compression')());
}
if (username !== undefined || password !== undefined) {
this.ui.writeLine(`adding basic auth; username=${username}; password=${password}`);
app.use(basicAuth(username, password));
}
if (this.cache) {
app.get('/*', this.buildCacheMiddleware());
}
if (this.distPath) {
app.get('/', fastbootMiddleware);
this.forbiddenAssets.forEach(function(path) {
app.get(path, function(req, res) {
res.sendStatus(404);
});
});
app.use(express.static(this.distPath));
app.get('/assets/*', function(req, res) {
res.sendStatus(404);
});
}
app.get('/*', fastbootMiddleware);
this.afterMiddleware(app);
return new Promise(resolve => {
let listener = app.listen(process.env.PORT || 3000, () => {
let host = listener.address().address;
let port = listener.address().port;
this.ui.writeLine('HTTP server started; url=http://%s:%s', host, port);
resolve();
});
});
}
buildCacheMiddleware() {
return (req, res, next) => {
let path = req.path;
Promise.resolve(this.cache.fetch(path, req))
.then(response => {
if (response) {
this.ui.writeLine(`cache hit; path=${path}`);
res.send(response);
} else {
this.ui.writeLine(`cache miss; path=${path}`);
this.interceptResponseCompletion(path, res);
next();
}
})
.catch(() => next());
};
}
interceptResponseCompletion(path, res) {
let send = res.send.bind(res);
res.send = (body) => {
let ret = send(body);
this.cache.put(path, body, res)
.then(() => {
this.ui.writeLine(`stored in cache; path=${path}`);
})
.catch(() => {
let truncatedBody = body.replace(/\n/g).substr(0, 200);
this.ui.writeLine(`error storing cache; path=${path}; body=${truncatedBody}...`);
});
res.send = send;
return ret;
};
}
}
module.exports = ExpressHTTPServer;