feat(core): custom pushAssets function to control http2 push headers (#4198)

Resolves #4011
Resolves #4161
This commit is contained in:
awronski 2018-10-26 19:59:12 +02:00 committed by Pooya Parsa
parent ae9de93a45
commit c9fd78048f

View File

@ -44,30 +44,18 @@ export default async function nuxtMiddleware(req, res, next) {
if (!error && this.options.render.http2.push) {
// Parse resourceHints to extract HTTP.2 prefetch/push headers
// https://w3c.github.io/preload/#server-push-http-2
const pushAssets = []
const preloadFiles = getPreloadFiles()
const { shouldPush } = this.options.render.http2
const { shouldPush, pushAssets } = this.options.render.http2
const { publicPath } = this.resources.clientManifest
preloadFiles.forEach(({ file, asType, fileWithoutQuery }) => {
// By default, we only preload scripts or css
/* istanbul ignore if */
if (!shouldPush && asType !== 'script' && asType !== 'style') {
return
}
// User wants to explicitly control what to preload
if (shouldPush && !shouldPush(fileWithoutQuery, asType)) {
return
}
pushAssets.push(`<${publicPath}${file}>; rel=preload; as=${asType}`)
})
const links = pushAssets ? pushAssets(req, res, publicPath, preloadFiles) : defaultPushAssets(preloadFiles, shouldPush, publicPath, this.options.dev)
// Pass with single Link header
// https://blog.cloudflare.com/http-2-server-push-with-multiple-assets-per-link-header
// https://www.w3.org/Protocols/9707-link-header.html
res.setHeader('Link', pushAssets.join(','))
if (links.length > 0) {
res.setHeader('Link', links.join(', '))
}
}
if (this.options.render.csp) {
@ -94,6 +82,29 @@ export default async function nuxtMiddleware(req, res, next) {
}
}
const defaultPushAssets = (preloadFiles, shouldPush, publicPath, isDev) => {
if (shouldPush && isDev) {
consola.warn('http2.shouldPush is deprecated. User http2.pushAssets function')
}
const links = []
preloadFiles.forEach(({ file, asType, fileWithoutQuery }) => {
// By default, we only preload scripts or css
/* istanbul ignore if */
if (!shouldPush && asType !== 'script' && asType !== 'style') {
return
}
// User wants to explicitly control what to preload
if (shouldPush && !shouldPush(fileWithoutQuery, asType)) {
return
}
links.push(`<${publicPath}${file}>; rel=preload; as=${asType}`)
})
return links
}
const getCspString = ({ cspScriptSrcHashSet, allowedSources, policies, isDev }) => {
const joinedHashSet = Array.from(cspScriptSrcHashSet).join(' ')
const baseCspStr = `script-src 'self'${isDev ? ` 'unsafe-eval'` : ''} ${joinedHashSet}`