forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfavicons.js
54 lines (45 loc) · 1.69 KB
/
favicons.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
// We actually don't rely and use /favicon.ico but it's nevertheless a
// very common request. Same with /apple-touch-icon.png.
// Because we store our images, including those not for the Markdown text,
// in the `assets/images/site` directory, we will use a custom
// solution to serve this directly.
import fs from 'fs'
import { SURROGATE_ENUMS, setFastlySurrogateKey } from './set-fastly-surrogate-key.js'
import { cacheControlFactory } from './cache-control.js'
const cacheControl = cacheControlFactory(60 * 60 * 24 * 7, { immutable: true })
const MAP = {
'/favicon.ico': {
contentType: 'image/x-icon',
buffer: getBuffer('assets/images/site/favicon.ico'),
},
'/apple-touch-icon.png': {
contentType: 'image/png',
buffer: getBuffer('assets/images/site/apple-touch-icon.png'),
},
}
function getBuffer(filePath) {
let buffer
if (!fs.existsSync(filePath)) {
throw new Error(`${filePath} not found on disk`)
}
return () => {
if (!buffer) {
// Yes, sync and a bit slow, but the headers we send will
// make sure these requests are rare because the payload
// will be sticky in the CDN and stickly in the browser too.
buffer = fs.readFileSync(filePath)
}
return buffer
}
}
export default function favicons(req, res, next) {
if (!MAP[req.path]) return next()
// This makes sure the CDN caching survives each production deployment.
setFastlySurrogateKey(res, SURROGATE_ENUMS.MANUAL)
// Manually settings a Cache-Control because no other middleware
// will get a chance to do this later since we terminate here.
cacheControl(res)
const { contentType, buffer } = MAP[req.path]
res.set('content-type', contentType)
res.send(buffer())
}