/
handleFileRoutes.ts
82 lines (65 loc) · 2.27 KB
/
handleFileRoutes.ts
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
import url from 'url';
import serveStatic from 'serve-static';
import express from 'express';
import { TypeMiddleware } from '../../types';
import { errorCodes, compressions, getAcceptedCompression } from '../../utils';
function setContentTypeAndEncoding(params: {
encoding: (typeof compressions)[number]['encoding'];
contentType: 'application/javascript' | 'text/css';
}): express.Handler {
const { encoding, contentType } = params;
return (req, res, next) => {
res.set('Content-Type', contentType);
res.set('Content-Encoding', encoding);
return next();
};
}
const redirectToCompressed: TypeMiddleware = (app) => {
app.use((req, res, next) => {
if (req.url.endsWith('.js') || req.url.endsWith('.css')) {
const acceptedCompression = getAcceptedCompression(req);
if (acceptedCompression) {
req.url = `${req.url}.${acceptedCompression.extension}`;
}
}
next();
});
};
const setEncodingsForCompressedFiles: TypeMiddleware = (app) => {
compressions.forEach(({ encoding, extension }) => {
app.get(
`*.js.${extension}`,
setContentTypeAndEncoding({ encoding, contentType: 'application/javascript' })
);
app.get(`*.css.${extension}`, setContentTypeAndEncoding({ encoding, contentType: 'text/css' }));
});
};
export const handleFileRoutes: TypeMiddleware = (app, params) => {
app.disable('x-powered-by');
if (params.compressedFilesGenerated) {
redirectToCompressed(app, params);
setEncodingsForCompressedFiles(app, params);
}
// Send 404 for server files
app.get('*', (req, res, next) =>
req.originalUrl.includes('server') ? res.sendStatus(errorCodes.NOT_FOUND) : next()
);
app.use(
serveStatic(params.staticFilesPath, {
maxAge: params.maxAgeForStatic,
setHeaders: (res) => {
res.header('vary', 'Accept-Encoding');
},
})
);
(params.customFileMiddlewares || []).forEach((fn) => fn(app, params));
// Send 404 for all not found files
app.get('*', (req, res, next) => {
if (url.parse(req.originalUrl)?.pathname?.includes('.')) {
// eslint-disable-next-line no-console
// console.log(`CRITICAL: file URL ${req.url} ORIGINAL ${req.originalUrl} not found, sent 404`);
return res.sendStatus(errorCodes.NOT_FOUND);
}
return next();
});
};