16
middleware/fast-head.js
Normal file
16
middleware/fast-head.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { cacheControlFactory } from './cache-control.js'
|
||||
|
||||
const cacheControl = cacheControlFactory(60 * 60 * 24)
|
||||
|
||||
export default function fastHead(req, res, next) {
|
||||
const { context } = req
|
||||
const { page } = context
|
||||
if (page) {
|
||||
// Since the *presence* is not affected by the request, we can cache
|
||||
// this and allow the CDN to hold on to it.
|
||||
cacheControl(res)
|
||||
|
||||
return res.status(200).send('')
|
||||
}
|
||||
next()
|
||||
}
|
||||
@@ -44,7 +44,6 @@ import archivedEnterpriseVersions from './archived-enterprise-versions.js'
|
||||
import robots from './robots.js'
|
||||
import earlyAccessLinks from './contextualizers/early-access-links.js'
|
||||
import categoriesForSupport from './categories-for-support.js'
|
||||
import loaderio from './loaderio-verification.js'
|
||||
import triggerError from './trigger-error.js'
|
||||
import releaseNotes from './contextualizers/release-notes.js'
|
||||
import whatsNewChangelog from './contextualizers/whats-new-changelog.js'
|
||||
@@ -65,6 +64,7 @@ import archivedAssetRedirects from './archived-asset-redirects.js'
|
||||
import favicons from './favicons.js'
|
||||
import setStaticAssetCaching from './static-asset-caching.js'
|
||||
import protect from './overload-protection.js'
|
||||
import fastHead from './fast-head.js'
|
||||
|
||||
const { DEPLOYMENT_ENV, NODE_ENV } = process.env
|
||||
const isDevelopment = NODE_ENV === 'development'
|
||||
@@ -303,12 +303,15 @@ export default function (app) {
|
||||
'/categories.json',
|
||||
asyncMiddleware(instrument(categoriesForSupport, './categories-for-support'))
|
||||
)
|
||||
app.use(instrument(loaderio, './loaderio-verification'))
|
||||
app.get('/_500', asyncMiddleware(instrument(triggerError, './trigger-error')))
|
||||
|
||||
// Check for a dropped connection before proceeding (again)
|
||||
app.use(haltOnDroppedConnection)
|
||||
|
||||
// Specifically deal with HEAD requests before doing the slower
|
||||
// full page rendering.
|
||||
app.head('/*', fastHead)
|
||||
|
||||
// *** Preparation for render-page: contextualizers ***
|
||||
app.use(asyncMiddleware(instrument(releaseNotes, './contextualizers/release-notes')))
|
||||
app.use(instrument(graphQL, './contextualizers/graphql'))
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
// prove to loader.io that we own this site
|
||||
// by responding to requests like `/loaderio-12345/` with `loaderio-12345`
|
||||
export default function loaderIoVerification(req, res, next) {
|
||||
if (!req.path.startsWith('/loaderio-')) return next()
|
||||
return res.send(req.path.replace(/\//g, ''))
|
||||
}
|
||||
@@ -29,8 +29,13 @@ describe('server', () => {
|
||||
test('supports HEAD requests', async () => {
|
||||
const res = await head('/en')
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(res.headers).not.toHaveProperty('content-length')
|
||||
expect(res.headers['content-length']).toBe('0')
|
||||
expect(res.text).toBe('')
|
||||
// Because the HEAD requests can't be different no matter what's
|
||||
// in the request headers (Accept-Language or Cookies)
|
||||
// it's safe to let it cache. The only key is the URL.
|
||||
expect(res.headers['cache-control']).toContain('public')
|
||||
expect(res.headers['cache-control']).toMatch(/max-age=\d+/)
|
||||
})
|
||||
|
||||
test('renders the homepage', async () => {
|
||||
|
||||
Reference in New Issue
Block a user